From 6503e5d9c6ab89ebb681b4819b07d3ff4890e5fb Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 11 Oct 2008 18:11:12 +0000 Subject: [PATCH] Added functions to pin a thread to the current CPU (i.e. it will only be scheduled on that CPU) and to avoid unscheduling it. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27974 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/thread.h | 28 +++++++++++++++++++++++++++ headers/private/kernel/thread_types.h | 3 +++ src/system/kernel/scheduler.cpp | 17 +++++++++++++--- src/system/kernel/thread.cpp | 3 +++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/headers/private/kernel/thread.h b/headers/private/kernel/thread.h index 9a3bdd83ef..864859b35b 100644 --- a/headers/private/kernel/thread.h +++ b/headers/private/kernel/thread.h @@ -205,4 +205,32 @@ thread_interrupt(struct thread* thread, bool kill) } +static inline void +thread_pin_to_current_cpu(struct thread* thread) +{ + thread->pinned_to_cpu++; +} + + +static inline void +thread_unpin_from_current_cpu(struct thread* thread) +{ + thread->pinned_to_cpu--; +} + + +static inline void +thread_disable_scheduling(struct thread* thread) +{ + thread->keep_scheduled++; +} + + +static inline void +thread_enable_scheduling(struct thread* thread) +{ + thread->keep_scheduled--; +} + + #endif /* _THREAD_H */ diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 9506c1ae31..0b4363073e 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -230,6 +230,9 @@ struct thread { int32 state; int32 next_state; struct cpu_ent *cpu; + struct cpu_ent *previous_cpu; + int32 pinned_to_cpu; + int32 keep_scheduled; sigset_t sig_pending; sigset_t sig_block_mask; diff --git a/src/system/kernel/scheduler.cpp b/src/system/kernel/scheduler.cpp index 6f9fd85891..3a52c6e8d9 100644 --- a/src/system/kernel/scheduler.cpp +++ b/src/system/kernel/scheduler.cpp @@ -543,7 +543,7 @@ context_switch(struct thread *fromThread, struct thread *toThread) if ((fromThread->flags & THREAD_FLAGS_DEBUGGER_INSTALLED) != 0) user_debug_thread_unscheduled(fromThread); - toThread->cpu = fromThread->cpu; + toThread->previous_cpu = toThread->cpu = fromThread->cpu; fromThread->cpu = NULL; arch_thread_set_current_thread(toThread); @@ -560,8 +560,11 @@ context_switch(struct thread *fromThread, struct thread *toThread) static int32 reschedule_event(timer *unused) { - // this function is called as a result of the timer event set by the scheduler - // returning this causes a reschedule on the timer event + if (thread_get_current_thread()->keep_scheduled > 0) + return B_HANDLED_INTERRUPT; + + // this function is called as a result of the timer event set by the + // scheduler returning this causes a reschedule on the timer event thread_get_current_thread()->cpu->preempted = 1; return B_INVOKE_SCHEDULER; } @@ -617,6 +620,14 @@ scheduler_reschedule(void) } #endif + // skip thread, if it doesn't want to run on this CPU + if (nextThread->pinned_to_cpu > 0 + && nextThread->previous_cpu != oldThread->cpu) { + prevThread = nextThread; + nextThread = nextThread->queue_next; + continue; + } + // always extract real time threads if (nextThread->priority >= B_FIRST_REAL_TIME_PRIORITY) break; diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 46a251f74c..7e2706aa85 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -223,6 +223,9 @@ create_thread_struct(struct thread *inthread, const char *name, thread->id = threadID >= 0 ? threadID : allocate_thread_id(); thread->team = NULL; thread->cpu = cpu; + thread->previous_cpu = NULL; + thread->pinned_to_cpu = 0; + thread->keep_scheduled = 0; thread->fault_handler = 0; thread->page_faults_allowed = 1; thread->kernel_stack_area = -1;