source: rtems/cpukit/score/src/threadqdequeuepriority.c @ b89f64c

4.104.114.95
Last change on this file since b89f64c was 96d0b64, checked in by Joel Sherrill <joel.sherrill@…>, on 03/05/07 at 21:01:40

2007-03-05 Joel Sherrill <joel@…>

PR 1222/cpukit

  • score/Makefile.am, score/include/rtems/score/coremutex.h, score/include/rtems/score/threadq.h, score/inline/rtems/score/coremutex.inl, score/src/coremsgsubmit.c, score/src/coremutexsurrender.c, score/src/threadchangepriority.c, score/src/threadclearstate.c, score/src/threadhandler.c, score/src/threadinitialize.c, score/src/threadqdequeuefifo.c, score/src/threadqdequeuepriority.c, score/src/threadqenqueue.c, score/src/threadqenqueuefifo.c, score/src/threadqenqueuepriority.c, score/src/threadqextractfifo.c, score/src/threadqextractpriority.c, score/src/threadsetstate.c: Enhance so that when the prioirity of a thread that is blocked on a priority based thread queue is changed, that its placement in the queue is reevaluated based upon the new priority. This enhancement includes modifications to the SuperCore? as well as new test cases.
  • score/src/threadqrequeue.c: New file.
  • Property mode set to 100644
File size: 3.6 KB
Line 
1/*
2 *  Thread Queue Handler
3 *
4 *
5 *  COPYRIGHT (c) 1989-2006.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 *
12 *  $Id$
13 */
14
15#if HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#include <rtems/system.h>
20#include <rtems/score/chain.h>
21#include <rtems/score/isr.h>
22#include <rtems/score/object.h>
23#include <rtems/score/states.h>
24#include <rtems/score/thread.h>
25#include <rtems/score/threadq.h>
26#include <rtems/score/tqdata.h>
27
28/*PAGE
29 *
30 *  _Thread_queue_Dequeue_priority
31 *
32 *  This routine removes a thread from the specified PRIORITY based
33 *  threadq, unblocks it, and cancels its timeout timer.
34 *
35 *  Input parameters:
36 *    the_thread_queue - pointer to thread queue
37 *
38 *  Output parameters:
39 *    returns - thread dequeued or NULL
40 *
41 *  INTERRUPT LATENCY:
42 *    only case
43 */
44
45Thread_Control *_Thread_queue_Dequeue_priority(
46  Thread_queue_Control *the_thread_queue
47)
48{
49  uint32_t        index;
50  ISR_Level       level;
51  Thread_Control *the_thread = NULL;  /* just to remove warnings */
52  Thread_Control *new_first_thread;
53  Chain_Node     *new_first_node;
54  Chain_Node     *new_second_node;
55  Chain_Node     *last_node;
56  Chain_Node     *next_node;
57  Chain_Node     *previous_node;
58
59  _ISR_Disable( level );
60  for( index=0 ;
61       index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
62       index++ ) {
63    if ( !_Chain_Is_empty( &the_thread_queue->Queues.Priority[ index ] ) ) {
64      the_thread = (Thread_Control *)
65                    the_thread_queue->Queues.Priority[ index ].first;
66      goto dequeue;
67    }
68  }
69
70  switch ( the_thread_queue->sync_state ) {
71    case THREAD_QUEUE_SYNCHRONIZED:
72    case THREAD_QUEUE_SATISFIED:
73      _ISR_Enable( level );
74      return NULL;
75
76    case THREAD_QUEUE_NOTHING_HAPPENED:
77    case THREAD_QUEUE_TIMEOUT:
78      the_thread_queue->sync_state = THREAD_QUEUE_SATISFIED;
79      _ISR_Enable( level );
80      return _Thread_Executing;
81  }
82
83dequeue:
84  the_thread->Wait.queue = NULL;
85  new_first_node   = the_thread->Wait.Block2n.first;
86  new_first_thread = (Thread_Control *) new_first_node;
87  next_node        = the_thread->Object.Node.next;
88  previous_node    = the_thread->Object.Node.previous;
89
90  if ( !_Chain_Is_empty( &the_thread->Wait.Block2n ) ) {
91    last_node       = the_thread->Wait.Block2n.last;
92    new_second_node = new_first_node->next;
93
94    previous_node->next      = new_first_node;
95    next_node->previous      = new_first_node;
96    new_first_node->next     = next_node;
97    new_first_node->previous = previous_node;
98
99    if ( !_Chain_Has_only_one_node( &the_thread->Wait.Block2n ) ) {
100                                                /* > two threads on 2-n */
101      new_second_node->previous =
102                _Chain_Head( &new_first_thread->Wait.Block2n );
103
104      new_first_thread->Wait.Block2n.first = new_second_node;
105      new_first_thread->Wait.Block2n.last  = last_node;
106
107      last_node->next = _Chain_Tail( &new_first_thread->Wait.Block2n );
108    }
109  } else {
110    previous_node->next = next_node;
111    next_node->previous = previous_node;
112  }
113
114  if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
115    _ISR_Enable( level );
116    _Thread_Unblock( the_thread );
117  } else {
118    _Watchdog_Deactivate( &the_thread->Timer );
119    _ISR_Enable( level );
120    (void) _Watchdog_Remove( &the_thread->Timer );
121    _Thread_Unblock( the_thread );
122  }
123
124#if defined(RTEMS_MULTIPROCESSING)
125  if ( !_Objects_Is_local_id( the_thread->Object.id ) )
126    _Thread_MP_Free_proxy( the_thread );
127#endif
128  return( the_thread );
129}
Note: See TracBrowser for help on using the repository browser.