23 #if defined (POK_NEEDS_SCHED) || defined (POK_NEEDS_THREADS)
32 #ifdef POK_NEEDS_PARTITIONS
36 #ifdef POK_NEEDS_MIDDLEWARE
46 extern pok_thread_t pok_threads[];
48 #ifdef POK_NEEDS_PARTITIONS
49 extern pok_partition_t pok_partitions[];
56 void pok_sched_partition_switch();
59 #if defined (POK_NEEDS_PORTS_SAMPLING) || defined (POK_NEEDS_PORTS_QUEUEING)
60 void pok_port_flushall (
void);
63 uint64_t pok_sched_slots[POK_CONFIG_SCHEDULING_NBSLOTS]
64 = (
uint64_t[]) POK_CONFIG_SCHEDULING_SLOTS;
65 uint8_t pok_sched_slots_allocation[POK_CONFIG_SCHEDULING_NBSLOTS]
66 = (
uint8_t[]) POK_CONFIG_SCHEDULING_SLOTS_ALLOCATION;
72 uint8_t pok_sched_current_slot = 0;
73 uint32_t current_thread = KERNEL_THREAD;
75 void pok_sched_thread_switch (
void);
81 void pok_sched_init (
void)
83 #ifdef POK_NEEDS_PARTITIONS
84 #if defined (POK_NEEDS_ERROR_HANDLING) || defined (POK_NEEDS_DEBUG)
94 for (slot = 0 ; slot < POK_CONFIG_SCHEDULING_NBSLOTS ; slot++)
96 total_time = total_time + pok_sched_slots[slot];
99 if (total_time != POK_CONFIG_SCHEDULING_MAJOR_FRAME)
101 #ifdef POK_NEEDS_DEBUG
102 printf (
"Major frame is not compliant with all time slots\n");
104 #ifdef POK_NEEDS_ERROR_HANDLING
105 pok_kernel_error (POK_ERROR_KIND_KERNEL_CONFIG);
111 pok_sched_current_slot = 0;
112 pok_sched_next_major_frame = POK_CONFIG_SCHEDULING_MAJOR_FRAME;
113 pok_sched_next_deadline = pok_sched_slots[0];
114 pok_current_partition = pok_sched_slots_allocation[0];
131 #ifdef POK_NEEDS_PARTITIONS
132 pok_partition_t* pok_elect_partition()
134 # if POK_CONFIG_NB_PARTITIONS > 1
137 if (pok_sched_next_deadline <= now)
140 # if defined (POK_NEEDS_PORTS_SAMPLING) || defined (POK_NEEDS_PORTS_QUEUEING)
141 if (pok_sched_next_major_frame <= now)
143 pok_sched_next_major_frame = pok_sched_next_major_frame + POK_CONFIG_SCHEDULING_MAJOR_FRAME;
148 pok_sched_current_slot = (pok_sched_current_slot + 1) % POK_CONFIG_SCHEDULING_NBSLOTS;
149 pok_sched_next_deadline = pok_sched_next_deadline + pok_sched_slots[pok_sched_current_slot];
159 pok_partitions[pok_current_partition].prev_current_thread = prev_current_thread;
160 pok_partitions[pok_current_partition].current_thread = POK_SCHED_CURRENT_THREAD;
162 pok_current_partition = pok_sched_slots_allocation[pok_sched_current_slot];
164 prev_current_thread = pok_partitions[pok_current_partition].prev_current_thread;
165 current_thread = pok_partitions[pok_current_partition].current_thread;
167 #ifdef POK_NEEDS_SCHED_HFPPS
168 if (pok_partitions[pok_current_partition].payback > 0)
171 pok_sched_next_deadline -= pok_partitions[pok_current_partition].payback;
172 pok_partitions[pok_current_partition].payback = 0;
179 return (&(pok_partitions[pok_current_partition]));
183 #ifdef POK_NEEDS_PARTITIONS
184 uint32_t pok_elect_thread(pok_partition_t* current_partition)
196 pok_thread_t* thread;
197 for (i = 0; i < pok_partitions[pok_current_partition].nthreads; i++)
199 thread = &(pok_threads[current_partition->thread_index_low + i]);
201 #if defined (POK_NEEDS_LOCKOBJECTS) || defined (POK_NEEDS_PORTS_QUEUEING) || defined (POK_NEEDS_PORTS_SAMPLING)
202 if ((thread->state == POK_STATE_WAITING) && (thread->wakeup_time <= now))
204 thread->state = POK_STATE_RUNNABLE;
208 if ((thread->state == POK_STATE_WAIT_NEXT_ACTIVATION) && (thread->next_activation <= now))
210 thread->state = POK_STATE_RUNNABLE;
211 thread->remaining_time_capacity = thread->time_capacity;
212 thread->next_activation = thread->period + POK_GETTICK();
220 switch (current_partition->mode)
222 case POK_PARTITION_MODE_INIT_COLD:
223 case POK_PARTITION_MODE_INIT_WARM:
224 #ifdef POK_NEEDS_ERROR_HANDLING
225 if ((current_partition->thread_error != 0) &&
226 (pok_threads[current_partition->thread_error].state != POK_STATE_STOPPED))
228 elected = current_partition->thread_error;
232 elected = current_partition->thread_main;
236 elected = current_partition->thread_main;
239 case POK_PARTITION_MODE_NORMAL:
240 #ifdef POK_NEEDS_ERROR_HANDLING
241 if ((POK_SCHED_CURRENT_THREAD == POK_CURRENT_PARTITION.thread_error) &&
242 (POK_CURRENT_THREAD.state == POK_STATE_RUNNABLE))
244 elected = POK_CURRENT_PARTITION.thread_error;
245 POK_CURRENT_PARTITION.current_thread = elected;
249 if ( (POK_SCHED_CURRENT_THREAD != IDLE_THREAD) &&
250 (POK_SCHED_CURRENT_THREAD != POK_CURRENT_PARTITION.thread_main)
251 #ifdef POK_NEEDS_ERROR_HANDLING
252 && (POK_SCHED_CURRENT_THREAD != POK_CURRENT_PARTITION.thread_error)
256 if (POK_CURRENT_THREAD.remaining_time_capacity > 0)
258 POK_CURRENT_THREAD.remaining_time_capacity = POK_CURRENT_THREAD.remaining_time_capacity - 1;
262 POK_CURRENT_THREAD.state = POK_STATE_WAIT_NEXT_ACTIVATION;
265 elected = POK_CURRENT_PARTITION.sched_func (current_partition->thread_index_low,
266 current_partition->thread_index_high);
267 #ifdef POK_NEEDS_INSTRUMENTATION
268 if ( (elected != IDLE_THREAD) && (elected != POK_CURRENT_PARTITION.thread_main))
270 pok_instrumentation_running_task (elected);
273 POK_CURRENT_PARTITION.current_thread = elected;
278 elected = IDLE_THREAD;
282 #ifdef POK_NEEDS_SCHED_HFPPS
283 if (pok_threads[elected].payback > 0)
285 pok_threads[elected].remaining_time_capacity -= pok_threads[elected].payback;
286 pok_threads[elected].payback = 0;
291 pok_threads[elected].end_time = now + pok_threads[elected].remaining_time_capacity;
297 #ifdef POK_NEEDS_PARTITIONS
302 #ifdef POK_NEEDS_SCHED_HFPPS
304 elected_thread = current_thread;
307 if (pok_threads[elected_thread].end_time <= now && pok_threads[elected_thread].remaining_time_capacity > 0)
310 pok_threads[elected_thread].payback = pok_threads[elected_thread].remaining_time_capacity;
311 pok_partitions[pok_current_partition].payback = pok_threads[elected_thread].remaining_time_capacity;
313 pok_sched_next_deadline += pok_threads[elected_thread].remaining_time_capacity;
318 pok_partition_t* elected_partition = pok_elect_partition();
319 elected_thread = pok_elect_thread(elected_partition);
322 pok_sched_context_switch(elected_thread);
325 void pok_sched_thread_switch ()
334 if ((pok_threads[i].state == POK_STATE_WAITING) &&
335 (pok_threads[i].wakeup_time <= now))
337 pok_threads[i].state = POK_STATE_RUNNABLE;
346 pok_sched_context_switch(elected);
354 void pok_sched_context_switch (
const uint32_t elected_id)
359 if (POK_SCHED_CURRENT_THREAD == elected_id)
363 current_sp = &POK_CURRENT_THREAD.sp;
364 new_sp = pok_threads[elected_id].sp;
371 pok_threads[elected_id].partition);
373 current_thread = elected_id;
378 #ifdef POK_NEEDS_SCHED_RMS
382 #ifdef POK_NEEDS_DEBUG
386 if (POK_SCHED_CURRENT_THREAD == IDLE_THREAD)
388 res = prev_current_thread;
392 res = POK_SCHED_CURRENT_THREAD;
395 #ifdef POK_NEEDS_DEBUG
404 if (res >= index_high)
409 while ((res != index_low) &&
410 (pok_threads[res].state != POK_STATE_RUNNABLE));
412 if ((res == index_low) && (pok_threads[res].state != POK_STATE_RUNNABLE))
415 if (POK_SCHED_CURRENT_THREAD != IDLE_THREAD)
417 prev_current_thread = POK_SCHED_CURRENT_THREAD;
421 #ifdef POK_NEEDS_DEBUG
422 if ( res!= IDLE_THREAD)
424 printf(
"--- scheduling thread: %d {%d} --- ", res,
425 pok_threads[res].period);
427 while ( from <= index_high )
429 if ( pok_threads[from].state==POK_STATE_RUNNABLE )
431 printf(
" %d {%d} ,",from,pok_threads[from].period);
435 printf(
" are runnable\n");
449 if (POK_SCHED_CURRENT_THREAD == IDLE_THREAD)
451 res = prev_current_thread;
455 res = POK_SCHED_CURRENT_THREAD;
460 if ((POK_CURRENT_THREAD.remaining_time_capacity > 0) && (POK_CURRENT_THREAD.state == POK_STATE_RUNNABLE))
462 return POK_SCHED_CURRENT_THREAD;
468 if (res > index_high)
473 while ((res != from) && (pok_threads[res].state != POK_STATE_RUNNABLE));
475 if ((res == from) && (pok_threads[res].state != POK_STATE_RUNNABLE))
478 if (POK_SCHED_CURRENT_THREAD != IDLE_THREAD)
480 prev_current_thread = POK_SCHED_CURRENT_THREAD;
487 #if defined (POK_NEEDS_LOCKOBJECTS) || defined (POK_NEEDS_PORTS_QUEUEING) || defined (POK_NEEDS_PORTS_SAMPLING)
488 void pok_sched_unlock_thread (
const uint32_t thread_id)
490 pok_threads[thread_id].state = POK_STATE_RUNNABLE;
494 #if defined (POK_NEEDS_LOCKOBJECTS) || defined (POK_NEEDS_PORTS_QUEUEING) || defined (POK_NEEDS_PORTS_SAMPLING)
495 void pok_sched_lock_current_thread (
void)
497 pok_threads[current_thread].state = POK_STATE_LOCK;
500 void pok_sched_lock_current_thread_timed (
const uint64_t time)
502 pok_threads[current_thread].state = POK_STATE_WAITING;
503 pok_threads[current_thread].wakeup_time = time;
507 #ifdef POK_NEEDS_SCHED_STOP_SELF
508 void pok_sched_stop_self (
void)
510 POK_CURRENT_THREAD.state = POK_STATE_STOPPED;
515 void pok_sched_stop_thread (
const uint32_t tid)
517 pok_threads[tid].state = POK_STATE_STOPPED;
520 #ifdef POK_NEEDS_DEPRECIATED
521 void pok_sched_lock_thread (
const uint32_t thread_id)
523 pok_threads[thread_id].state = POK_STATE_LOCK;
529 POK_CURRENT_THREAD.state = POK_STATE_WAIT_NEXT_ACTIVATION;
530 POK_CURRENT_THREAD.remaining_time_capacity = 0;
535 #if defined (POK_NEEDS_PARTITIONS) && defined (POK_NEEDS_ERROR_HANDLING)
536 void pok_sched_activate_error_thread (
void)
538 uint32_t error_thread = pok_partitions[pok_current_partition].thread_error;
539 if (error_thread != 0)
541 pok_threads[error_thread].remaining_time_capacity = 1000;
542 pok_threads[error_thread].period = 100;
543 pok_threads[error_thread].next_activation= 0;
545 pok_threads[error_thread].state = POK_STATE_RUNNABLE;
546 pok_sched_context_switch (error_thread);
551 #ifdef POK_NEEDS_PARTITIONS
555 #if defined (POK_NEEDS_ERROR_HANDLING)
556 if (pok_partitions[pok_current_partition].thread_error == 0)
559 if (KERNEL_THREAD == POK_SCHED_CURRENT_THREAD
560 || IDLE_THREAD == POK_SCHED_CURRENT_THREAD)
564 *thread_id=POK_SCHED_CURRENT_THREAD;