]> rtime.felk.cvut.cz Git - rtems-pluggable-edf.git/blobdiff - src/edf/scheduler_edf.c
Bug in _Scheduler_edf_Update and initial priority shift fixed. Running.
[rtems-pluggable-edf.git] / src / edf / scheduler_edf.c
index 8212a90621a0489e863f2c73bed2f2e0c8709994..5568009aa8f107769fd258eecd8cbbdacd8c1ca0 100644 (file)
@@ -14,8 +14,9 @@
  * The threads wanted to be served on a priority base will be assigned the very 
  * longest deadlines.
  */ 
-#define edf_initial_priority_shift(init_prio)  \
-       (init_prio + EDF_ABS_DEADLINE_MAX + 1)
+// inline void edf_initial_priority_shift(Priority_Control *prio) {
+//     prio += EDF_ABS_DEADLINE_MAX + 1;
+// }
 
 void edf_next_period(Thread_Control *the_thread) {
        RBT_Node *node = (RBT_Node*)the_thread->scheduler_info; 
@@ -68,11 +69,15 @@ void * _Scheduler_edf_Allocate(  Thread_Control      *the_thread) {
        RBT_Node *schinfo;
        sched = _Workspace_Allocate (sizeof(RBT_Node));
        the_thread->scheduler_info = (RBT_Node *) sched;
-       the_thread->real_priority = the_thread->current_priority = edf_initial_priority_shift(the_thread->real_priority);
+       //edf_initial_priority_shift(&(the_thread->real_priority));
+       
+       the_thread->real_priority += (EDF_HYBRID_MASK);
+       the_thread->current_priority = the_thread->real_priority;
        
        schinfo = (RBT_Node *)(the_thread->scheduler_info);
        schinfo->rel_deadline = 0;      // This has to be negotiated afterwards
        schinfo->abs_deadline = 0;
+       schinfo->is_enqueued = 0;
        schinfo->left = NULL;
        schinfo->right = NULL;
        schinfo->parent = NULL;
@@ -86,17 +91,20 @@ void _Scheduler_edf_Free(  Thread_Control      *the_thread) {
 }
 
 void _Scheduler_edf_Update(  Thread_Control      *the_thread) {
+       RBT_Node *node = (RBT_Node*)the_thread->scheduler_info;
        // Update deadlines for deadline driven tasks
        if (!(the_thread->current_priority && EDF_HYBRID_MASK))
                ((RBT_Node*)the_thread->scheduler_info)->abs_deadline = the_thread->current_priority;   
        else
                ((RBT_Node*)the_thread->scheduler_info)->abs_deadline = 0;      
-       _Scheduler_edf_Extract(the_thread); 
-       _Scheduler_edf_Enqueue(the_thread); 
-       if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
-               _Thread_Heir = the_thread;
-               if ( _Thread_Executing->is_preemptible || the_thread->current_priority == 0 )
-                       _Thread_Dispatch_necessary = true;      
+       if(node->is_enqueued) {
+               _Scheduler_edf_Extract(the_thread); 
+               _Scheduler_edf_Enqueue(the_thread); 
+               if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
+                       _Thread_Heir = the_thread;
+                       if ( _Thread_Executing->is_preemptible || the_thread->current_priority == 0 )
+                               _Thread_Dispatch_necessary = true;      
+               }
        }
 }
 
@@ -134,8 +142,8 @@ void _Scheduler_edf_Yield( void ) {
        ready      = sched_info->ready_chain;
        _ISR_Disable( level );
        if ( !_RBT_Has_only_one_node( ready ) ) {
-               _RBT_Extract(ready,executing); 
-               _RBT_Insert(ready,executing); // preserve the abs_deadline
+               _Scheduler_edf_Extract(executing); 
+               _Scheduler_edf_Enqueue(executing); // preserve the abs_deadline
 
                _ISR_Flash( level );
 
@@ -155,6 +163,7 @@ void _Scheduler_edf_Enqueue(  Thread_Control    *the_thread) {
        EDF_Chain_Control *chain = node->ready_chain;
 
        _RBT_Insert(chain,the_thread);
+       node->is_enqueued = 1;
 }
 
 void _Scheduler_edf_Enqueue_first(  Thread_Control    *the_thread) {
@@ -163,7 +172,10 @@ void _Scheduler_edf_Enqueue_first(  Thread_Control    *the_thread) {
 }
 
 void _Scheduler_edf_Extract(  Thread_Control     *the_thread) {
+       RBT_Node *node = (RBT_Node*)the_thread->scheduler_info;
        EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
+       
        _RBT_Extract(chain,the_thread);
+       node->is_enqueued = 0;
 }