Fix the underlying problem that caused the issue of running threads being
enqueued into the run_queue again. Modified the workaround to a panic in the scheduler so we notice when something else does the same. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23731 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user