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

4.115
Last change on this file since d7c3883 was ce002b16, checked in by Sebastian Huber <sebastian.huber@…>, on 11/25/10 at 09:27:06

2010-11-25 Sebastian Huber <sebastian.huber@…>

  • libfs/src/dosfs/fat_file.c, libfs/src/imfs/imfs_debug.c, libfs/src/imfs/imfs_directory.c, libfs/src/imfs/imfs_getchild.c, posix/src/killinfo.c, score/inline/rtems/score/schedulerpriority.inl, score/inline/rtems/score/watchdog.inl, score/src/apiext.c, score/src/chain.c, score/src/coremsgflushsupp.c, score/src/coremsginsert.c, score/src/objectshrinkinformation.c, score/src/schedulerpriorityyield.c, score/src/threadqdequeuepriority.c, score/src/threadqenqueuepriority.c, score/src/threadqextractpriority.c, score/src/threadqfirstfifo.c, score/src/threadqfirstpriority.c, score/src/threadyieldprocessor.c, score/src/userextthreadbegin.c, score/src/userextthreadcreate.c, score/src/userextthreaddelete.c, score/src/userextthreadrestart.c, score/src/userextthreadstart.c, score/src/userextthreadswitch.c, score/src/watchdogreportchain.c: Avoid chain API violations.
  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 *  Thread Queue Handler - Enqueue By Priority
3 *
4 *  COPYRIGHT (c) 1989-2009.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <rtems/system.h>
19#include <rtems/score/chain.h>
20#include <rtems/score/isr.h>
21#include <rtems/score/object.h>
22#include <rtems/score/states.h>
23#include <rtems/score/thread.h>
24#include <rtems/score/threadq.h>
25#include <rtems/score/tqdata.h>
26
27/*
28 *  Support the user forcing the unrolling to be disabled.
29 */
30#if __RTEMS_DO_NOT_UNROLL_THREADQ_ENQUEUE_PRIORITY__
31  #undef CPU_UNROLL_ENQUEUE_PRIORITY
32  #define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
33#endif
34
35/*PAGE
36 *
37 *  _Thread_queue_Enqueue_priority
38 *
39 *  This routine places a blocked thread on a priority thread queue.
40 *
41 *  Input parameters:
42 *    the_thread_queue - pointer to threadq
43 *    thread           - thread to insert
44 *
45 *  Output parameters: NONE
46 *
47 *  INTERRUPT LATENCY:
48 *    forward less than
49 *    forward equal
50 */
51
52Thread_blocking_operation_States _Thread_queue_Enqueue_priority (
53  Thread_queue_Control *the_thread_queue,
54  Thread_Control       *the_thread,
55  ISR_Level            *level_p
56)
57{
58  Priority_Control     search_priority;
59  Thread_Control      *search_thread;
60  ISR_Level            level;
61  Chain_Control       *header;
62  uint32_t             header_index;
63  Chain_Node          *the_node;
64  Chain_Node          *next_node;
65  Chain_Node          *previous_node;
66  Chain_Node          *search_node;
67  Priority_Control     priority;
68  States_Control       block_state;
69
70  _Chain_Initialize_empty( &the_thread->Wait.Block2n );
71
72  priority     = the_thread->current_priority;
73  header_index = _Thread_queue_Header_number( priority );
74  header       = &the_thread_queue->Queues.Priority[ header_index ];
75  block_state  = the_thread_queue->state;
76
77  if ( _Thread_queue_Is_reverse_search( priority ) )
78    goto restart_reverse_search;
79
80restart_forward_search:
81  search_priority = PRIORITY_MINIMUM - 1;
82  _ISR_Disable( level );
83  search_thread = (Thread_Control *) _Chain_First( header );
84  while ( !_Chain_Is_tail( header, (Chain_Node *)search_thread ) ) {
85    search_priority = search_thread->current_priority;
86    if ( priority <= search_priority )
87      break;
88
89#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE )
90    search_thread = (Thread_Control *) search_thread->Object.Node.next;
91    if ( _Chain_Is_tail( header, (Chain_Node *)search_thread ) )
92      break;
93    search_priority = search_thread->current_priority;
94    if ( priority <= search_priority )
95      break;
96#endif
97    _ISR_Flash( level );
98    if ( !_States_Are_set( search_thread->current_state, block_state) ) {
99      _ISR_Enable( level );
100      goto restart_forward_search;
101    }
102    search_thread =
103       (Thread_Control *)search_thread->Object.Node.next;
104  }
105
106  if ( the_thread_queue->sync_state !=
107       THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
108    goto synchronize;
109
110  the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
111
112  if ( priority == search_priority )
113    goto equal_priority;
114
115  search_node   = (Chain_Node *) search_thread;
116  previous_node = search_node->previous;
117  the_node      = (Chain_Node *) the_thread;
118
119  the_node->next         = search_node;
120  the_node->previous     = previous_node;
121  previous_node->next    = the_node;
122  search_node->previous  = the_node;
123  the_thread->Wait.queue = the_thread_queue;
124  _ISR_Enable( level );
125  return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
126
127restart_reverse_search:
128  search_priority     = PRIORITY_MAXIMUM + 1;
129
130  _ISR_Disable( level );
131  search_thread = (Thread_Control *) _Chain_Last( header );
132  while ( !_Chain_Is_head( header, (Chain_Node *)search_thread ) ) {
133    search_priority = search_thread->current_priority;
134    if ( priority >= search_priority )
135      break;
136#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE )
137    search_thread = (Thread_Control *) search_thread->Object.Node.previous;
138    if ( _Chain_Is_head( header, (Chain_Node *)search_thread ) )
139      break;
140    search_priority = search_thread->current_priority;
141    if ( priority >= search_priority )
142      break;
143#endif
144    _ISR_Flash( level );
145    if ( !_States_Are_set( search_thread->current_state, block_state) ) {
146      _ISR_Enable( level );
147      goto restart_reverse_search;
148    }
149    search_thread = (Thread_Control *)
150                         search_thread->Object.Node.previous;
151  }
152
153  if ( the_thread_queue->sync_state !=
154       THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
155    goto synchronize;
156
157  the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
158
159  if ( priority == search_priority )
160    goto equal_priority;
161
162  search_node = (Chain_Node *) search_thread;
163  next_node   = search_node->next;
164  the_node    = (Chain_Node *) the_thread;
165
166  the_node->next          = next_node;
167  the_node->previous      = search_node;
168  search_node->next       = the_node;
169  next_node->previous    = the_node;
170  the_thread->Wait.queue = the_thread_queue;
171  _ISR_Enable( level );
172  return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
173
174equal_priority:               /* add at end of priority group */
175  search_node   = _Chain_Tail( &search_thread->Wait.Block2n );
176  previous_node = search_node->previous;
177  the_node      = (Chain_Node *) the_thread;
178
179  the_node->next         = search_node;
180  the_node->previous     = previous_node;
181  previous_node->next    = the_node;
182  search_node->previous  = the_node;
183  the_thread->Wait.queue = the_thread_queue;
184  _ISR_Enable( level );
185  return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
186
187synchronize:
188  /*
189   *  An interrupt completed the thread's blocking request.
190   *  For example, the blocking thread could have been given
191   *  the mutex by an ISR or timed out.
192   *
193   *  WARNING! Returning with interrupts disabled!
194   */
195  *level_p = level;
196  return the_thread_queue->sync_state;
197}
Note: See TracBrowser for help on using the repository browser.