async_scheduler.c

Go to the documentation of this file.
00001 
00009 #include <includes.h>
00010 
00011 #ifndef __VERSION_0_1__
00012 #warning RangerOS mismatch, expected v0.1. 
00013 #endif
00014 
00021 static const VOID_VOID_F * asched_schedule; 
00022 
00023 static int asched_divider;
00024 static int asched_div_counter;
00025 
00026 static volatile int asched_slot_start_index; 
00027 static int asched_saved_slot_start_index;
00028 static volatile int asched_next_task_index;
00029 
00030 static volatile long int asched_timestamp;
00031 
00032 static ASCHED_COMPLETION asched_completion;
00033 
00039 void asched_init(const VOID_VOID_F * sched, int tick_divider) { 
00040   asched_schedule = sched;
00041   asched_divider = tick_divider;
00042   asched_div_counter = 0;
00043   asched_slot_start_index = -1;
00044   asched_saved_slot_start_index = -1;
00045   asched_next_task_index = -1;
00046   
00047   asched_completion = ASCHED_DONE;
00048 }
00049 
00055 void asched_tick(void) {
00056   int search_idx;
00057   
00058   if(asched_div_counter >= (asched_divider - 1)){
00059     //1) check if all tasks have successfully completed from the previous iteration
00060     if(asched_completion != ASCHED_DONE){
00061       error_occurred(ERROR_ASCHED_DNF);
00062     } 
00063     
00064     //2) schedule next tasks
00065     if(asched_next_task_index >= 0){    
00066       search_idx = asched_next_task_index;
00067       while(asched_schedule[search_idx] != (VOID_VOID_F)NULL){//find end of current time slot in case of overrun
00068         search_idx++; 
00069       }
00070       search_idx++;//advance to first task of next slot
00071       //if we have reached the end of the schedule (double NULL), wrap to the beginning
00072       if(asched_schedule[search_idx] == (VOID_VOID_F)NULL){
00073         search_idx = 0; 
00074       }
00075     } else {
00076       search_idx = 0; //first run of the scheduler
00077     }
00078     asched_slot_start_index = search_idx;//schedule the beginning of the next time slot
00079     
00080     asched_completion = ASCHED_NOT_DONE;  
00081 
00082     //3) reset divider
00083     asched_div_counter = 0;
00084   } else {
00085     asched_div_counter++;
00086   }
00087   
00088 }
00089 
00094 void asched_set_timestamp(int timestamp){
00095   asched_timestamp = timestamp;
00096 }
00097 
00102 void asched_run(void) {
00103   //execute this timestep
00104   VOID_VOID_F next_task;
00105 
00106   //we do not want things to run before asched_tick has been called for the first time.
00107   if(asched_slot_start_index >= 0) {
00108     while(1){
00109       if((asched_slot_start_index != asched_saved_slot_start_index)){   //check if rescheduling has occured,
00110         asched_saved_slot_start_index = asched_slot_start_index;
00111         asched_next_task_index = asched_slot_start_index;
00112       }
00113       next_task = asched_schedule[asched_next_task_index];
00114       if(next_task != (VOID_VOID_F)NULL) {
00115         next_task();//execute next task
00116         asched_next_task_index++;
00117       } else {//bah, race conditions!!! ???
00118         asched_completion = ASCHED_DONE;
00119         break;
00120       }
00121     }
00122   }
00123 }
00124 
00125 
00131 int asched_get_timestamp(void){
00132   return asched_timestamp;
00133 }
00134 
Generated on Tue Jun 29 16:36:14 2010 by  doxygen 1.6.3