]> rtime.felk.cvut.cz Git - rtems-pluggable-edf.git/commitdiff
EDF pluggable scheduler running!
authorPetr Benes <benesp16@fel.cvut.cz>
Tue, 29 Mar 2011 17:30:22 +0000 (19:30 +0200)
committerPetr Benes <benesp16@fel.cvut.cz>
Tue, 29 Mar 2011 17:30:22 +0000 (19:30 +0200)
The period/deadline is taken over from the priority number.
There is a better API for EDF required.

A minor hack involving the idle task has been made in order to take into
account it's lowest priority. This should be somehow extended for all
eventual tasks having no specific deadline.

rtems-omk-template/appfoo/init.c
rtems-omk-template/appfoo/scheduler_edf.c
rtems-omk-template/appfoo/system.h
rtems-omk-template/appfoo/task_2.c

index ed6ab84b61ec58efeabe1288350da83638a546be..76cbc2e87768f5878436e383f921cb3d95f6a613 100644 (file)
@@ -79,10 +79,10 @@ rtems_task Init(
   printf( "Starting application " SW_VER_ID " v "
           BUILD_VERSION_STRING(SW_VER_MAJOR,SW_VER_MINOR,SW_VER_PATCH)
          "\n" );
-
+  
+// Task 1 ==============================================  
   Task_1_name = rtems_build_name( 'T', 'S', 'K', '1' );
-  Task_2_name = rtems_build_name( 'T', 'S', 'K', '2' );
-    
+
   status = rtems_task_create(
      Task_1_name,
      TASK_1_PRIORITY,
@@ -91,11 +91,14 @@ rtems_task Init(
      RTEMS_DEFAULT_ATTRIBUTES,
      &Task_1_id
   );
-  
-  
   check_rtems_status(status, 0, "rtems_task_create of Task_1");
+  status = rtems_task_start( Task_1_id, Task_1, 0 );
+  check_rtems_status(status, 0, "rtems_task_start of Task_1\n");
 
   
+// Task 2 ==============================================  
+  Task_2_name = rtems_build_name( 'T', 'S', 'K', '2' );
+  
   status = rtems_task_create(
      Task_2_name,
      TASK_2_PRIORITY,
@@ -107,13 +110,12 @@ rtems_task Init(
   
   check_rtems_status(status, 0, "rtems_task_create of Task_2");
 
-  status = rtems_task_start( Task_1_id, Task_1, 0 );
-  check_rtems_status(status, 0, "rtems_task_start of Task_1\n");
 
   status = rtems_task_start( Task_2_id, Task_2, 0 );
   check_rtems_status(status, 0, "rtems_task_start of Task_2\n");
 
-
+//  ====================================================
+  
   rtems_shell_init("SHLL",RTEMS_MINIMUM_STACK_SIZE+0x1000,
               SHELL_TASK_PRIORITY,"/dev/console",1,0, NULL);
 
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);
 }
 
index 4bff97ec24bd97a3e3c2022116c9f1cb98d78e92..bccc673bfb04f2fb9d822c18d96136ef634981b8 100644 (file)
@@ -90,13 +90,14 @@ rtems_task Init(
 #define CONFIGURE_SCHEDULER_USER_ENTRY_POINTS 
 // EDF
 #include "scheduler_edf.h"
+#include "rbtree.h"
 #define SCHEDULER_ENTRY_POINTS SCHEDULER_EDF_ENTRY_POINTS
-// Priority
-//#include "scheduler_priority.h"
-//#define SCHEDULER_ENTRY_POINTS SCHEDULER_PRIORITY_ENTRY_POINTS
+       // Priority
+       //#include "scheduler_priority.h"
+       //#define SCHEDULER_ENTRY_POINTS SCHEDULER_PRIORITY_ENTRY_POINTS
 
-#define CONFIGURE_MEMORY_FOR_SCHEDULER (1024)
-#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (256)
+#define CONFIGURE_MEMORY_FOR_SCHEDULER (_Configure_From_workspace(sizeof(EDF_Chain_Control)))
+#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (_Configure_From_workspace(sizeof(RBT_Node)))
 
 
 
index 4101717ef8af04fe6da830b1ed5ba07d6725febf..160ff6c9e50147542590e1145b3284f33bc0e1d4 100644 (file)
@@ -23,7 +23,7 @@ rtems_task Task_2(
     for (i=0; i<10000; i++) {
       s = i + i;
     }
-    status = rtems_task_wake_after( TICKS_PER_SECOND*2 );
+    status = rtems_task_wake_after( TICKS_PER_SECOND*1.5 );
     check_rtems_status( status, 0, "rtems_task_wake_after" );
   }
 }