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 15struct ConditionVariable; 16struct mutex; 17struct rw_lock; 18 19 20// scheduler listeners 21 22 23struct 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 35typedef DoublyLinkedList<SchedulerListener> SchedulerListenerList; 36extern SchedulerListenerList gSchedulerListeners; 37extern spinlock gSchedulerListenersLock; 38 39 40template<typename Parameter1> 41inline void 42NotifySchedulerListeners(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 53template<typename Parameter1, typename Parameter2> 54inline void 55NotifySchedulerListeners( 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 70struct 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 81typedef DoublyLinkedList<WaitObjectListener> WaitObjectListenerList; 82extern WaitObjectListenerList gWaitObjectListeners; 83extern spinlock gWaitObjectListenerLock; 84 85 86template<typename Parameter1> 87inline void 88NotifyWaitObjectListeners(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 101template<typename Parameter1, typename Parameter2> 102inline void 103NotifyWaitObjectListeners( 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 117void add_wait_object_listener(struct WaitObjectListener* listener); 118void remove_wait_object_listener(struct WaitObjectListener* listener); 119 120 121#endif // KERNEL_LISTENERS_H 122