/* * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #ifndef KERNEL_LISTENERS_H #define KERNEL_LISTENERS_H #include #include #include struct ConditionVariable; struct mutex; struct rw_lock; // scheduler listeners struct SchedulerListener : DoublyLinkedListLinkImpl { virtual ~SchedulerListener(); virtual void ThreadEnqueuedInRunQueue( Thread* thread) = 0; virtual void ThreadRemovedFromRunQueue( Thread* thread) = 0; virtual void ThreadScheduled(Thread* oldThread, Thread* newThread) = 0; }; typedef DoublyLinkedList SchedulerListenerList; extern SchedulerListenerList gSchedulerListeners; extern spinlock gSchedulerListenersLock; template inline void NotifySchedulerListeners(void (SchedulerListener::*hook)(Parameter1), Parameter1 parameter1) { if (!gSchedulerListeners.IsEmpty()) { SchedulerListenerList::Iterator it = gSchedulerListeners.GetIterator(); while (SchedulerListener* listener = it.Next()) (listener->*hook)(parameter1); } } template inline void NotifySchedulerListeners( void (SchedulerListener::*hook)(Parameter1, Parameter2), Parameter1 parameter1, Parameter2 parameter2) { if (!gSchedulerListeners.IsEmpty()) { SchedulerListenerList::Iterator it = gSchedulerListeners.GetIterator(); while (SchedulerListener* listener = it.Next()) (listener->*hook)(parameter1, parameter2); } } // wait object listeners struct WaitObjectListener : DoublyLinkedListLinkImpl { virtual ~WaitObjectListener(); virtual void SemaphoreCreated(sem_id id, const char* name) = 0; virtual void ConditionVariableInitialized( ConditionVariable* variable) = 0; virtual void MutexInitialized(mutex* lock) = 0; virtual void RWLockInitialized(rw_lock* lock) = 0; }; typedef DoublyLinkedList WaitObjectListenerList; extern WaitObjectListenerList gWaitObjectListeners; extern spinlock gWaitObjectListenerLock; template inline void NotifyWaitObjectListeners(void (WaitObjectListener::*hook)(Parameter1), Parameter1 parameter1) { if (!gWaitObjectListeners.IsEmpty()) { InterruptsSpinLocker locker(gWaitObjectListenerLock); WaitObjectListenerList::Iterator it = gWaitObjectListeners.GetIterator(); while (WaitObjectListener* listener = it.Next()) (listener->*hook)(parameter1); } } template inline void NotifyWaitObjectListeners( void (WaitObjectListener::*hook)(Parameter1, Parameter2), Parameter1 parameter1, Parameter2 parameter2) { if (!gWaitObjectListeners.IsEmpty()) { InterruptsSpinLocker locker(gWaitObjectListenerLock); WaitObjectListenerList::Iterator it = gWaitObjectListeners.GetIterator(); while (WaitObjectListener* listener = it.Next()) (listener->*hook)(parameter1, parameter2); } } void add_wait_object_listener(struct WaitObjectListener* listener); void remove_wait_object_listener(struct WaitObjectListener* listener); #endif // KERNEL_LISTENERS_H