Added a listener mechanism to the scheduler (ATM only for scheduler_simple).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30242 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Ingo Weinhold, [email protected].
|
* Copyright 2008-2009, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2005, Axel Dörfler, [email protected].
|
* Copyright 2005, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -12,6 +12,28 @@
|
|||||||
|
|
||||||
struct scheduling_analysis;
|
struct scheduling_analysis;
|
||||||
struct thread;
|
struct thread;
|
||||||
|
struct SchedulerListener;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
struct SchedulerListener : DoublyLinkedListLinkImpl<SchedulerListener> {
|
||||||
|
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<SchedulerListener> SchedulerListenerList;
|
||||||
|
extern SchedulerListenerList gSchedulerListeners;
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
|
||||||
struct scheduler_ops {
|
struct scheduler_ops {
|
||||||
@@ -29,7 +51,7 @@ struct scheduler_ops {
|
|||||||
// called when a thread structure is freed - freeing up any allocated
|
// called when a thread structure is freed - freeing up any allocated
|
||||||
// mem on the scheduler's part should be done here
|
// mem on the scheduler's part should be done here
|
||||||
void (*on_thread_destroy)(struct thread* thread);
|
void (*on_thread_destroy)(struct thread* thread);
|
||||||
|
|
||||||
void (*start)(void);
|
void (*start)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,6 +74,9 @@ extern struct scheduler_ops* gScheduler;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void scheduler_add_listener(struct SchedulerListener* listener);
|
||||||
|
void scheduler_remove_listener(struct SchedulerListener* listener);
|
||||||
|
|
||||||
void scheduler_init(void);
|
void scheduler_init(void);
|
||||||
|
|
||||||
status_t _user_analyze_scheduling(bigtime_t from, bigtime_t until, void* buffer,
|
status_t _user_analyze_scheduling(bigtime_t from, bigtime_t until, void* buffer,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Ingo Weinhold, [email protected].
|
* Copyright 2008-2009, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -16,6 +16,30 @@
|
|||||||
#define SCHEDULER_TYPE 1
|
#define SCHEDULER_TYPE 1
|
||||||
|
|
||||||
struct scheduler_ops* gScheduler;
|
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
|
void
|
||||||
|
|||||||
@@ -101,6 +101,12 @@ simple_enqueue_in_run_queue(struct thread *thread)
|
|||||||
|
|
||||||
T(EnqueueThread(thread, prev, curr));
|
T(EnqueueThread(thread, prev, curr));
|
||||||
|
|
||||||
|
// notify listeners
|
||||||
|
for (SchedulerListenerList::Iterator it = gSchedulerListeners.GetIterator();
|
||||||
|
SchedulerListener* listener = it.Next();) {
|
||||||
|
listener->ThreadEnqueuedInRunQueue(thread);
|
||||||
|
}
|
||||||
|
|
||||||
thread->queue_next = curr;
|
thread->queue_next = curr;
|
||||||
if (prev)
|
if (prev)
|
||||||
prev->queue_next = thread;
|
prev->queue_next = thread;
|
||||||
@@ -167,6 +173,12 @@ simple_set_thread_priority(struct thread *thread, int32 priority)
|
|||||||
|
|
||||||
T(RemoveThread(thread));
|
T(RemoveThread(thread));
|
||||||
|
|
||||||
|
// notify listeners
|
||||||
|
for (SchedulerListenerList::Iterator it = gSchedulerListeners.GetIterator();
|
||||||
|
SchedulerListener* listener = it.Next();) {
|
||||||
|
listener->ThreadRemovedFromRunQueue(thread);
|
||||||
|
}
|
||||||
|
|
||||||
// find thread in run queue
|
// find thread in run queue
|
||||||
struct thread *item, *prev;
|
struct thread *item, *prev;
|
||||||
for (item = sRunQueue, prev = NULL; item && item != thread;
|
for (item = sRunQueue, prev = NULL; item && item != thread;
|
||||||
@@ -335,6 +347,12 @@ simple_reschedule(void)
|
|||||||
|
|
||||||
T(ScheduleThread(nextThread, oldThread));
|
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->state = B_THREAD_RUNNING;
|
||||||
nextThread->next_state = B_THREAD_READY;
|
nextThread->next_state = B_THREAD_READY;
|
||||||
oldThread->was_yielded = false;
|
oldThread->was_yielded = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user