1/*
2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _KERNEL_USER_TIMER_H
6#define _KERNEL_USER_TIMER_H
7
8
9#include <sys/cdefs.h>
10#include <time.h>
11
12#include <util/DoublyLinkedList.h>
13
14#include <ksignal.h>
15#include <timer.h>
16#include <user_timer_defs.h>
17
18
19struct thread_creation_attributes;
20
21
22namespace BKernel {
23
24
25struct UserEvent;
26struct Team;
27
28
29struct UserTimer : DoublyLinkedListLinkImpl<UserTimer> {
30								UserTimer();
31	virtual						~UserTimer();
32
33			int32				ID() const
34									{ return fID; }
35			void				SetID(int32 id)
36									{ fID = id; }
37
38			void				SetEvent(UserEvent* event)
39									{ fEvent = event; }
40
41	virtual	void				Schedule(bigtime_t nextTime, bigtime_t interval,
42									uint32 flags, bigtime_t& _oldRemainingTime,
43									bigtime_t& _oldInterval) = 0;
44			void				Cancel();
45
46	virtual	void				GetInfo(bigtime_t& _remainingTime,
47									bigtime_t& _interval,
48									uint32& _overrunCount) = 0;
49
50protected:
51	static	int32				HandleTimerHook(struct timer* timer);
52	virtual	void				HandleTimer();
53
54	inline	void				UpdatePeriodicStartTime();
55	inline	void				CheckPeriodicOverrun(bigtime_t now);
56
57	inline	void				CancelTimer();
58
59protected:
60			int32				fID;
61			timer				fTimer;
62			UserEvent*			fEvent;
63			bigtime_t			fNextTime;
64			bigtime_t			fInterval;
65			uint32				fOverrunCount;
66			bool				fScheduled;	// fTimer scheduled
67			int32				fSkip;
68};
69
70
71struct SystemTimeUserTimer : public UserTimer {
72	virtual	void				Schedule(bigtime_t nextTime, bigtime_t interval,
73									uint32 flags, bigtime_t& _oldRemainingTime,
74									bigtime_t& _oldInterval);
75	virtual	void				GetInfo(bigtime_t& _remainingTime,
76									bigtime_t& _interval,
77									uint32& _overrunCount);
78
79protected:
80	virtual	void				HandleTimer();
81
82			void				ScheduleKernelTimer(bigtime_t now,
83									bool checkPeriodicOverrun);
84};
85
86
87struct RealTimeUserTimer : public SystemTimeUserTimer {
88	virtual	void				Schedule(bigtime_t nextTime, bigtime_t interval,
89									uint32 flags, bigtime_t& _oldRemainingTime,
90									bigtime_t& _oldInterval);
91
92			void				TimeWarped();
93
94private:
95			bigtime_t			fRealTimeOffset;
96			bool				fAbsolute;
97
98protected:
99	virtual	void				HandleTimer();
100
101public:
102			// conceptually package private
103			DoublyLinkedListLink<RealTimeUserTimer> fGlobalListLink;
104};
105
106
107struct TeamTimeUserTimer : public UserTimer {
108								TeamTimeUserTimer(team_id teamID);
109								~TeamTimeUserTimer();
110
111	virtual	void				Schedule(bigtime_t nextTime, bigtime_t interval,
112									uint32 flags, bigtime_t& _oldRemainingTime,
113									bigtime_t& _oldInterval);
114	virtual	void				GetInfo(bigtime_t& _remainingTime,
115									bigtime_t& _interval,
116									uint32& _overrunCount);
117
118			void				Deactivate();
119
120			void				Update(Thread* unscheduledThread,
121									Thread* lockedThread = NULL);
122			void				TimeWarped(bigtime_t changedBy);
123
124protected:
125	virtual	void				HandleTimer();
126
127private:
128			void				_Update(bool unscheduling,
129									Thread* lockedThread = NULL);
130
131private:
132			team_id				fTeamID;
133			Team*				fTeam;
134			int32				fRunningThreads;
135			bool				fAbsolute;
136
137public:
138			// conceptually package private
139			DoublyLinkedListLink<TeamTimeUserTimer> fCPUTimeListLink;
140};
141
142
143struct TeamUserTimeUserTimer : public UserTimer {
144								TeamUserTimeUserTimer(team_id teamID);
145								~TeamUserTimeUserTimer();
146
147	virtual	void				Schedule(bigtime_t nextTime, bigtime_t interval,
148									uint32 flags, bigtime_t& _oldRemainingTime,
149									bigtime_t& _oldInterval);
150	virtual	void				GetInfo(bigtime_t& _remainingTime,
151									bigtime_t& _interval,
152									uint32& _overrunCount);
153
154			void				Deactivate();
155			void				Check();
156
157private:
158			team_id				fTeamID;
159			Team*				fTeam;
160
161public:
162			// conceptually package private
163			DoublyLinkedListLink<TeamUserTimeUserTimer> fCPUTimeListLink;
164};
165
166
167struct ThreadTimeUserTimer : public UserTimer {
168								ThreadTimeUserTimer(thread_id threadID);
169								~ThreadTimeUserTimer();
170
171	virtual	void				Schedule(bigtime_t nextTime, bigtime_t interval,
172									uint32 flags, bigtime_t& _oldRemainingTime,
173									bigtime_t& _oldInterval);
174	virtual	void				GetInfo(bigtime_t& _remainingTime,
175									bigtime_t& _interval,
176									uint32& _overrunCount);
177
178			void				Deactivate();
179
180			void				Start();
181			void				Stop();
182			void				TimeWarped(bigtime_t changedBy);
183
184protected:
185	virtual	void				HandleTimer();
186
187private:
188			thread_id			fThreadID;
189			Thread*				fThread;	// != NULL only when active
190			bool				fAbsolute;
191
192public:
193			// conceptually package private
194			DoublyLinkedListLink<ThreadTimeUserTimer> fCPUTimeListLink;
195};
196
197
198struct UserTimerList {
199								UserTimerList();
200								~UserTimerList();
201
202			UserTimer*			TimerFor(int32 id) const;
203			void				AddTimer(UserTimer* timer);
204			void				RemoveTimer(UserTimer* timer)
205									{ fTimers.Remove(timer); }
206			int32				DeleteTimers(bool userDefinedOnly);
207
208private:
209			typedef DoublyLinkedList<UserTimer> TimerList;
210
211private:
212			TimerList			fTimers;
213};
214
215
216typedef DoublyLinkedList<RealTimeUserTimer,
217	DoublyLinkedListMemberGetLink<RealTimeUserTimer,
218		&RealTimeUserTimer::fGlobalListLink> > RealTimeUserTimerList;
219
220typedef DoublyLinkedList<TeamTimeUserTimer,
221	DoublyLinkedListMemberGetLink<TeamTimeUserTimer,
222		&TeamTimeUserTimer::fCPUTimeListLink> > TeamTimeUserTimerList;
223
224typedef DoublyLinkedList<TeamUserTimeUserTimer,
225	DoublyLinkedListMemberGetLink<TeamUserTimeUserTimer,
226		&TeamUserTimeUserTimer::fCPUTimeListLink> > TeamUserTimeUserTimerList;
227
228typedef DoublyLinkedList<ThreadTimeUserTimer,
229	DoublyLinkedListMemberGetLink<ThreadTimeUserTimer,
230		&ThreadTimeUserTimer::fCPUTimeListLink> > ThreadTimeUserTimerList;
231
232
233}	// namespace BKernel
234
235
236using BKernel::RealTimeUserTimer;
237using BKernel::RealTimeUserTimerList;
238using BKernel::SystemTimeUserTimer;
239using BKernel::TeamUserTimeUserTimer;
240using BKernel::TeamUserTimeUserTimerList;
241using BKernel::TeamTimeUserTimer;
242using BKernel::TeamTimeUserTimerList;
243using BKernel::ThreadTimeUserTimer;
244using BKernel::ThreadTimeUserTimerList;
245using BKernel::UserTimer;
246using BKernel::UserTimerList;
247
248
249__BEGIN_DECLS
250
251status_t	user_timer_create_thread_timers(Team* team, Thread* thread);
252status_t	user_timer_create_team_timers(Team* team);
253
254status_t	user_timer_get_clock(clockid_t clockID, bigtime_t& _time);
255void		user_timer_real_time_clock_changed();
256
257void		user_timer_stop_cpu_timers(Thread* thread, Thread* nextThread);
258void		user_timer_continue_cpu_timers(Thread* thread,
259				Thread* previousThread);
260void		user_timer_check_team_user_timers(Team* team);
261
262status_t	_user_get_clock(clockid_t clockID, bigtime_t* _time);
263status_t	_user_set_clock(clockid_t clockID, bigtime_t time);
264
265int32		_user_create_timer(clockid_t clockID, thread_id threadID,
266				uint32 flags, const struct sigevent* event,
267				const thread_creation_attributes* threadAttributes);
268status_t	_user_delete_timer(int32 timerID, thread_id threadID);
269status_t	_user_get_timer(int32 timerID, thread_id threadID,
270				struct user_timer_info* info);
271status_t	_user_set_timer(int32 timerID, thread_id threadID,
272				bigtime_t startTime, bigtime_t interval, uint32 flags,
273				struct user_timer_info* oldInfo);
274
275__END_DECLS
276
277
278#endif	// _KERNEL_USER_TIMER_H
279