diff --git a/headers/private/kernel/kscheduler.h b/headers/private/kernel/kscheduler.h index cbad85d9e2..16316e87c1 100644 --- a/headers/private/kernel/kscheduler.h +++ b/headers/private/kernel/kscheduler.h @@ -43,7 +43,7 @@ void scheduler_reschedule_ici(void); indefinitely, the function will eventually return. The caller must hold the current thread \c scheduler_lock. */ -void scheduler_reschedule(void); +void scheduler_reschedule(int32 next_state); /*! Sets the given thread's priority. The thread may be running or may be in the ready-to-run queue. @@ -112,7 +112,7 @@ static inline void scheduler_reschedule_if_necessary_locked() { if (gCPU[smp_get_current_cpu()].invoke_scheduler) - scheduler_reschedule(); + scheduler_reschedule(B_THREAD_READY); } diff --git a/headers/private/kernel/thread.h b/headers/private/kernel/thread.h index a5e44d2b42..96d80ba912 100644 --- a/headers/private/kernel/thread.h +++ b/headers/private/kernel/thread.h @@ -211,7 +211,7 @@ thread_is_interrupted(Thread* thread, uint32 flags) static inline bool thread_is_blocked(Thread* thread) { - return thread->wait.status == 1; + return atomic_get(&thread->wait.status) == 1; } diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 6212deb48d..2a7051bc3b 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -424,7 +424,6 @@ struct Thread : TeamThreadIteratorEntry, KernelReferenceable, int32 priority; // protected by scheduler lock int32 io_priority; // protected by fLock int32 state; // protected by scheduler lock - int32 next_state; // protected by scheduler lock struct cpu_ent *cpu; // protected by scheduler lock struct cpu_ent *previous_cpu; // protected by scheduler lock int32 pinned_to_cpu; // only accessed by this thread or in the diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp index abcaf5fa08..41176d850f 100644 --- a/src/system/kernel/arch/x86/arch_int.cpp +++ b/src/system/kernel/arch/x86/arch_int.cpp @@ -232,7 +232,7 @@ x86_hardware_interrupt(struct iframe* frame) cpu_status state = disable_interrupts(); if (thread->cpu->invoke_scheduler) { SpinLocker schedulerLocker(thread->scheduler_lock); - scheduler_reschedule(); + scheduler_reschedule(B_THREAD_READY); schedulerLocker.Unlock(); restore_interrupts(state); } else if (thread->post_interrupt_callback != NULL) { diff --git a/src/system/kernel/image.cpp b/src/system/kernel/image.cpp index 55ac115dff..c948b69f86 100644 --- a/src/system/kernel/image.cpp +++ b/src/system/kernel/image.cpp @@ -383,8 +383,7 @@ notify_loading_app(status_t result, bool suspend) Thread* thread = thread_get_current_thread(); InterruptsSpinLocker schedulerLocker(thread->scheduler_lock); - thread->next_state = B_THREAD_SUSPENDED; - scheduler_reschedule(); + scheduler_reschedule(B_THREAD_SUSPENDED); } } } diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 6fbe308f13..109c2821b2 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -620,7 +620,7 @@ enqueue(Thread* thread, bool newOne) { ASSERT(thread != NULL); - thread->state = thread->next_state = B_THREAD_READY; + thread->state = B_THREAD_READY; compute_thread_load(thread); @@ -1148,7 +1148,7 @@ update_thread_times(Thread* oldThread, Thread* nextThread) static void -reschedule(void) +reschedule(int32 nextState) { ASSERT(!are_interrupts_enabled()); @@ -1162,7 +1162,7 @@ reschedule(void) TRACE("reschedule(): cpu %ld, current thread = %ld\n", thisCPU, oldThread->id); - oldThread->state = oldThread->next_state; + oldThread->state = nextState; scheduler_thread_data* schedulerOldThreadData = oldThread->scheduler_data; // return time spent in interrupts @@ -1172,7 +1172,7 @@ reschedule(void) bool enqueueOldThread = false; bool putOldThreadAtBack = false; - switch (oldThread->next_state) { + switch (nextState) { case B_THREAD_RUNNING: case B_THREAD_READY: enqueueOldThread = true; @@ -1197,7 +1197,7 @@ reschedule(void) increase_penalty(oldThread); thread_goes_away(oldThread); TRACE("not enqueueing thread %ld into run queue next_state = %ld\n", - oldThread->id, oldThread->next_state); + oldThread->id, nextState); break; } @@ -1247,7 +1247,6 @@ reschedule(void) update_cpu_priority(thisCPU, get_effective_priority(nextThread)); nextThread->state = B_THREAD_RUNNING; - nextThread->next_state = B_THREAD_READY; ASSERT(nextThread->scheduler_data->previous_core == thisCore); @@ -1291,16 +1290,16 @@ reschedule(void) Note: expects thread spinlock to be held */ void -scheduler_reschedule(void) +scheduler_reschedule(int32 nextState) { if (!sSchedulerEnabled) { Thread* thread = thread_get_current_thread(); - if (thread != NULL && thread->next_state != B_THREAD_READY) + if (thread != NULL && nextState != B_THREAD_READY) panic("scheduler_reschedule_no_op() called in non-ready thread"); return; } - reschedule(); + reschedule(nextState); } @@ -1346,7 +1345,7 @@ scheduler_start(void) { InterruptsSpinLocker _(thread_get_current_thread()->scheduler_lock); - reschedule(); + reschedule(B_THREAD_READY); } diff --git a/src/system/kernel/signal.cpp b/src/system/kernel/signal.cpp index 5377903308..34af28a51f 100644 --- a/src/system/kernel/signal.cpp +++ b/src/system/kernel/signal.cpp @@ -1129,8 +1129,7 @@ handle_signals(Thread* thread) if (!resume) { InterruptsSpinLocker _(thread->scheduler_lock); - thread->next_state = B_THREAD_SUSPENDED; - scheduler_reschedule(); + scheduler_reschedule(B_THREAD_SUSPENDED); } continue; diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 175645a15c..dde114ed77 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -1811,8 +1811,7 @@ load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount, Thread* thread = thread_get_current_thread(); InterruptsSpinLocker schedulerLocker(thread->scheduler_lock); - thread->next_state = B_THREAD_SUSPENDED; - scheduler_reschedule(); + scheduler_reschedule(B_THREAD_SUSPENDED); } if (loadingInfo.result < B_OK) diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 141486709f..fc6cbe3842 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -892,7 +892,6 @@ thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel) thread->priority = attributes.priority == -1 ? B_NORMAL_PRIORITY : attributes.priority; thread->state = B_THREAD_SUSPENDED; - thread->next_state = B_THREAD_SUSPENDED; thread->sig_block_mask = attributes.signal_mask; @@ -1501,7 +1500,9 @@ make_thread_suspended(int argc, char **argv) if (thread->id != id) continue; - thread->next_state = B_THREAD_SUSPENDED; + Signal signal(SIGSTOP, SI_USER, B_OK, team_get_kernel_team()->id); + send_signal_to_thread(thread, signal, B_DO_NOT_RESCHEDULE); + kprintf("thread %" B_PRId32 " suspended\n", id); found = true; break; @@ -1710,7 +1711,6 @@ _dump_thread_info(Thread *thread, bool shortInfo) kprintf("priority: %" B_PRId32 " (I/O: %" B_PRId32 ")\n", thread->priority, thread->io_priority); kprintf("state: %s\n", state_to_text(thread, thread->state)); - kprintf("next_state: %s\n", state_to_text(thread, thread->next_state)); kprintf("cpu: %p ", thread->cpu); if (thread->cpu) kprintf("(%d)\n", thread->cpu->cpu_num); @@ -2250,8 +2250,7 @@ thread_exit(void) sUndertakerCondition.NotifyOne(); undertakerLocker.Unlock(); - thread->next_state = THREAD_STATE_FREE_ON_RESCHED; - scheduler_reschedule(); + scheduler_reschedule(THREAD_STATE_FREE_ON_RESCHED); panic("never can get here\n"); } @@ -2399,7 +2398,7 @@ thread_yield(void) InterruptsSpinLocker _(thread->scheduler_lock); thread->has_yielded = true; - scheduler_reschedule(); + scheduler_reschedule(B_THREAD_READY); } @@ -2678,7 +2677,6 @@ thread_init(kernel_args *args) thread->team = team_get_kernel_team(); thread->priority = B_IDLE_PRIORITY; thread->state = B_THREAD_RUNNING; - thread->next_state = B_THREAD_READY; sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1); thread->kernel_stack_area = find_area(name); @@ -2828,10 +2826,8 @@ thread_block_locked(Thread* thread) // check for signals, if interruptible if (thread_is_interrupted(thread, thread->wait.flags)) { thread->wait.status = B_INTERRUPTED; - } else { - thread->next_state = B_THREAD_WAITING; - scheduler_reschedule(); - } + } else + scheduler_reschedule(B_THREAD_WAITING); } return thread->wait.status;