Author: bonefish Date: 2011-05-10 16:40:20 +0200 (Tue, 10 May 2011) New Revision: 41420 Changeset: https://dev.haiku-os.org/changeset/41420 Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/kscheduler.h haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_affine.cpp haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_simple.cpp haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_simple_smp.cpp haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp Log: * Turn existing scheduler_ops hook comments into doxygen comments and extended them/added missing ones. * scheduler_ops::on_thread_create(): Changed return type to status_t (affine_on_thread_create() does no longer need to panic()) and added bool idleThread parameter (used by affine_on_thread_create()). Resolved the respective TODOs in Thread::Init(). Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/kscheduler.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/private/kernel/kscheduler.h 2011-05-10 13:06:07 UTC (rev 41419) +++ haiku/branches/developer/bonefish/signals/headers/private/kernel/kscheduler.h 2011-05-10 14:40:20 UTC (rev 41420) @@ -18,23 +18,54 @@ struct scheduler_ops { + /*! Enqueues the thread in the ready-to-run queue. + The caller must hold the scheduler lock (with disabled interrupts). + */ void (*enqueue_in_run_queue)(Thread* thread); + + /*! Selects a thread from the ready-to-run queue and, if that's not the + calling thread, switches the current CPU's context to run the selected + thread. + If it's the same thread, the thread will just continue to run. + In either case, unless the thread is dead or is sleeping/waiting + indefinitely, the function will eventually return. + The caller must hold the scheduler lock (with disabled interrupts). + */ void (*reschedule)(void); + + /*! Sets the given thread's priority. + The thread may be running or may be in the ready-to-run queue. + The caller must hold the scheduler lock (with disabled interrupts). + */ void (*set_thread_priority)(Thread* thread, int32 priority); bigtime_t (*estimate_max_scheduling_latency)(Thread* thread); - void (*on_thread_create)(Thread* thread); - // called when the thread structure is first created - - // initialization of per-thread housekeeping data structures should - // be done here + /*! Called when the Thread structure is first created. + Per-thread housekeeping resources can be allocated. + Interrupts must be enabled. + */ + status_t (*on_thread_create)(Thread* thread, bool idleThread); + + /*! Called when a Thread structure is initialized and made ready for + use. + The per-thread housekeeping data structures are reset, if needed. + The caller must hold the scheduler lock (with disabled interrupts). + */ void (*on_thread_init)(Thread* thread); - // called when a thread structure is initialized and made ready for - // use - should be used to reset the housekeeping data structures - // if needed + + /*! Called when a Thread structure is freed. + Frees up any per-thread resources allocated on the scheduler's part. The + function may be called even if on_thread_create() failed. + Interrupts must be enabled. + */ void (*on_thread_destroy)(Thread* thread); - // called when a thread structure is freed - freeing up any allocated - // mem on the scheduler's part should be done here + /*! Called in the early boot process to start thread scheduling on the + current CPU. + The function is called once for each CPU. + Interrupts must be disabled, but the caller must not hold the scheduler + lock. + */ void (*start)(void); }; @@ -46,8 +77,8 @@ gScheduler->set_thread_priority(thread, priority) #define scheduler_reschedule() gScheduler->reschedule() #define scheduler_start() gScheduler->start() -#define scheduler_on_thread_create(thread) \ - gScheduler->on_thread_create(thread) +#define scheduler_on_thread_create(thread, idleThread) \ + gScheduler->on_thread_create(thread, idleThread) #define scheduler_on_thread_init(thread) \ gScheduler->on_thread_init(thread) #define scheduler_on_thread_destroy(thread) \ Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_affine.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_affine.cpp 2011-05-10 13:06:07 UTC (rev 41419) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_affine.cpp 2011-05-10 14:40:20 UTC (rev 41420) @@ -533,12 +533,19 @@ } -static void -affine_on_thread_create(Thread* thread) +static status_t +affine_on_thread_create(Thread* thread, bool idleThread) { + // we don't need a data structure for the idle threads + if (idleThread) { + thread->scheduler_data = NULL; + return B_OK; + } + thread->scheduler_data = new(std::nothrow) scheduler_thread_data(); if (thread->scheduler_data == NULL) - panic("affine_scheduler: Unable to allocate scheduling data structure for thread %ld\n", thread->id); + return B_NO_MEMORY; + return B_OK; } Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_simple.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_simple.cpp 2011-05-10 13:06:07 UTC (rev 41419) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_simple.cpp 2011-05-10 14:40:20 UTC (rev 41420) @@ -357,10 +357,11 @@ } -static void -simple_on_thread_create(Thread* thread) +static status_t +simple_on_thread_create(Thread* thread, bool idleThread) { // do nothing + return B_OK; } Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_simple_smp.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_simple_smp.cpp 2011-05-10 13:06:07 UTC (rev 41419) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/scheduler/scheduler_simple_smp.cpp 2011-05-10 14:40:20 UTC (rev 41420) @@ -456,10 +456,11 @@ } -static void -on_thread_create(Thread* thread) +static status_t +on_thread_create(Thread* thread, bool idleThread) { // do nothing + return B_OK; } Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp 2011-05-10 13:06:07 UTC (rev 41419) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp 2011-05-10 14:40:20 UTC (rev 41420) @@ -276,12 +276,9 @@ status_t Thread::Init(bool idleThread) { - // TODO: Not initializing the scheduler structure for the idle threads is - // weird. Pass on the flag and let the scheduler decide. - // TODO: The function should return an error code. The affine scheduler - // panic()s instead! - if (!idleThread) - scheduler_on_thread_create(this); + status_t error = scheduler_on_thread_create(this, idleThread); + if (error != B_OK) + return error; char temp[64]; sprintf(temp, "thread_%ld_retcode_sem", id); @@ -299,7 +296,7 @@ if (msg.read_sem < 0) return msg.read_sem; - status_t error = arch_thread_init_thread_struct(this); + error = arch_thread_init_thread_struct(this); if (error != B_OK) return error;