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