OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [score/] [src/] [threadqenqueuepriority.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
2
 *  Thread Queue Handler
3
 *
4
 *
5
 *  COPYRIGHT (c) 1989-1999.
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.OARcorp.com/rtems/license.html.
11
 *
12
 *  threadqenqueuepriority.c,v 1.2 1999/11/17 17:50:40 joel Exp
13
 */
14
 
15
#include <rtems/system.h>
16
#include <rtems/score/chain.h>
17
#include <rtems/score/isr.h>
18
#include <rtems/score/object.h>
19
#include <rtems/score/states.h>
20
#include <rtems/score/thread.h>
21
#include <rtems/score/threadq.h>
22
#include <rtems/score/tqdata.h>
23
 
24
/*PAGE
25
 *
26
 *  _Thread_queue_Enqueue_priority
27
 *
28
 *  This routine blocks a thread, places it on a thread, and optionally
29
 *  starts a timeout timer.
30
 *
31
 *  Input parameters:
32
 *    the_thread_queue - pointer to threadq
33
 *    thread           - thread to insert
34
 *    timeout          - timeout interval in ticks
35
 *
36
 *  Output parameters: NONE
37
 *
38
 *  INTERRUPT LATENCY:
39
 *    forward less than
40
 *    forward equal
41
 */
42
 
43
void _Thread_queue_Enqueue_priority(
44
  Thread_queue_Control *the_thread_queue,
45
  Thread_Control       *the_thread,
46
  Watchdog_Interval     timeout
47
)
48
{
49
  Priority_Control     search_priority;
50
  Thread_Control      *search_thread;
51
  ISR_Level            level;
52
  Chain_Control       *header;
53
  unsigned32           header_index;
54
  Chain_Node          *the_node;
55
  Chain_Node          *next_node;
56
  Chain_Node          *previous_node;
57
  Chain_Node          *search_node;
58
  Priority_Control     priority;
59
  States_Control       block_state;
60
  Thread_queue_States  sync_state;
61
 
62
  _Chain_Initialize_empty( &the_thread->Wait.Block2n );
63
 
64
  priority     = the_thread->current_priority;
65
  header_index = _Thread_queue_Header_number( priority );
66
  header       = &the_thread_queue->Queues.Priority[ header_index ];
67
  block_state  = the_thread_queue->state;
68
 
69
  if ( _Thread_queue_Is_reverse_search( priority ) )
70
    goto restart_reverse_search;
71
 
72
restart_forward_search:
73
  search_priority = PRIORITY_MINIMUM - 1;
74
  _ISR_Disable( level );
75
  search_thread = (Thread_Control *) header->first;
76
  while ( !_Chain_Is_tail( header, (Chain_Node *)search_thread ) ) {
77
    search_priority = search_thread->current_priority;
78
    if ( priority <= search_priority )
79
      break;
80
 
81
#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE )
82
    search_thread = (Thread_Control *) search_thread->Object.Node.next;
83
    if ( _Chain_Is_tail( header, (Chain_Node *)search_thread ) )
84
      break;
85
    search_priority = search_thread->current_priority;
86
    if ( priority <= search_priority )
87
      break;
88
#endif
89
    _ISR_Flash( level );
90
    if ( !_States_Are_set( search_thread->current_state, block_state) ) {
91
      _ISR_Enable( level );
92
      goto restart_forward_search;
93
    }
94
    search_thread =
95
       (Thread_Control *)search_thread->Object.Node.next;
96
  }
97
 
98
  if ( the_thread_queue->sync_state != THREAD_QUEUE_NOTHING_HAPPENED )
99
    goto synchronize;
100
 
101
  the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED;
102
 
103
  if ( priority == search_priority )
104
    goto equal_priority;
105
 
106
  search_node   = (Chain_Node *) search_thread;
107
  previous_node = search_node->previous;
108
  the_node      = (Chain_Node *) the_thread;
109
 
110
  the_node->next        = search_node;
111
  the_node->previous    = previous_node;
112
  previous_node->next   = the_node;
113
  search_node->previous = the_node;
114
  _ISR_Enable( level );
115
  return;
116
 
117
restart_reverse_search:
118
  search_priority     = PRIORITY_MAXIMUM + 1;
119
 
120
  _ISR_Disable( level );
121
  search_thread = (Thread_Control *) header->last;
122
  while ( !_Chain_Is_head( header, (Chain_Node *)search_thread ) ) {
123
    search_priority = search_thread->current_priority;
124
    if ( priority >= search_priority )
125
      break;
126
#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE )
127
    search_thread = (Thread_Control *) search_thread->Object.Node.previous;
128
    if ( _Chain_Is_head( header, (Chain_Node *)search_thread ) )
129
      break;
130
    search_priority = search_thread->current_priority;
131
    if ( priority >= search_priority )
132
      break;
133
#endif
134
    _ISR_Flash( level );
135
    if ( !_States_Are_set( search_thread->current_state, block_state) ) {
136
      _ISR_Enable( level );
137
      goto restart_reverse_search;
138
    }
139
    search_thread = (Thread_Control *)
140
                         search_thread->Object.Node.previous;
141
  }
142
 
143
  if ( the_thread_queue->sync_state != THREAD_QUEUE_NOTHING_HAPPENED )
144
    goto synchronize;
145
 
146
  the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED;
147
 
148
  if ( priority == search_priority )
149
    goto equal_priority;
150
 
151
  search_node = (Chain_Node *) search_thread;
152
  next_node   = search_node->next;
153
  the_node    = (Chain_Node *) the_thread;
154
 
155
  the_node->next      = next_node;
156
  the_node->previous  = search_node;
157
  search_node->next   = the_node;
158
  next_node->previous = the_node;
159
  _ISR_Enable( level );
160
  return;
161
 
162
equal_priority:               /* add at end of priority group */
163
  search_node   = _Chain_Tail( &search_thread->Wait.Block2n );
164
  previous_node = search_node->previous;
165
  the_node      = (Chain_Node *) the_thread;
166
 
167
  the_node->next        = search_node;
168
  the_node->previous    = previous_node;
169
  previous_node->next   = the_node;
170
  search_node->previous = the_node;
171
  _ISR_Enable( level );
172
  return;
173
 
174
synchronize:
175
 
176
  sync_state = the_thread_queue->sync_state;
177
  the_thread_queue->sync_state = THREAD_QUEUE_SYNCHRONIZED;
178
 
179
  switch ( sync_state ) {
180
    case THREAD_QUEUE_SYNCHRONIZED:
181
      /*
182
       *  This should never happen.  It indicates that someone did not
183
       *  enter a thread queue critical section.
184
       */
185
      break;
186
 
187
    case THREAD_QUEUE_NOTHING_HAPPENED:
188
      /*
189
       *  This should never happen.  All of this was dealt with above.
190
       */
191
      break;
192
 
193
    case THREAD_QUEUE_TIMEOUT:
194
      the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
195
      _ISR_Enable( level );
196
      break;
197
 
198
    case THREAD_QUEUE_SATISFIED:
199
      if ( _Watchdog_Is_active( &the_thread->Timer ) ) {
200
        _Watchdog_Deactivate( &the_thread->Timer );
201
        _ISR_Enable( level );
202
        (void) _Watchdog_Remove( &the_thread->Timer );
203
      } else
204
        _ISR_Enable( level );
205
      break;
206
  }
207
 
208
  /*
209
   *  Global objects with thread queue's should not be operated on from an
210
   *  ISR.  But the sync code still must allow short timeouts to be processed
211
   *  correctly.
212
   */
213
 
214
  _Thread_Unblock( the_thread );
215
 
216
#if defined(RTEMS_MULTIPROCESSING)
217
  if ( !_Objects_Is_local_id( the_thread->Object.id ) )
218
    _Thread_MP_Free_proxy( the_thread );
219
#endif
220
}
221
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.