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