source: rtems/cpukit/score/src/threadqops.c @ 3b3d1489

5
Last change on this file since 3b3d1489 was 341f629, checked in by Sebastian Huber <sebastian.huber@…>, on 08/21/15 at 03:39:59

rbtree: Add _RBTree_Minimum(), _RBTree_Maximum()

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#if HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/score/threadimpl.h>
20#include <rtems/score/assert.h>
21#include <rtems/score/chainimpl.h>
22#include <rtems/score/rbtreeimpl.h>
23
24static void _Thread_queue_Do_nothing_priority_change(
25  Thread_Control     *the_thread,
26  Priority_Control    new_priority,
27  Thread_queue_Queue *queue
28)
29{
30  /* Do nothing */
31}
32
33static void _Thread_queue_Do_nothing_extract(
34  Thread_queue_Queue *queue,
35  Thread_Control    *the_thread
36)
37{
38  /* Do nothing */
39}
40
41static void _Thread_queue_Queue_enqueue(
42  Thread_queue_Queue *queue,
43  Thread_Control     *the_thread,
44  void             ( *initialize )( Thread_queue_Heads * ),
45  void             ( *enqueue )( Thread_queue_Heads *, Thread_Control * )
46)
47{
48  Thread_queue_Heads *heads = queue->heads;
49  Thread_queue_Heads *spare_heads = the_thread->Wait.spare_heads;
50
51  the_thread->Wait.spare_heads = NULL;
52
53  if ( heads == NULL ) {
54    _Assert( spare_heads != NULL );
55    _Assert( _Chain_Is_empty( &spare_heads->Free_chain ) );
56    heads = spare_heads;
57    queue->heads = heads;
58    ( *initialize )( heads );
59  }
60
61  _Chain_Prepend_unprotected( &heads->Free_chain, &spare_heads->Free_node );
62
63  ( *enqueue )( heads, the_thread );
64}
65
66static void _Thread_queue_Queue_extract(
67  Thread_queue_Queue *queue,
68  Thread_Control     *the_thread,
69  void             ( *extract )( Thread_queue_Heads *, Thread_Control * )
70)
71{
72  Thread_queue_Heads *heads = queue->heads;
73
74  _Assert( heads != NULL );
75
76  the_thread->Wait.spare_heads = RTEMS_CONTAINER_OF(
77    _Chain_Get_first_unprotected( &heads->Free_chain ),
78    Thread_queue_Heads,
79    Free_node
80  );
81
82  if ( _Chain_Is_empty( &heads->Free_chain ) ) {
83    queue->heads = NULL;
84  }
85
86  ( *extract )( heads, the_thread );
87}
88
89static void _Thread_queue_FIFO_do_initialize(
90  Thread_queue_Heads *heads
91)
92{
93  _Chain_Initialize_empty( &heads->Heads.Fifo );
94}
95
96static void _Thread_queue_FIFO_do_enqueue(
97  Thread_queue_Heads *heads,
98  Thread_Control     *the_thread
99)
100{
101  _Chain_Append_unprotected(
102    &heads->Heads.Fifo,
103    &the_thread->Wait.Node.Chain
104  );
105}
106
107static void _Thread_queue_FIFO_do_extract(
108  Thread_queue_Heads *heads,
109  Thread_Control     *the_thread
110)
111{
112  _Chain_Extract_unprotected( &the_thread->Wait.Node.Chain );
113}
114
115static void _Thread_queue_FIFO_enqueue(
116  Thread_queue_Queue *queue,
117  Thread_Control     *the_thread
118)
119{
120  _Thread_queue_Queue_enqueue(
121    queue,
122    the_thread,
123    _Thread_queue_FIFO_do_initialize,
124    _Thread_queue_FIFO_do_enqueue
125  );
126}
127
128static void _Thread_queue_FIFO_extract(
129  Thread_queue_Queue *queue,
130  Thread_Control     *the_thread
131)
132{
133  _Thread_queue_Queue_extract(
134    queue,
135    the_thread,
136    _Thread_queue_FIFO_do_extract
137  );
138}
139
140static Thread_Control *_Thread_queue_FIFO_first(
141  Thread_queue_Heads *heads
142)
143{
144  Chain_Control *fifo = &heads->Heads.Fifo;
145
146  return _Chain_Is_empty( fifo ) ?
147    NULL : THREAD_CHAIN_NODE_TO_THREAD( _Chain_First( fifo ) );
148}
149
150static void _Thread_queue_Priority_priority_change(
151  Thread_Control     *the_thread,
152  Priority_Control    new_priority,
153  Thread_queue_Queue *queue
154)
155{
156  Thread_queue_Heads *heads = queue->heads;
157
158  _Assert( heads != NULL );
159
160  _RBTree_Extract(
161    &heads->Heads.Priority,
162    &the_thread->Wait.Node.RBTree
163  );
164  _RBTree_Insert(
165    &heads->Heads.Priority,
166    &the_thread->Wait.Node.RBTree,
167    _Thread_queue_Compare_priority,
168    false
169  );
170}
171
172static void _Thread_queue_Priority_do_initialize(
173  Thread_queue_Heads *heads
174)
175{
176  _RBTree_Initialize_empty( &heads->Heads.Priority );
177}
178
179static void _Thread_queue_Priority_do_enqueue(
180  Thread_queue_Heads *heads,
181  Thread_Control     *the_thread
182)
183{
184  _RBTree_Insert(
185    &heads->Heads.Priority,
186    &the_thread->Wait.Node.RBTree,
187    _Thread_queue_Compare_priority,
188    false
189  );
190}
191
192static void _Thread_queue_Priority_do_extract(
193  Thread_queue_Heads *heads,
194  Thread_Control     *the_thread
195)
196{
197  _RBTree_Extract(
198    &heads->Heads.Priority,
199    &the_thread->Wait.Node.RBTree
200  );
201}
202
203static void _Thread_queue_Priority_enqueue(
204  Thread_queue_Queue *queue,
205  Thread_Control     *the_thread
206)
207{
208  _Thread_queue_Queue_enqueue(
209    queue,
210    the_thread,
211    _Thread_queue_Priority_do_initialize,
212    _Thread_queue_Priority_do_enqueue
213  );
214}
215
216static void _Thread_queue_Priority_extract(
217  Thread_queue_Queue *queue,
218  Thread_Control     *the_thread
219)
220{
221  _Thread_queue_Queue_extract(
222    queue,
223    the_thread,
224    _Thread_queue_Priority_do_extract
225  );
226}
227
228static Thread_Control *_Thread_queue_Priority_first(
229  Thread_queue_Heads *heads
230)
231{
232  RBTree_Node *first;
233
234  first = _RBTree_Minimum( &heads->Heads.Priority );
235
236  return first != NULL ? THREAD_RBTREE_NODE_TO_THREAD( first ) : NULL;
237}
238
239const Thread_queue_Operations _Thread_queue_Operations_default = {
240  .priority_change = _Thread_queue_Do_nothing_priority_change,
241  .extract = _Thread_queue_Do_nothing_extract
242  /*
243   * The default operations are only used in _Thread_Change_priority() and
244   * _Thread_Timeout() and don't have a thread queue associated with them, so
245   * the enqueue and first operations are superfluous.
246   */
247};
248
249const Thread_queue_Operations _Thread_queue_Operations_FIFO = {
250  .priority_change = _Thread_queue_Do_nothing_priority_change,
251  .enqueue = _Thread_queue_FIFO_enqueue,
252  .extract = _Thread_queue_FIFO_extract,
253  .first = _Thread_queue_FIFO_first
254};
255
256const Thread_queue_Operations _Thread_queue_Operations_priority = {
257  .priority_change = _Thread_queue_Priority_priority_change,
258  .enqueue = _Thread_queue_Priority_enqueue,
259  .extract = _Thread_queue_Priority_extract,
260  .first = _Thread_queue_Priority_first
261};
Note: See TracBrowser for help on using the repository browser.