diff --git a/kernel/tasks.c b/kernel/tasks.c index 206823e7..3ed1bdd3 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -1155,17 +1155,16 @@ void load_balancing(void) uint32_t prio; task_t* task; - spinlock_irqsave_lock(&runqueues[core_id].lock); for(i=0; (i> (FSHIFT-1)) > (runqueues[core_id].load[0] >> (FSHIFT-1))) { //kprintf("Try to steal a task from core %u (load %u) to %u (load %u)\n", i, runqueues[i].load[0], core_id, runqueues[core_id].load[0]); //kprintf("Task on core %u: %u, core %u, %u\n", i, runqueues[i].nr_tasks, core_id, runqueues[i].nr_tasks); + spinlock_irqsave_lock(&runqueues[i].lock); prio = lsb(runqueues[i].prio_bitmap); if (prio < sizeof(size_t)*8) { // steal a ready task @@ -1180,7 +1179,12 @@ void load_balancing(void) runqueues[i].prio_bitmap &= ~(1 << prio); } else runqueues[i].queue[prio-1].last = task->prev; + // update task counters + runqueues[i].nr_tasks--; + spinlock_irqsave_unlock(&runqueues[i].lock); + // add task at the end of queue core_id + spinlock_irqsave_lock(&runqueues[core_id].lock); if (!runqueues[core_id].queue[prio-1].last) { runqueues[core_id].queue[prio-1].first = runqueues[core_id].queue[prio-1].last = task; task->next = task->prev = NULL; @@ -1194,15 +1198,20 @@ void load_balancing(void) // update task counters runqueues[core_id].nr_tasks++; - runqueues[i].nr_tasks--; runqueues[core_id].balance_counter = TIMER_FREQ/2; - } /*else { + spinlock_irqsave_unlock(&runqueues[core_id].lock); + } else { +#if 1 + spinlock_irqsave_unlock(&runqueues[i].lock); +#else task_t* tmp; // steal a blocked task task = runqueues[i].timers.first; - if (!task) // Ups, found no valid task to steal + if (!task) { // Ups, found no valid task to steal + spinlock_irqsave_unlock(&runqueues[i].lock); goto no_task_found; + } kprintf("Core %u steals the blocked task %d from %u with prio %u\n", core_id, task->id, i, task->prio); @@ -1212,6 +1221,10 @@ void load_balancing(void) else runqueues[i].timers.first = runqueues[i].timers.first->next; + spinlock_irqsave_unlock(&runqueues[i].lock); + + spinlock_irqsave_lock(&runqueues[core_id].lock); + // add timer to queue core_id tmp = runqueues[core_id].timers.first; while(tmp && (task->timeout >= tmp->timeout)) @@ -1240,16 +1253,16 @@ void load_balancing(void) // update task counters runqueues[core_id].balance_counter = TIMER_FREQ/2; - }*/ + + spinlock_irqsave_lock(&runqueues[core_id].lock); +#endif + } } //no_task_found: - spinlock_irqsave_unlock(&runqueues[i].lock); } if (runqueues[core_id].balance_counter <= 0) runqueues[core_id].balance_counter = TIMER_FREQ/2; - - spinlock_irqsave_unlock(&runqueues[core_id].lock); #endif } #endif