1 /* 2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef KERNEL_LISTENERS_H 6 #define KERNEL_LISTENERS_H 7 8 9 #include <KernelExport.h> 10 11 #include <util/AutoLock.h> 12 #include <util/DoublyLinkedList.h> 13 14 15 struct ConditionVariable; 16 struct mutex; 17 struct rw_lock; 18 19 20 // scheduler listeners 21 22 23 struct SchedulerListener : DoublyLinkedListLinkImpl<SchedulerListener> { 24 virtual ~SchedulerListener(); 25 26 virtual void ThreadEnqueuedInRunQueue( 27 Thread* thread) = 0; 28 virtual void ThreadRemovedFromRunQueue( 29 Thread* thread) = 0; 30 virtual void ThreadScheduled(Thread* oldThread, 31 Thread* newThread) = 0; 32 }; 33 34 35 typedef DoublyLinkedList<SchedulerListener> SchedulerListenerList; 36 extern SchedulerListenerList gSchedulerListeners; 37 extern spinlock gSchedulerListenersLock; 38 39 40 template<typename Parameter1> 41 inline void 42 NotifySchedulerListeners(void (SchedulerListener::*hook)(Parameter1), 43 Parameter1 parameter1) 44 { 45 if (!gSchedulerListeners.IsEmpty()) { 46 SchedulerListenerList::Iterator it = gSchedulerListeners.GetIterator(); 47 while (SchedulerListener* listener = it.Next()) 48 (listener->*hook)(parameter1); 49 } 50 } 51 52 53 template<typename Parameter1, typename Parameter2> 54 inline void 55 NotifySchedulerListeners( 56 void (SchedulerListener::*hook)(Parameter1, Parameter2), 57 Parameter1 parameter1, Parameter2 parameter2) 58 { 59 if (!gSchedulerListeners.IsEmpty()) { 60 SchedulerListenerList::Iterator it = gSchedulerListeners.GetIterator(); 61 while (SchedulerListener* listener = it.Next()) 62 (listener->*hook)(parameter1, parameter2); 63 } 64 } 65 66 67 // wait object listeners 68 69 70 struct WaitObjectListener : DoublyLinkedListLinkImpl<WaitObjectListener> { 71 virtual ~WaitObjectListener(); 72 73 virtual void SemaphoreCreated(sem_id id, 74 const char* name) = 0; 75 virtual void ConditionVariableInitialized( 76 ConditionVariable* variable) = 0; 77 virtual void MutexInitialized(mutex* lock) = 0; 78 virtual void RWLockInitialized(rw_lock* lock) = 0; 79 }; 80 81 typedef DoublyLinkedList<WaitObjectListener> WaitObjectListenerList; 82 extern WaitObjectListenerList gWaitObjectListeners; 83 extern spinlock gWaitObjectListenerLock; 84 85 86 template<typename Parameter1> 87 inline void 88 NotifyWaitObjectListeners(void (WaitObjectListener::*hook)(Parameter1), 89 Parameter1 parameter1) 90 { 91 if (!gWaitObjectListeners.IsEmpty()) { 92 InterruptsSpinLocker locker(gWaitObjectListenerLock); 93 WaitObjectListenerList::Iterator it 94 = gWaitObjectListeners.GetIterator(); 95 while (WaitObjectListener* listener = it.Next()) 96 (listener->*hook)(parameter1); 97 } 98 } 99 100 101 template<typename Parameter1, typename Parameter2> 102 inline void 103 NotifyWaitObjectListeners( 104 void (WaitObjectListener::*hook)(Parameter1, Parameter2), 105 Parameter1 parameter1, Parameter2 parameter2) 106 { 107 if (!gWaitObjectListeners.IsEmpty()) { 108 InterruptsSpinLocker locker(gWaitObjectListenerLock); 109 WaitObjectListenerList::Iterator it 110 = gWaitObjectListeners.GetIterator(); 111 while (WaitObjectListener* listener = it.Next()) 112 (listener->*hook)(parameter1, parameter2); 113 } 114 } 115 116 117 void add_wait_object_listener(struct WaitObjectListener* listener); 118 void remove_wait_object_listener(struct WaitObjectListener* listener); 119 120 121 #endif // KERNEL_LISTENERS_H 122