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 IDUserTimer33 int32 ID() const 34 { return fID; } SetIDUserTimer35 void SetID(int32 id) 36 { fID = id; } 37 SetEventUserTimer38 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); RemoveTimerUserTimerList204 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