]> rtime.felk.cvut.cz Git - rtems-pluggable-edf.git/blob - rtems-omk-template/appfoo/scheduler_edf.c
2cbd8b3419eaaf1e5f70d4269917087829015770
[rtems-pluggable-edf.git] / rtems-omk-template / appfoo / scheduler_edf.c
1 #include "scheduler_edf.h"
2 #include "rbtree.h"
3 #include <stdio.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
9 /* let the scheduler talk */
10 #define SCHED_VERBOSE
11
12
13 void _Scheduler_edf_Initialize(void) {
14         #ifdef SCHED_VERBOSE
15         printf("Sched: Initialize");
16         #endif
17         // initialize the RB tree
18         _Thread_Ready_EDF_chain.root = NULL;
19         _Thread_Ready_EDF_chain.first = NULL;
20         _Thread_Heir = NULL;
21         _Thread_Executing = NULL;
22 }
23
24 void _Scheduler_edf_Block(  Thread_Control    *the_thread ) {
25         #ifdef SCHED_VERBOSE
26         printf("Sched: Block");
27         #endif
28         _Scheduler_edf_Extract(the_thread);
29 }
30
31 void _Scheduler_edf_Schedule(void) {
32         #ifdef SCHED_VERBOSE
33         printf("Sched: Schedule");
34         #endif
35         // set the heir
36         _Thread_Heir = (Thread_Control *) _Thread_Ready_EDF_chain.first;
37 }
38
39 void * _Scheduler_edf_Allocate(  Thread_Control      *the_thread) {
40         #ifdef SCHED_VERBOSE
41         printf("Sched: Allocate");
42         #endif
43         void * sched;
44         RBT_Node *schinfo;
45         sched = _Workspace_Allocate (sizeof(RBT_Node));
46         the_thread->scheduler_info = (RBT_Node *) sched;
47         the_thread->real_priority = ABS_DEADLINE_MAXIMUM - _Watchdog_Ticks_since_boot-2;
48         the_thread->is_preemptible = TRUE;
49         the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
50         the_thread->budget_callout = NULL;
51         
52         schinfo = (RBT_Node *)(the_thread->scheduler_info);
53         schinfo->rel_deadline = the_thread->real_priority;
54         schinfo->abs_deadline = 0;
55         schinfo->left = NULL;
56         schinfo->right = NULL;
57         schinfo->parent = NULL;
58         schinfo->ready_chain = &_Thread_Ready_EDF_chain;
59
60         return sched;
61 }
62
63 void _Scheduler_edf_Free(  Thread_Control      *the_thread) {
64         #ifdef SCHED_VERBOSE
65         printf("Sched: Free");
66         #endif
67         _Workspace_Free (the_thread->scheduler_info);
68 }
69
70 void _Scheduler_edf_Update(  Thread_Control      *the_thread) {
71         #ifdef SCHED_VERBOSE
72         printf("Sched: Update");
73         #endif
74         // after a priority changes, just extract and insert again
75         //in case it is in the tree
76         EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
77         _RBT_Extract(chain, the_thread); 
78         _RBT_Insert(chain, the_thread); // preserve the abs_deadline
79 }
80
81 void _Scheduler_edf_Unblock(  Thread_Control    *the_thread ) {
82         #ifdef SCHED_VERBOSE
83         printf("Sched: Unblock");
84         #endif
85         _Scheduler_edf_Enqueue(the_thread);
86 }
87
88 void _Scheduler_edf_Yield( void ) {
89         #ifdef SCHED_VERBOSE
90         printf("Sched: Yield");
91         #endif
92         
93         RBT_Node *sched_info;
94         ISR_Level                      level;
95         Thread_Control                *executing;
96         EDF_Chain_Control                 *ready;
97
98         executing  = _Thread_Executing;
99         sched_info = (RBT_Node *) executing->scheduler_info;
100         ready      = sched_info->ready_chain;
101         _ISR_Disable( level );
102         if ( !_RBT_Has_only_one_node( ready ) ) {
103                 _RBT_Extract(ready,executing); 
104                 _RBT_Insert(ready,executing); // preserve the abs_deadline
105
106                 _ISR_Flash( level );
107
108                 if ( _Thread_Is_heir( executing ) )
109                         _Thread_Heir = (Thread_Control *) ready->first;
110                 _Thread_Dispatch_necessary = TRUE;
111         }
112         else if ( !_Thread_Is_heir( executing ) )
113                 _Thread_Dispatch_necessary = TRUE;
114
115         _ISR_Enable( level );
116         // --------------------------------
117         
118 }
119
120 void _Scheduler_edf_Enqueue(  Thread_Control    *the_thread) {
121         #ifdef SCHED_VERBOSE
122         printf("Sched: Enqueue");
123         #endif
124         RBT_Node *node = (RBT_Node*)the_thread->scheduler_info;
125         EDF_Chain_Control *chain = node->ready_chain;
126         node->abs_deadline = _Watchdog_Ticks_since_boot + node->rel_deadline;
127         _RBT_Insert(chain,the_thread);
128 }
129
130 void _Scheduler_edf_Enqueue_first(  Thread_Control    *the_thread) {
131         #ifdef SCHED_VERBOSE
132         printf("Sched: Enqueue_first");
133         #endif
134         // FIXME: force first position
135         EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
136         _RBT_Insert(chain,the_thread);
137 }
138
139 void _Scheduler_edf_Extract(  Thread_Control     *the_thread) {
140         #ifdef SCHED_VERBOSE
141         printf("Sched: Extract");
142         #endif
143         EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
144         _RBT_Extract(chain,the_thread);
145 }
146