@@ -17,7 +17,10 @@ bool timefreeze = false;
1717uint32_t timemillis ;
1818
1919uint8_t current_queue = 0 ;
20- uint8_t timeQuantumCounter = 0 ;
20+ uint8_t timeQuantumCounters [QUEUE_NUMBER ] = {0 };
21+
22+ // Prematurely preempted threads
23+ static thread_t * early_preempted_threads [QUEUE_NUMBER ] = {NULL };
2124
2225task_t * kernel_task ;
2326
@@ -410,20 +413,35 @@ uint32_t task_switch(uint32_t esp) {
410413 old_thread -> esp = esp ; // save esp
411414
412415 if (old_thread -> parent != doNothing_task ) {
413- ++ timeQuantumCounter ;
416+ timeQuantumCounters [ current_queue ] ++ ;
414417
415418 if (timemillis < old_thread -> timeout ) {
416419 // Task was faster than the time quantum
417420 old_thread -> nice = (4 * old_thread -> nice ) / 5 + (old_thread -> timeout - timemillis ) / 5 ;
418- } else if (timeQuantumCounter > current_queue ) {
421+ timeQuantumCounters [current_queue ] = 0 ;
422+ } else if (timeQuantumCounters [current_queue ] > current_queue ) {
419423 // Task took too long, demoting it to a lower priority queue
420424 queue_enqueue (& (queues [MIN (current_queue + 1 , QUEUE_NUMBER - 1 )]), old_thread );
421425 old_thread -> nice = 0 ;
426+ timeQuantumCounters [current_queue ] = 0 ;
422427 } else {
423- // Task still has some time left to run
424- ODA .ts_flag = true;
425- timefreeze = false;
426- return old_thread -> esp ;
428+ bool higherPriorityAppeared = false;
429+
430+ for (uint8_t i = 0 ; i < current_queue ; ++ i ) {
431+ if (!queue_isEmpty (& (queues [i ]))) {
432+ // Another task in a higher priority queue has appeared
433+ early_preempted_threads [current_queue ] = old_thread ;
434+ higherPriorityAppeared = true;
435+ break ;
436+ }
437+ }
438+
439+ if (!higherPriorityAppeared ) {
440+ // Task still has some time left to run
441+ ODA .ts_flag = true;
442+ timefreeze = false;
443+ return old_thread -> esp ;
444+ }
427445 }
428446
429447 uint64_t cpuCycles = rdtsc () - old_thread -> parent -> last_active ;
@@ -433,12 +451,17 @@ uint32_t task_switch(uint32_t esp) {
433451 }
434452 }
435453
436- timeQuantumCounter = 0 ;
437-
438454 // Find the next task to run
439455 for (uint8_t i = 0 ; i < QUEUE_NUMBER ; ++ i ) {
440456 queue_t * queue = & (queues [i ]);
441457
458+ if (early_preempted_threads [i ] != NULL ) {
459+ current_thread = early_preempted_threads [i ];
460+ early_preempted_threads [i ] = NULL ;
461+ current_queue = i ;
462+ goto found_new_task ;
463+ }
464+
442465 if (!queue_isEmpty (queue )) {
443466 current_thread = queue_dequeue (queue );
444467 current_queue = i ;
0 commit comments