diff --git a/headers/private/kernel/kscheduler.h b/headers/private/kernel/kscheduler.h index 49a3189009..79aa32cfc2 100644 --- a/headers/private/kernel/kscheduler.h +++ b/headers/private/kernel/kscheduler.h @@ -1,5 +1,5 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -12,6 +12,28 @@ struct scheduling_analysis; struct thread; +struct SchedulerListener; + + +#ifdef __cplusplus + +#include + +struct SchedulerListener : DoublyLinkedListLinkImpl { + virtual ~SchedulerListener(); + + virtual void ThreadEnqueuedInRunQueue( + struct thread* thread) = 0; + virtual void ThreadRemovedFromRunQueue( + struct thread* thread) = 0; + virtual void ThreadScheduled(struct thread* oldThread, + struct thread* newThread) = 0; +}; + +typedef DoublyLinkedList SchedulerListenerList; +extern SchedulerListenerList gSchedulerListeners; + +#endif // __cplusplus struct scheduler_ops { @@ -29,7 +51,7 @@ struct scheduler_ops { // called when a thread structure is freed - freeing up any allocated // mem on the scheduler's part should be done here void (*on_thread_destroy)(struct thread* thread); - + void (*start)(void); }; @@ -52,6 +74,9 @@ extern struct scheduler_ops* gScheduler; extern "C" { #endif +void scheduler_add_listener(struct SchedulerListener* listener); +void scheduler_remove_listener(struct SchedulerListener* listener); + void scheduler_init(void); status_t _user_analyze_scheduling(bigtime_t from, bigtime_t until, void* buffer, diff --git a/src/system/kernel/scheduler/scheduler.cpp b/src/system/kernel/scheduler/scheduler.cpp index 805798171e..1b8b1b9488 100644 --- a/src/system/kernel/scheduler/scheduler.cpp +++ b/src/system/kernel/scheduler/scheduler.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -16,6 +16,30 @@ #define SCHEDULER_TYPE 1 struct scheduler_ops* gScheduler; +SchedulerListenerList gSchedulerListeners; + + +SchedulerListener::~SchedulerListener() +{ +} + + +/*! Add the given scheduler listener. Thread lock must be held. +*/ +void +scheduler_add_listener(struct SchedulerListener* listener) +{ + gSchedulerListeners.Add(listener); +} + + +/*! Remove the given scheduler listener. Thread lock must be held. +*/ +void +scheduler_remove_listener(struct SchedulerListener* listener) +{ + gSchedulerListeners.Remove(listener); +} void diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp b/src/system/kernel/scheduler/scheduler_simple.cpp index dcdf24f4e3..40ae5ca74a 100644 --- a/src/system/kernel/scheduler/scheduler_simple.cpp +++ b/src/system/kernel/scheduler/scheduler_simple.cpp @@ -101,6 +101,12 @@ simple_enqueue_in_run_queue(struct thread *thread) T(EnqueueThread(thread, prev, curr)); + // notify listeners + for (SchedulerListenerList::Iterator it = gSchedulerListeners.GetIterator(); + SchedulerListener* listener = it.Next();) { + listener->ThreadEnqueuedInRunQueue(thread); + } + thread->queue_next = curr; if (prev) prev->queue_next = thread; @@ -167,6 +173,12 @@ simple_set_thread_priority(struct thread *thread, int32 priority) T(RemoveThread(thread)); + // notify listeners + for (SchedulerListenerList::Iterator it = gSchedulerListeners.GetIterator(); + SchedulerListener* listener = it.Next();) { + listener->ThreadRemovedFromRunQueue(thread); + } + // find thread in run queue struct thread *item, *prev; for (item = sRunQueue, prev = NULL; item && item != thread; @@ -335,6 +347,12 @@ simple_reschedule(void) T(ScheduleThread(nextThread, oldThread)); + // notify listeners + for (SchedulerListenerList::Iterator it = gSchedulerListeners.GetIterator(); + SchedulerListener* listener = it.Next();) { + listener->ThreadScheduled(oldThread, nextThread); + } + nextThread->state = B_THREAD_RUNNING; nextThread->next_state = B_THREAD_READY; oldThread->was_yielded = false;