xref: /haiku/headers/private/kernel/UserTimer.h (revision 4bd0c1066b227cec4b79883bdef697c7a27f2e90)
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 									Thread* lockedThread = NULL);
122 			void				TimeWarped(bigtime_t changedBy);
123 
124 protected:
125 	virtual	void				HandleTimer();
126 
127 private:
128 			void				_Update(bool unscheduling,
129 									Thread* lockedThread = NULL);
130 
131 private:
132 			team_id				fTeamID;
133 			Team*				fTeam;
134 			int32				fRunningThreads;
135 			bool				fAbsolute;
136 
137 public:
138 			// conceptually package private
139 			DoublyLinkedListLink<TeamTimeUserTimer> fCPUTimeListLink;
140 };
141 
142 
143 struct 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 
157 private:
158 			team_id				fTeamID;
159 			Team*				fTeam;
160 
161 public:
162 			// conceptually package private
163 			DoublyLinkedListLink<TeamUserTimeUserTimer> fCPUTimeListLink;
164 };
165 
166 
167 struct 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 
184 protected:
185 	virtual	void				HandleTimer();
186 
187 private:
188 			thread_id			fThreadID;
189 			Thread*				fThread;	// != NULL only when active
190 			bool				fAbsolute;
191 
192 public:
193 			// conceptually package private
194 			DoublyLinkedListLink<ThreadTimeUserTimer> fCPUTimeListLink;
195 };
196 
197 
198 struct 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 
208 private:
209 			typedef DoublyLinkedList<UserTimer> TimerList;
210 
211 private:
212 			TimerList			fTimers;
213 };
214 
215 
216 typedef DoublyLinkedList<RealTimeUserTimer,
217 	DoublyLinkedListMemberGetLink<RealTimeUserTimer,
218 		&RealTimeUserTimer::fGlobalListLink> > RealTimeUserTimerList;
219 
220 typedef DoublyLinkedList<TeamTimeUserTimer,
221 	DoublyLinkedListMemberGetLink<TeamTimeUserTimer,
222 		&TeamTimeUserTimer::fCPUTimeListLink> > TeamTimeUserTimerList;
223 
224 typedef DoublyLinkedList<TeamUserTimeUserTimer,
225 	DoublyLinkedListMemberGetLink<TeamUserTimeUserTimer,
226 		&TeamUserTimeUserTimer::fCPUTimeListLink> > TeamUserTimeUserTimerList;
227 
228 typedef DoublyLinkedList<ThreadTimeUserTimer,
229 	DoublyLinkedListMemberGetLink<ThreadTimeUserTimer,
230 		&ThreadTimeUserTimer::fCPUTimeListLink> > ThreadTimeUserTimerList;
231 
232 
233 }	// namespace BKernel
234 
235 
236 using BKernel::RealTimeUserTimer;
237 using BKernel::RealTimeUserTimerList;
238 using BKernel::SystemTimeUserTimer;
239 using BKernel::TeamUserTimeUserTimer;
240 using BKernel::TeamUserTimeUserTimerList;
241 using BKernel::TeamTimeUserTimer;
242 using BKernel::TeamTimeUserTimerList;
243 using BKernel::ThreadTimeUserTimer;
244 using BKernel::ThreadTimeUserTimerList;
245 using BKernel::UserTimer;
246 using BKernel::UserTimerList;
247 
248 
249 __BEGIN_DECLS
250 
251 status_t	user_timer_create_thread_timers(Team* team, Thread* thread);
252 status_t	user_timer_create_team_timers(Team* team);
253 
254 status_t	user_timer_get_clock(clockid_t clockID, bigtime_t& _time);
255 void		user_timer_real_time_clock_changed();
256 
257 void		user_timer_stop_cpu_timers(Thread* thread, Thread* nextThread);
258 void		user_timer_continue_cpu_timers(Thread* thread,
259 				Thread* previousThread);
260 void		user_timer_check_team_user_timers(Team* team);
261 
262 status_t	_user_get_clock(clockid_t clockID, bigtime_t* _time);
263 status_t	_user_set_clock(clockid_t clockID, bigtime_t time);
264 
265 int32		_user_create_timer(clockid_t clockID, thread_id threadID,
266 				uint32 flags, const struct sigevent* event,
267 				const thread_creation_attributes* threadAttributes);
268 status_t	_user_delete_timer(int32 timerID, thread_id threadID);
269 status_t	_user_get_timer(int32 timerID, thread_id threadID,
270 				struct user_timer_info* info);
271 status_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