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 19struct thread_creation_attributes; 20 21 22namespace BKernel { 23 24 25struct UserEvent; 26struct Team; 27 28 29struct 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 50protected: 51 static int32 HandleTimerHook(struct timer* timer); 52 virtual void HandleTimer(); 53 54 inline void UpdatePeriodicStartTime(); 55 inline void CheckPeriodicOverrun(bigtime_t now); 56 57protected: 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 68struct 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 76protected: 77 virtual void HandleTimer(); 78 79 void ScheduleKernelTimer(bigtime_t now, 80 bool checkPeriodicOverrun); 81}; 82 83 84struct 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 91private: 92 bigtime_t fRealTimeOffset; 93 bool fAbsolute; 94 95protected: 96 virtual void HandleTimer(); 97 98public: 99 // conceptually package private 100 DoublyLinkedListLink<RealTimeUserTimer> fGlobalListLink; 101}; 102 103 104struct 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 120protected: 121 virtual void HandleTimer(); 122 123private: 124 void _Update(bool unscheduling); 125 126private: 127 team_id fTeamID; 128 Team* fTeam; 129 int32 fRunningThreads; 130 bool fAbsolute; 131 132public: 133 // conceptually package private 134 DoublyLinkedListLink<TeamTimeUserTimer> fCPUTimeListLink; 135}; 136 137 138struct 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 152private: 153 team_id fTeamID; 154 Team* fTeam; 155 156public: 157 // conceptually package private 158 DoublyLinkedListLink<TeamUserTimeUserTimer> fCPUTimeListLink; 159}; 160 161 162struct 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 179protected: 180 virtual void HandleTimer(); 181 182private: 183 thread_id fThreadID; 184 Thread* fThread; // != NULL only when active 185 bool fAbsolute; 186 187public: 188 // conceptually package private 189 DoublyLinkedListLink<ThreadTimeUserTimer> fCPUTimeListLink; 190}; 191 192 193struct 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 203private: 204 typedef DoublyLinkedList<UserTimer> TimerList; 205 206private: 207 TimerList fTimers; 208}; 209 210 211typedef DoublyLinkedList<RealTimeUserTimer, 212 DoublyLinkedListMemberGetLink<RealTimeUserTimer, 213 &RealTimeUserTimer::fGlobalListLink> > RealTimeUserTimerList; 214 215typedef DoublyLinkedList<TeamTimeUserTimer, 216 DoublyLinkedListMemberGetLink<TeamTimeUserTimer, 217 &TeamTimeUserTimer::fCPUTimeListLink> > TeamTimeUserTimerList; 218 219typedef DoublyLinkedList<TeamUserTimeUserTimer, 220 DoublyLinkedListMemberGetLink<TeamUserTimeUserTimer, 221 &TeamUserTimeUserTimer::fCPUTimeListLink> > TeamUserTimeUserTimerList; 222 223typedef DoublyLinkedList<ThreadTimeUserTimer, 224 DoublyLinkedListMemberGetLink<ThreadTimeUserTimer, 225 &ThreadTimeUserTimer::fCPUTimeListLink> > ThreadTimeUserTimerList; 226 227 228} // namespace BKernel 229 230 231using BKernel::RealTimeUserTimer; 232using BKernel::RealTimeUserTimerList; 233using BKernel::SystemTimeUserTimer; 234using BKernel::TeamUserTimeUserTimer; 235using BKernel::TeamUserTimeUserTimerList; 236using BKernel::TeamTimeUserTimer; 237using BKernel::TeamTimeUserTimerList; 238using BKernel::ThreadTimeUserTimer; 239using BKernel::ThreadTimeUserTimerList; 240using BKernel::UserTimer; 241using BKernel::UserTimerList; 242 243 244__BEGIN_DECLS 245 246status_t user_timer_create_thread_timers(Team* team, Thread* thread); 247status_t user_timer_create_team_timers(Team* team); 248 249status_t user_timer_get_clock(clockid_t clockID, bigtime_t& _time); 250void user_timer_real_time_clock_changed(); 251 252void user_timer_stop_cpu_timers(Thread* thread, Thread* nextThread); 253void user_timer_continue_cpu_timers(Thread* thread, 254 Thread* previousThread); 255void user_timer_check_team_user_timers(Team* team); 256 257status_t _user_get_clock(clockid_t clockID, bigtime_t* _time); 258status_t _user_set_clock(clockid_t clockID, bigtime_t time); 259 260int32 _user_create_timer(clockid_t clockID, thread_id threadID, 261 uint32 flags, const struct sigevent* event, 262 const thread_creation_attributes* threadAttributes); 263status_t _user_delete_timer(int32 timerID, thread_id threadID); 264status_t _user_get_timer(int32 timerID, thread_id threadID, 265 struct user_timer_info* info); 266status_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