diff --git a/src/system/kernel/scheduler.cpp b/src/system/kernel/scheduler.cpp index 827a2395f4..a2ac6357c0 100644 --- a/src/system/kernel/scheduler.cpp +++ b/src/system/kernel/scheduler.cpp @@ -219,17 +219,9 @@ scheduler_reschedule(void) if (nextThread->cpu && nextThread->cpu->cpu_num != oldThread->cpu->cpu_num) { - // ToDo: This thread is still running on another CPU. The - // thread just missed a semaphore, put itself into the notify - // queue but was not yet rescheduled. During this time frame - // release_sem_etc() was called for said semaphore and put the - // thread into the run queue to notify it. - // Therefore it is now _still_ running on one CPU and _already_ - // part of the run queue again. We have to skip this thread - // here because otherwise we would overwrite the thread->cpu - // pointer with the current CPU which would make both CPUs - // "think" they are the same one and kill off the scheduler - // logic in here as well as all calls to smp_get_current_cpu(). + panic("thread in run queue that's still running on another CPU!\n"); + // ToDo: remove this check completely when we're sure that this + // cannot happen anymore. prevThread = nextThread; nextThread = nextThread->queue_next; continue; diff --git a/src/system/kernel/sem.cpp b/src/system/kernel/sem.cpp index 8bb2b34bec..40a22f82e2 100644 --- a/src/system/kernel/sem.cpp +++ b/src/system/kernel/sem.cpp @@ -1065,7 +1065,6 @@ release_sem_etc(sem_id id, int32 count, uint32 flags) // release this thread thread = thread_dequeue(&sSems[slot].u.used.queue); thread_enqueue(thread, &releaseQueue); - thread->state = B_THREAD_READY; thread->sem.count = 0; } } else if (flags & B_RELEASE_IF_WAITING_ONLY) @@ -1091,7 +1090,12 @@ release_sem_etc(sem_id id, int32 count, uint32 flags) thread->next_priority = thread->priority >= B_FIRST_REAL_TIME_PRIORITY ? thread->priority : thread->priority + 1; #endif - scheduler_enqueue_in_run_queue(thread); + if (thread->state == B_THREAD_RUNNING) + thread->next_state = B_THREAD_READY; + else { + thread->state = B_THREAD_READY; + scheduler_enqueue_in_run_queue(thread); + } } if ((flags & B_DO_NOT_RESCHEDULE) == 0) scheduler_reschedule();