1 #include "scheduler_edf.h"
4 #include <rtems/system.h>
5 #include <rtems/score/isr.h>
6 #include <rtems/score/watchdog.h>
7 #include <rtems/score/wkspace.h>
8 #include <rtems/score/percpu.h>
10 /* let the scheduler talk */
11 //#define SCHED_VERBOSE
14 void _Scheduler_edf_Initialize(void) {
16 printf("Sched: Initialize");
18 // initialize the RB tree
19 _Thread_Ready_EDF_chain.root = NULL;
20 _Thread_Ready_EDF_chain.first = NULL;
22 _Thread_Executing = NULL;
25 void _Scheduler_edf_Block( Thread_Control *the_thread ) {
27 printf("Sched: Block");
29 _Scheduler_edf_Extract(the_thread);
31 /* TODO: flash critical section? */
33 if ( _Thread_Is_heir( the_thread ) )
34 _Scheduler_edf_Schedule();
36 if ( _Thread_Is_executing( the_thread ) )
37 _Thread_Dispatch_necessary = true;
40 void _Scheduler_edf_Schedule(void) {
42 printf("Sched: Schedule");
45 _Thread_Heir = (Thread_Control *) _Thread_Ready_EDF_chain.first;
48 void * _Scheduler_edf_Allocate( Thread_Control *the_thread) {
50 printf("Sched: Allocate");
54 sched = _Workspace_Allocate (sizeof(RBT_Node));
55 the_thread->scheduler_info = (RBT_Node *) sched;
56 //the_thread->real_priority = ABS_DEADLINE_MAXIMUM - _Watchdog_Ticks_since_boot-2;
57 //the_thread->is_preemptible = TRUE;
58 //the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
59 //the_thread->budget_callout = NULL;
61 schinfo = (RBT_Node *)(the_thread->scheduler_info);
62 schinfo->rel_deadline = the_thread->real_priority;
63 schinfo->abs_deadline = 0;
65 schinfo->right = NULL;
66 schinfo->parent = NULL;
67 schinfo->ready_chain = &_Thread_Ready_EDF_chain;
72 void _Scheduler_edf_Free( Thread_Control *the_thread) {
74 printf("Sched: Free");
76 _Workspace_Free (the_thread->scheduler_info);
79 void _Scheduler_edf_Update( Thread_Control *the_thread) {
81 printf("Sched: Update");
83 // after a priority changes, just extract and insert again
84 //in case it is in the tree
85 // EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
86 // _RBT_Extract(chain, the_thread);
87 // _RBT_Insert(chain, the_thread); // preserve the abs_deadline
90 void _Scheduler_edf_Unblock( Thread_Control *the_thread ) {
92 printf("Sched: Unblock");
94 _Scheduler_edf_Enqueue(the_thread);
95 /* TODO: flash critical section? */
98 * If the thread that was unblocked is more important than the heir,
99 * then we have a new heir. This may or may not result in a
103 * If the current thread is preemptible, then we need to do
106 * Even if the thread isn't preemptible, if the new heir is
107 * a pseudo-ISR system task, we need to do a context switch.
109 if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
110 _Thread_Heir = the_thread;
111 if ( _Thread_Executing->is_preemptible || the_thread->current_priority == 0 )
112 _Thread_Dispatch_necessary = true;
116 void _Scheduler_edf_Yield( void ) {
118 printf("Sched: Yield");
121 RBT_Node *sched_info;
123 Thread_Control *executing;
124 EDF_Chain_Control *ready;
126 executing = _Thread_Executing;
127 sched_info = (RBT_Node *) executing->scheduler_info;
128 ready = sched_info->ready_chain;
129 _ISR_Disable( level );
130 if ( !_RBT_Has_only_one_node( ready ) ) {
131 _RBT_Extract(ready,executing);
132 _RBT_Insert(ready,executing); // preserve the abs_deadline
136 if ( _Thread_Is_heir( executing ) )
137 _Thread_Heir = (Thread_Control *) ready->first;
138 _Thread_Dispatch_necessary = TRUE;
140 else if ( !_Thread_Is_heir( executing ) )
141 _Thread_Dispatch_necessary = TRUE;
143 _ISR_Enable( level );
147 void _Scheduler_edf_Enqueue( Thread_Control *the_thread) {
149 printf("Sched: Enqueue");
151 RBT_Node *node = (RBT_Node*)the_thread->scheduler_info;
152 EDF_Chain_Control *chain = node->ready_chain;
153 if (node->rel_deadline == 255) //hack for idle task
154 node->abs_deadline = ABS_DEADLINE_MAXIMUM;
156 node->abs_deadline = _Watchdog_Ticks_since_boot + node->rel_deadline;
157 _RBT_Insert(chain,the_thread);
161 void _Scheduler_edf_Enqueue_first( Thread_Control *the_thread) {
163 printf("Sched: Enqueue_first");
165 // FIXME: force first position
166 _Scheduler_edf_Enqueue(the_thread);
169 void _Scheduler_edf_Extract( Thread_Control *the_thread) {
171 printf("Sched: Extract");
173 EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
174 _RBT_Extract(chain,the_thread);