sched.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <string.h>
00014 #include <stdlib.h>
00015 #include <l4/env/errno.h>
00016 #include <l4/log/l4log.h>
00017 #include <l4/dm_mem/dm_mem.h>
00018 #include "sched.h"
00019
00020 int sched_cur_threads, sched_max_threads;
00021 sched_t **scheds;
00022 l4semaphore_t scheds_lock = L4SEMAPHORE_UNLOCKED;
00023
00024
00025
00026
00027
00028
00029 int sched_init(void){
00030 return (scheds = calloc(sizeof(sched_t*),
00031 sched_max_threads))!=0?0:-L4_ENOMEM;
00032 }
00033
00034
00035
00036
00037
00038
00039
00040
00041 int sched_index(int prio){
00042 int pos, min_pos, end_pos;
00043
00044 if(sched_cur_threads==0) return 0;
00045 if(prio>scheds[sched_cur_threads-1]->prio) return sched_cur_threads;
00046 end_pos = sched_cur_threads;
00047
00048 min_pos=0;
00049 pos=0;
00050 while(1){
00051 pos = (min_pos+end_pos)/2;
00052 if(pos==min_pos){
00053 if(scheds[pos]->prio < prio) return pos+1;
00054 return pos;
00055 }
00056 if(scheds[pos]->prio < prio){
00057 min_pos = pos;
00058 } else {
00059 end_pos = pos;
00060 }
00061 }
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 static int get_max_dp(int prio, sched_t *new_){
00079 int i, maxdp=0;
00080
00081 for(i=0; i<sched_cur_threads; i++){
00082
00083 if(scheds[i]->prio>=prio) break;
00084 if(is_dp(scheds[i]) && scheds[i]->wcet>maxdp)
00085 maxdp = scheds[i]->wcet;
00086 }
00087 if(new_ && is_dp(new_) && new_->prio<prio && new_->wcet>maxdp){
00088 maxdp = new_->wcet;
00089 }
00090 return maxdp;
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 int sched_response_time(sched_t *sched, int from, sched_t *new_){
00110 int r, r_j, pos;
00111
00112
00113
00114 r = sched->wcet + get_max_dp(sched->prio, new_);
00115 for(;;){
00116 r_j = sched->wcet + get_max_dp(sched->prio, new_);
00117 for(pos=from; pos<sched_cur_threads; pos++){
00118 if(scheds[pos]==sched) continue;
00119 if(!is_dp(scheds[pos])){
00120 r_j += ( ((r+scheds[pos]->period-1)/scheds[pos]->period)
00121 * scheds[pos]->wcet );
00122 } else {
00123
00124 }
00125 }
00126 if(new_ && !is_dp(new_)){
00127 r_j += ((r+new_->period-1)/new_->period) * new_->wcet;
00128 }
00129 if(r_j > (sched->deadline?sched->deadline:sched->period))
00130 return -1;
00131 if(r_j == r) return r_j;
00132
00133 r = r_j;
00134 }
00135 }
00136
00137
00138
00139 int sched_free(int pos){
00140 sched_t *sched;
00141
00142 if(pos>=sched_cur_threads) return -L4_EINVAL;
00143 sched = scheds[pos];
00144 sched_cur_threads--;
00145 memmove(scheds+pos, scheds+pos+1,
00146 sizeof(sched_t*)*(sched_cur_threads-pos));
00147 if(sched->watch) l4dm_mem_release(sched->watch);
00148 if(sched->watcher!=L4THREAD_INVALID_ID){
00149 l4thread_shutdown(sched->watcher);
00150 }
00151 if(sched->dl_hist) rt_mon_hist_free(sched->dl_hist);
00152 free((char*)sched->name);
00153 free(sched);
00154 return 0;
00155 }
00156
00157
00158
00159 int sched_prepare_free(int pos){
00160 sched_t *sched;
00161 l4_msgdope_t result;
00162
00163 if(pos>=sched_cur_threads) return -L4_EINVAL;
00164 sched = scheds[pos];
00165
00166 if(sched->watcher!=L4THREAD_INVALID_ID){
00167
00168 l4_ipc_send(l4thread_l4_id(sched->watcher), L4_IPC_SHORT_MSG, 0, 0,
00169 L4_IPC_NEVER, &result);
00170 l4semaphore_down(&sched->watcher_end_sem);
00171 }
00172 return 0;
00173 }
00174
00175 void lock_scheds(void){
00176 l4semaphore_down(&scheds_lock);
00177 }
00178
00179 void unlock_scheds(void){
00180 l4semaphore_up(&scheds_lock);
00181 }