]> rtime.felk.cvut.cz Git - rtems-pluggable-edf.git/commitdiff
Bug in _Scheduler_edf_Update and initial priority shift fixed. Running.
authorPetr Benes <benesp16@fel.cvut.cz>
Wed, 13 Apr 2011 14:18:02 +0000 (16:18 +0200)
committerPetr Benes <benesp16@fel.cvut.cz>
Wed, 13 Apr 2011 14:18:02 +0000 (16:18 +0200)
src/edf/edf_types.h
src/edf/rbtree.h
src/edf/scheduler_edf.c

index edb959fcd4687beef36cee56e67e76f13435d409..38dc0ecc8c72957ca9b25521d02ed13b1fc70477 100644 (file)
@@ -15,7 +15,7 @@ typedef uint32_t Deadline_Control;
 #define EDF_BYTES_FOR_TIME 4   // It is uint32_t
 //#define EDF_TIME_RANGE 0xffffffff
 
-#define EDF_ABS_DEADLINE_MAX ((1 << (EDF_BYTES_FOR_TIME*4)) - 1)
+
 #define EDF_PRIORITY_MAX 255
 
 /** 
@@ -25,8 +25,8 @@ typedef uint32_t Deadline_Control;
  * We can distinguish them by looking at the MSB of their priority. Priority diven
  * have 1 and deadline driven have 0.
  */
-#define EDF_HYBRID_MASK (1 << (EDF_BYTES_FOR_TIME*8 - 1)) //This is MSB
-
+#define EDF_HYBRID_MASK 0x80000000 //This is MSB
+//#define EDF_ABS_DEADLINE_MAX (EDF_HYBRID_MASK - 1)
 
 typedef enum node_color_struct { N_RED, N_BLACK } Node_Color;
 typedef Thread_Control EDF_Node;
index 4a7af6d3fee1222ff3cd9fb1c2d1162c5cbbd660..b9c461fe978f9a74ac76a95f21f2ad4d74f4ffbb 100644 (file)
@@ -6,6 +6,7 @@ extern "C" {
 #endif
 
 #include "edf_types.h"
+#include <stdint.h>
        
 // This struct will be embedded into the Thread_Control control 
 // as scheduler_info 
@@ -17,6 +18,7 @@ typedef struct RBT_node_struct {
        EDF_Node  *parent;
        Node_Color       color;
        EDF_Chain_Control *ready_chain;
+       uint8_t is_enqueued;
 } RBT_Node;
 
 void _RBT_Insert(EDF_Chain_Control *chain,EDF_Node *node);
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;
 }