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