source: rtems/cpukit/score/include/rtems/score/schedulerimpl.h @ cfe457f

4.115
Last change on this file since cfe457f was cfe457f, checked in by Jennifer Averett <jennifer.averett@…>, on 03/06/14 at 14:37:21

score: score: Add get/set affinity to Scheduler Framework.

  • Property mode set to 100644
File size: 9.0 KB
Line 
1/**
2 * @file
3 *
4 * @brief Inlined Routines Associated with the Manipulation of the Scheduler
5 *
6 * This inline file contains all of the inlined routines associated with
7 * the manipulation of the scheduler.
8 */
9
10/*
11 *  Copyright (C) 2010 Gedare Bloom.
12 *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_SCHEDULERIMPL_H
20#define _RTEMS_SCORE_SCHEDULERIMPL_H
21
22#include <rtems/score/scheduler.h>
23#include <rtems/score/threadimpl.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29/**
30 * @addtogroup ScoreScheduler
31 */
32/**@{**/
33
34/**
35 *  @brief Initializes the scheduler to the policy chosen by the user.
36 *
37 *  This routine initializes the scheduler to the policy chosen by the user
38 *  through confdefs, or to the priority scheduler with ready chains by
39 *  default.
40 */
41void _Scheduler_Handler_initialization( void );
42
43/**
44 * The preferred method to add a new scheduler is to define the jump table
45 * entries and add a case to the _Scheduler_Initialize routine.
46 *
47 * Generic scheduling implementations that rely on the ready queue only can
48 * be found in the _Scheduler_queue_XXX functions.
49 */
50
51/*
52 * Passing the Scheduler_Control* to these functions allows for multiple
53 * scheduler's to exist simultaneously, which could be useful on an SMP
54 * system.  Then remote Schedulers may be accessible.  How to protect such
55 * accesses remains an open problem.
56 */
57
58/**
59 * @brief Scheduler schedule.
60 *
61 * This kernel routine implements the scheduling decision logic for
62 * the scheduler. It does NOT dispatch.
63 *
64 * @param[in] thread The thread which state changed previously.
65 */
66RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *thread )
67{
68  _Scheduler.Operations.schedule( thread );
69}
70
71/**
72 * @brief Scheduler yield with a particular thread.
73 *
74 * This routine is invoked when a thread wishes to voluntarily transfer control
75 * of the processor to another thread.
76 *
77 * @param[in] thread The yielding thread.
78 */
79RTEMS_INLINE_ROUTINE void _Scheduler_Yield(
80  Thread_Control *thread
81)
82{
83  ( *_Scheduler.Operations.yield )( thread );
84}
85
86/**
87 * @brief Scheduler block.
88 *
89 * This routine removes @a the_thread from the scheduling decision for
90 * the scheduler. The primary task is to remove the thread from the
91 * ready queue.  It performs any necessary schedulering operations
92 * including the selection of a new heir thread.
93 */
94RTEMS_INLINE_ROUTINE void _Scheduler_Block(
95    Thread_Control    *the_thread
96)
97{
98  _Scheduler.Operations.block( the_thread );
99}
100
101/**
102 * @brief Scheduler unblock.
103 *
104 * This routine adds @a the_thread to the scheduling decision for
105 * the scheduler.  The primary task is to add the thread to the
106 * ready queue per the schedulering policy and update any appropriate
107 * scheduling variables, for example the heir thread.
108 */
109RTEMS_INLINE_ROUTINE void _Scheduler_Unblock(
110    Thread_Control    *the_thread
111)
112{
113  _Scheduler.Operations.unblock( the_thread );
114}
115
116/**
117 * @brief Scheduler allocate.
118 *
119 * This routine allocates @a the_thread->scheduler
120 */
121RTEMS_INLINE_ROUTINE void* _Scheduler_Allocate(
122  Thread_Control    *the_thread
123)
124{
125  return _Scheduler.Operations.allocate( the_thread );
126}
127
128/**
129 * @brief Scheduler free.
130 *
131 * This routine frees @a the_thread->scheduler
132 */
133RTEMS_INLINE_ROUTINE void _Scheduler_Free(
134  Thread_Control    *the_thread
135)
136{
137  _Scheduler.Operations.free( the_thread );
138}
139
140/**
141 * @brief Scheduler update.
142 *
143 * This routine updates @a the_thread->scheduler
144 */
145RTEMS_INLINE_ROUTINE void _Scheduler_Update(
146  Thread_Control    *the_thread
147)
148{
149  _Scheduler.Operations.update( the_thread );
150}
151
152/**
153 * @brief Scheduler enqueue.
154 *
155 * This routine enqueue @a the_thread->scheduler
156 */
157RTEMS_INLINE_ROUTINE void _Scheduler_Enqueue(
158  Thread_Control    *the_thread
159)
160{
161  _Scheduler.Operations.enqueue( the_thread );
162}
163
164/**
165 * @brief Scheduler enqueue first.
166 *
167 * This routine enqueue_first @a the_thread->scheduler
168 */
169RTEMS_INLINE_ROUTINE void _Scheduler_Enqueue_first(
170  Thread_Control    *the_thread
171)
172{
173  _Scheduler.Operations.enqueue_first( the_thread );
174}
175
176/**
177 * @brief Scheduler extract.
178 *
179 * This routine extract @a the_thread->scheduler
180 */
181RTEMS_INLINE_ROUTINE void _Scheduler_Extract(
182  Thread_Control    *the_thread
183)
184{
185  _Scheduler.Operations.extract( the_thread );
186}
187
188/**
189 * @brief Scheduler priority compare.
190 *
191 * This routine compares two priorities.
192 */
193RTEMS_INLINE_ROUTINE int _Scheduler_Priority_compare(
194  Priority_Control p1,
195  Priority_Control p2
196)
197{
198  return _Scheduler.Operations.priority_compare(p1, p2);
199}
200
201/**
202 * @brief Scheduler release job.
203 *
204 * This routine is called when a new period of task is issued.
205 */
206RTEMS_INLINE_ROUTINE void _Scheduler_Release_job(
207  Thread_Control *the_thread,
208  uint32_t       length
209)
210{
211  _Scheduler.Operations.release_job(the_thread, length);
212}
213
214/**
215 * @brief Scheduler method invoked at each clock tick.
216 *
217 * This method is invoked at each clock tick to allow the scheduler
218 * implementation to perform any activities required.  For the
219 * scheduler which support standard RTEMS features, this includes
220 * time-slicing management.
221 */
222RTEMS_INLINE_ROUTINE void _Scheduler_Tick( void )
223{
224  _Scheduler.Operations.tick();
225}
226
227/**
228 * @brief Starts the idle thread for a particular processor.
229 *
230 * @param[in,out] thread The idle thread for the processor.
231 * @parma[in,out] processor The processor for the idle thread.
232 *
233 * @see _Thread_Create_idle().
234 */
235RTEMS_INLINE_ROUTINE void _Scheduler_Start_idle(
236  Thread_Control *thread,
237  Per_CPU_Control *processor
238)
239{
240  ( *_Scheduler.Operations.start_idle )( thread, processor );
241}
242
243#if defined(__RTEMS_HAVE_SYS_CPUSET_H__) && defined(RTEMS_SMP)
244  /**
245   * @brief Obtain the processor affinity for a thread.
246   *
247   * @param[in,out] thread The thread.
248   * @parma[out] cpuset The processor affinity for this thread
249   */
250  RTEMS_INLINE_ROUTINE int _Scheduler_Get_affinity(
251    Thread_Control *thread,
252    size_t          cpusetsize,
253    cpu_set_t      *cpuset
254  )
255  {
256    return (*_Scheduler.Operations.get_affinity)( thread, cpusetsize, cpuset );
257  }
258
259  /**
260   * @brief Set the processor affinity for a thread.
261   *
262   * @param[in,out] thread The thread.
263   * @parma[in] cpuset The processor affinity for this thread
264   */
265  RTEMS_INLINE_ROUTINE int _Scheduler_Set_affinity(
266    Thread_Control   *thread,
267    size_t            cpusetsize,
268    const cpu_set_t  *cpuset
269  )
270  {
271    return (*_Scheduler.Operations.set_affinity)( thread, cpusetsize, cpuset );
272  }
273#endif
274
275RTEMS_INLINE_ROUTINE void _Scheduler_Update_heir(
276  Thread_Control *heir,
277  bool force_dispatch
278)
279{
280  Thread_Control *executing = _Thread_Executing;
281
282  _Thread_Heir = heir;
283
284  if ( executing != heir && ( force_dispatch || executing->is_preemptible ) )
285    _Thread_Dispatch_necessary = true;
286}
287
288RTEMS_INLINE_ROUTINE void _Scheduler_Generic_block(
289  void ( *extract )( Thread_Control *thread ),
290  void ( *schedule )( Thread_Control *thread, bool force_dispatch ),
291  Thread_Control *thread
292)
293{
294  ( *extract )( thread );
295
296  /* TODO: flash critical section? */
297
298  if ( _Thread_Is_executing( thread ) || _Thread_Is_heir( thread ) ) {
299    ( *schedule )( thread, true );
300  }
301}
302
303/**
304 * @brief Returns true if @p1 encodes a lower priority than @a p2 in the
305 * intuitive sense of priority.
306 */
307RTEMS_INLINE_ROUTINE bool _Scheduler_Is_priority_lower_than(
308  Priority_Control p1,
309  Priority_Control p2
310)
311{
312  return _Scheduler_Priority_compare( p1,  p2 ) < 0;
313}
314
315/**
316 * @brief Returns true if @p1 encodes a higher priority than @a p2 in the
317 * intuitive sense of priority.
318 */
319RTEMS_INLINE_ROUTINE bool _Scheduler_Is_priority_higher_than(
320  Priority_Control p1,
321  Priority_Control p2
322)
323{
324  return _Scheduler_Priority_compare( p1,  p2 ) > 0;
325}
326
327/**
328 * @brief Returns the priority encoding @a p1 or @a p2 with the higher priority
329 * in the intuitive sense of priority.
330 */
331RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Highest_priority_of_two(
332  Priority_Control p1,
333  Priority_Control p2
334)
335{
336  return _Scheduler_Is_priority_higher_than( p1, p2 ) ? p1 : p2;
337}
338
339/**
340 * @brief Sets the thread priority to @a priority if it is higher than the
341 * current priority of the thread in the intuitive sense of priority.
342 */
343RTEMS_INLINE_ROUTINE void _Scheduler_Set_priority_if_higher(
344  Thread_Control   *the_thread,
345  Priority_Control  priority
346)
347{
348  Priority_Control current = the_thread->current_priority;
349
350  if ( _Scheduler_Is_priority_higher_than( priority, current ) ) {
351    _Thread_Set_priority( the_thread, priority );
352  }
353}
354
355/**
356 * @brief Changes the thread priority to @a priority if it is higher than the
357 * current priority of the thread in the intuitive sense of priority.
358 */
359RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority_if_higher(
360  Thread_Control   *the_thread,
361  Priority_Control  priority,
362  bool              prepend_it
363)
364{
365  Priority_Control current = the_thread->current_priority;
366
367  if ( _Scheduler_Is_priority_higher_than( priority, current ) ) {
368    _Thread_Change_priority( the_thread, priority, prepend_it );
369  }
370}
371
372/** @} */
373
374#ifdef __cplusplus
375}
376#endif
377
378#endif
379/* end of include file */
Note: See TracBrowser for help on using the repository browser.