]> rtime.felk.cvut.cz Git - rtems-pluggable-edf.git/blobdiff - rtems-omk-template/appfoo/scheduler_edf.c
EDF pluggable scheduler running!
[rtems-pluggable-edf.git] / rtems-omk-template / appfoo / scheduler_edf.c
index 2cbd8b3419eaaf1e5f70d4269917087829015770..90ce44d96882c3288ed74383df62b09f3fc50fcb 100644 (file)
@@ -5,9 +5,10 @@
 #include <rtems/score/isr.h>
 #include <rtems/score/watchdog.h>
 #include <rtems/score/wkspace.h>
+#include <rtems/score/percpu.h>
 
 /* let the scheduler talk */
-#define SCHED_VERBOSE
+//#define SCHED_VERBOSE
 
 
 void _Scheduler_edf_Initialize(void) {
@@ -25,7 +26,15 @@ void _Scheduler_edf_Block(  Thread_Control    *the_thread ) {
        #ifdef SCHED_VERBOSE
        printf("Sched: Block");
        #endif
-       _Scheduler_edf_Extract(the_thread);
+       _Scheduler_edf_Extract(the_thread);
+       
+       /* TODO: flash critical section? */
+
+       if ( _Thread_Is_heir( the_thread ) )
+               _Scheduler_edf_Schedule();
+
+       if ( _Thread_Is_executing( the_thread ) )
+               _Thread_Dispatch_necessary = true;      
 }
 
 void _Scheduler_edf_Schedule(void) {
@@ -33,7 +42,7 @@ void _Scheduler_edf_Schedule(void) {
        printf("Sched: Schedule");
        #endif
        // set the heir
-       _Thread_Heir = (Thread_Control *) _Thread_Ready_EDF_chain.first;
+       _Thread_Heir = (Thread_Control *) _Thread_Ready_EDF_chain.first;
 }
 
 void * _Scheduler_edf_Allocate(  Thread_Control      *the_thread) {
@@ -44,10 +53,10 @@ 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 = ABS_DEADLINE_MAXIMUM - _Watchdog_Ticks_since_boot-2;
-       the_thread->is_preemptible = TRUE;
-       the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
-       the_thread->budget_callout = NULL;
+       //the_thread->real_priority = ABS_DEADLINE_MAXIMUM - _Watchdog_Ticks_since_boot-2;
+       //the_thread->is_preemptible = TRUE;
+       //the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
+       //the_thread->budget_callout = NULL;
        
        schinfo = (RBT_Node *)(the_thread->scheduler_info);
        schinfo->rel_deadline = the_thread->real_priority;
@@ -56,7 +65,7 @@ void * _Scheduler_edf_Allocate(  Thread_Control      *the_thread) {
        schinfo->right = NULL;
        schinfo->parent = NULL;
        schinfo->ready_chain = &_Thread_Ready_EDF_chain;
-
+       
        return sched;
 }
 
@@ -73,16 +82,35 @@ void _Scheduler_edf_Update(  Thread_Control      *the_thread) {
        #endif
        // after a priority changes, just extract and insert again
        //in case it is in the tree
-       EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
-       _RBT_Extract(chain, the_thread); 
-       _RBT_Insert(chain, the_thread); // preserve the abs_deadline
+//     EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
+//     _RBT_Extract(chain, the_thread); 
+//     _RBT_Insert(chain, the_thread); // preserve the abs_deadline
 }
 
 void _Scheduler_edf_Unblock(  Thread_Control    *the_thread ) {
        #ifdef SCHED_VERBOSE
        printf("Sched: Unblock");
        #endif
-       _Scheduler_edf_Enqueue(the_thread);
+       _Scheduler_edf_Enqueue(the_thread);
+       /* TODO: flash critical section? */
+
+       /*
+       *  If the thread that was unblocked is more important than the heir,
+       *  then we have a new heir.  This may or may not result in a
+       *  context switch.
+       *
+       *  Normal case:
+       *    If the current thread is preemptible, then we need to do
+       *    a context switch.
+       *  Pseudo-ISR case:
+       *    Even if the thread isn't preemptible, if the new heir is
+       *    a pseudo-ISR system task, we need to do a context switch.
+       */
+       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;      
+       }
 }
 
 void _Scheduler_edf_Yield( void ) {
@@ -113,7 +141,6 @@ void _Scheduler_edf_Yield( void ) {
                _Thread_Dispatch_necessary = TRUE;
 
        _ISR_Enable( level );
-       // --------------------------------
        
 }
 
@@ -123,8 +150,12 @@ void _Scheduler_edf_Enqueue(  Thread_Control    *the_thread) {
        #endif
        RBT_Node *node = (RBT_Node*)the_thread->scheduler_info;
        EDF_Chain_Control *chain = node->ready_chain;
-       node->abs_deadline = _Watchdog_Ticks_since_boot + node->rel_deadline;
+       if (node->rel_deadline == 255) //hack for idle task
+               node->abs_deadline = ABS_DEADLINE_MAXIMUM;      
+       else
+               node->abs_deadline = _Watchdog_Ticks_since_boot + node->rel_deadline;
        _RBT_Insert(chain,the_thread);
+
 }
 
 void _Scheduler_edf_Enqueue_first(  Thread_Control    *the_thread) {
@@ -132,15 +163,14 @@ void _Scheduler_edf_Enqueue_first(  Thread_Control    *the_thread) {
        printf("Sched: Enqueue_first");
        #endif
        // FIXME: force first position
-       EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
-       _RBT_Insert(chain,the_thread);
+       _Scheduler_edf_Enqueue(the_thread);
 }
 
 void _Scheduler_edf_Extract(  Thread_Control     *the_thread) {
        #ifdef SCHED_VERBOSE
        printf("Sched: Extract");
        #endif
-       EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
-       _RBT_Extract(chain,the_thread);
+       EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
+       _RBT_Extract(chain,the_thread);
 }