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