xref: /haiku/headers/private/kernel/listeners.h (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
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