xref: /haiku/headers/private/kernel/UserTimer.h (revision a629567a9001547736cfe892cdf992be16868fed)
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 
19 struct thread_creation_attributes;
20 
21 
22 namespace BKernel {
23 
24 
25 struct UserEvent;
26 struct Team;
27 
28 
29 struct 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 
50 protected:
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 
59 protected:
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 
71 struct 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 
79 protected:
80 	virtual	void				HandleTimer();
81 
82 			void				ScheduleKernelTimer(bigtime_t now,
83 									bool checkPeriodicOverrun);
84 };
85 
86 
87 struct 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 
94 private:
95 			bigtime_t			fRealTimeOffset;
96 			bool				fAbsolute;
97 
98 protected:
99 	virtual	void				HandleTimer();
100 
101 public:
102 			// conceptually package private
103 			DoublyLinkedListLink<RealTimeUserTimer> fGlobalListLink;
104 };
105 
106 
107 struct 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 			void				TimeWarped(bigtime_t changedBy);
122 
123 protected:
124 	virtual	void				HandleTimer();
125 
126 private:
127 			void				_Update(bool unscheduling);
128 
129 private:
130 			team_id				fTeamID;
131 			Team*				fTeam;
132 			int32				fRunningThreads;
133 			bool				fAbsolute;
134 
135 public:
136 			// conceptually package private
137 			DoublyLinkedListLink<TeamTimeUserTimer> fCPUTimeListLink;
138 };
139 
140 
141 struct TeamUserTimeUserTimer : public UserTimer {
142 								TeamUserTimeUserTimer(team_id teamID);
143 								~TeamUserTimeUserTimer();
144 
145 	virtual	void				Schedule(bigtime_t nextTime, bigtime_t interval,
146 									uint32 flags, bigtime_t& _oldRemainingTime,
147 									bigtime_t& _oldInterval);
148 	virtual	void				GetInfo(bigtime_t& _remainingTime,
149 									bigtime_t& _interval,
150 									uint32& _overrunCount);
151 
152 			void				Deactivate();
153 			void				Check();
154 
155 private:
156 			team_id				fTeamID;
157 			Team*				fTeam;
158 
159 public:
160 			// conceptually package private
161 			DoublyLinkedListLink<TeamUserTimeUserTimer> fCPUTimeListLink;
162 };
163 
164 
165 struct ThreadTimeUserTimer : public UserTimer {
166 								ThreadTimeUserTimer(thread_id threadID);
167 								~ThreadTimeUserTimer();
168 
169 	virtual	void				Schedule(bigtime_t nextTime, bigtime_t interval,
170 									uint32 flags, bigtime_t& _oldRemainingTime,
171 									bigtime_t& _oldInterval);
172 	virtual	void				GetInfo(bigtime_t& _remainingTime,
173 									bigtime_t& _interval,
174 									uint32& _overrunCount);
175 
176 			void				Deactivate();
177 
178 			void				Start();
179 			void				Stop();
180 			void				TimeWarped(bigtime_t changedBy);
181 
182 protected:
183 	virtual	void				HandleTimer();
184 
185 private:
186 			thread_id			fThreadID;
187 			Thread*				fThread;	// != NULL only when active
188 			bool				fAbsolute;
189 
190 public:
191 			// conceptually package private
192 			DoublyLinkedListLink<ThreadTimeUserTimer> fCPUTimeListLink;
193 };
194 
195 
196 struct UserTimerList {
197 								UserTimerList();
198 								~UserTimerList();
199 
200 			UserTimer*			TimerFor(int32 id) const;
201 			void				AddTimer(UserTimer* timer);
202 			void				RemoveTimer(UserTimer* timer)
203 									{ fTimers.Remove(timer); }
204 			int32				DeleteTimers(bool userDefinedOnly);
205 
206 private:
207 			typedef DoublyLinkedList<UserTimer> TimerList;
208 
209 private:
210 			TimerList			fTimers;
211 };
212 
213 
214 typedef DoublyLinkedList<RealTimeUserTimer,
215 	DoublyLinkedListMemberGetLink<RealTimeUserTimer,
216 		&RealTimeUserTimer::fGlobalListLink> > RealTimeUserTimerList;
217 
218 typedef DoublyLinkedList<TeamTimeUserTimer,
219 	DoublyLinkedListMemberGetLink<TeamTimeUserTimer,
220 		&TeamTimeUserTimer::fCPUTimeListLink> > TeamTimeUserTimerList;
221 
222 typedef DoublyLinkedList<TeamUserTimeUserTimer,
223 	DoublyLinkedListMemberGetLink<TeamUserTimeUserTimer,
224 		&TeamUserTimeUserTimer::fCPUTimeListLink> > TeamUserTimeUserTimerList;
225 
226 typedef DoublyLinkedList<ThreadTimeUserTimer,
227 	DoublyLinkedListMemberGetLink<ThreadTimeUserTimer,
228 		&ThreadTimeUserTimer::fCPUTimeListLink> > ThreadTimeUserTimerList;
229 
230 
231 }	// namespace BKernel
232 
233 
234 using BKernel::RealTimeUserTimer;
235 using BKernel::RealTimeUserTimerList;
236 using BKernel::SystemTimeUserTimer;
237 using BKernel::TeamUserTimeUserTimer;
238 using BKernel::TeamUserTimeUserTimerList;
239 using BKernel::TeamTimeUserTimer;
240 using BKernel::TeamTimeUserTimerList;
241 using BKernel::ThreadTimeUserTimer;
242 using BKernel::ThreadTimeUserTimerList;
243 using BKernel::UserTimer;
244 using BKernel::UserTimerList;
245 
246 
247 __BEGIN_DECLS
248 
249 status_t	user_timer_create_thread_timers(Team* team, Thread* thread);
250 status_t	user_timer_create_team_timers(Team* team);
251 
252 status_t	user_timer_get_clock(clockid_t clockID, bigtime_t& _time);
253 void		user_timer_real_time_clock_changed();
254 
255 void		user_timer_stop_cpu_timers(Thread* thread, Thread* nextThread);
256 void		user_timer_continue_cpu_timers(Thread* thread,
257 				Thread* previousThread);
258 void		user_timer_check_team_user_timers(Team* team);
259 
260 status_t	_user_get_clock(clockid_t clockID, bigtime_t* _time);
261 status_t	_user_set_clock(clockid_t clockID, bigtime_t time);
262 
263 int32		_user_create_timer(clockid_t clockID, thread_id threadID,
264 				uint32 flags, const struct sigevent* event,
265 				const thread_creation_attributes* threadAttributes);
266 status_t	_user_delete_timer(int32 timerID, thread_id threadID);
267 status_t	_user_get_timer(int32 timerID, thread_id threadID,
268 				struct user_timer_info* info);
269 status_t	_user_set_timer(int32 timerID, thread_id threadID,
270 				bigtime_t startTime, bigtime_t interval, uint32 flags,
271 				struct user_timer_info* oldInfo);
272 
273 __END_DECLS
274 
275 
276 #endif	// _KERNEL_USER_TIMER_H
277