source: rtems/cpukit/score/src/threadqenqueuepriority.c @ fe6c170c

4.115
Last change on this file since fe6c170c was fe6c170c, checked in by Sebastian Huber <sebastian.huber@…>, on 07/24/13 at 14:19:52

score: Create states implementation header

Move implementation specific parts of states.h and states.inl into new
header file statesimpl.h. The states.h contains now only the
application visible API.

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Thread Queue Enqueue Priority
5 *  @ingroup ScoreThreadQ
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2009.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/threadq.h>
22#include <rtems/score/chainimpl.h>
23#include <rtems/score/statesimpl.h>
24
25/*
26 *  Support the user forcing the unrolling to be disabled.
27 */
28#if __RTEMS_DO_NOT_UNROLL_THREADQ_ENQUEUE_PRIORITY__
29  #undef CPU_UNROLL_ENQUEUE_PRIORITY
30  #define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
31#endif
32
33Thread_blocking_operation_States _Thread_queue_Enqueue_priority (
34  Thread_queue_Control *the_thread_queue,
35  Thread_Control       *the_thread,
36  ISR_Level            *level_p
37)
38{
39  Priority_Control     search_priority;
40  Thread_Control      *search_thread;
41  ISR_Level            level;
42  Chain_Control       *header;
43  uint32_t             header_index;
44  Chain_Node          *the_node;
45  Chain_Node          *next_node;
46  Chain_Node          *previous_node;
47  Chain_Node          *search_node;
48  Priority_Control     priority;
49  States_Control       block_state;
50
51  _Chain_Initialize_empty( &the_thread->Wait.Block2n );
52
53  priority     = the_thread->current_priority;
54  header_index = _Thread_queue_Header_number( priority );
55  header       = &the_thread_queue->Queues.Priority[ header_index ];
56  block_state  = the_thread_queue->state;
57
58  if ( _Thread_queue_Is_reverse_search( priority ) )
59    goto restart_reverse_search;
60
61restart_forward_search:
62  search_priority = PRIORITY_MINIMUM - 1;
63  _ISR_Disable( level );
64  search_thread = (Thread_Control *) _Chain_First( header );
65  while ( !_Chain_Is_tail( header, (Chain_Node *)search_thread ) ) {
66    search_priority = search_thread->current_priority;
67    if ( priority <= search_priority )
68      break;
69
70#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE )
71    search_thread = (Thread_Control *) search_thread->Object.Node.next;
72    if ( _Chain_Is_tail( header, (Chain_Node *)search_thread ) )
73      break;
74    search_priority = search_thread->current_priority;
75    if ( priority <= search_priority )
76      break;
77#endif
78    _ISR_Flash( level );
79    if ( !_States_Are_set( search_thread->current_state, block_state) ) {
80      _ISR_Enable( level );
81      goto restart_forward_search;
82    }
83    search_thread =
84       (Thread_Control *)search_thread->Object.Node.next;
85  }
86
87  if ( the_thread_queue->sync_state !=
88       THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
89    goto synchronize;
90
91  the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
92
93  if ( priority == search_priority )
94    goto equal_priority;
95
96  search_node   = (Chain_Node *) search_thread;
97  previous_node = search_node->previous;
98  the_node      = (Chain_Node *) the_thread;
99
100  the_node->next         = search_node;
101  the_node->previous     = previous_node;
102  previous_node->next    = the_node;
103  search_node->previous  = the_node;
104  the_thread->Wait.queue = the_thread_queue;
105  _ISR_Enable( level );
106  return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
107
108restart_reverse_search:
109  search_priority     = PRIORITY_MAXIMUM + 1;
110
111  _ISR_Disable( level );
112  search_thread = (Thread_Control *) _Chain_Last( header );
113  while ( !_Chain_Is_head( header, (Chain_Node *)search_thread ) ) {
114    search_priority = search_thread->current_priority;
115    if ( priority >= search_priority )
116      break;
117#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE )
118    search_thread = (Thread_Control *) search_thread->Object.Node.previous;
119    if ( _Chain_Is_head( header, (Chain_Node *)search_thread ) )
120      break;
121    search_priority = search_thread->current_priority;
122    if ( priority >= search_priority )
123      break;
124#endif
125    _ISR_Flash( level );
126    if ( !_States_Are_set( search_thread->current_state, block_state) ) {
127      _ISR_Enable( level );
128      goto restart_reverse_search;
129    }
130    search_thread = (Thread_Control *)
131                         search_thread->Object.Node.previous;
132  }
133
134  if ( the_thread_queue->sync_state !=
135       THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
136    goto synchronize;
137
138  the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
139
140  if ( priority == search_priority )
141    goto equal_priority;
142
143  search_node = (Chain_Node *) search_thread;
144  next_node   = search_node->next;
145  the_node    = (Chain_Node *) the_thread;
146
147  the_node->next          = next_node;
148  the_node->previous      = search_node;
149  search_node->next       = the_node;
150  next_node->previous    = the_node;
151  the_thread->Wait.queue = the_thread_queue;
152  _ISR_Enable( level );
153  return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
154
155equal_priority:               /* add at end of priority group */
156  search_node   = _Chain_Tail( &search_thread->Wait.Block2n );
157  previous_node = search_node->previous;
158  the_node      = (Chain_Node *) the_thread;
159
160  the_node->next         = search_node;
161  the_node->previous     = previous_node;
162  previous_node->next    = the_node;
163  search_node->previous  = the_node;
164  the_thread->Wait.queue = the_thread_queue;
165  _ISR_Enable( level );
166  return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
167
168synchronize:
169  /*
170   *  An interrupt completed the thread's blocking request.
171   *  For example, the blocking thread could have been given
172   *  the mutex by an ISR or timed out.
173   *
174   *  WARNING! Returning with interrupts disabled!
175   */
176  *level_p = level;
177  return the_thread_queue->sync_state;
178}
Note: See TracBrowser for help on using the repository browser.