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 57 inline void CancelTimer(); 58 59protected: 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 71struct 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 79protected: 80 virtual void HandleTimer(); 81 82 void ScheduleKernelTimer(bigtime_t now, 83 bool checkPeriodicOverrun); 84}; 85 86 87struct 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 94private: 95 bigtime_t fRealTimeOffset; 96 bool fAbsolute; 97 98protected: 99 virtual void HandleTimer(); 100 101public: 102 // conceptually package private 103 DoublyLinkedListLink<RealTimeUserTimer> fGlobalListLink; 104}; 105 106 107struct 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 124protected: 125 virtual void HandleTimer(); 126 127private: 128 void _Update(bool unscheduling, 129 Thread* lockedThread = NULL); 130 131private: 132 team_id fTeamID; 133 Team* fTeam; 134 int32 fRunningThreads; 135 bool fAbsolute; 136 137public: 138 // conceptually package private 139 DoublyLinkedListLink<TeamTimeUserTimer> fCPUTimeListLink; 140}; 141 142 143struct 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 157private: 158 team_id fTeamID; 159 Team* fTeam; 160 161public: 162 // conceptually package private 163 DoublyLinkedListLink<TeamUserTimeUserTimer> fCPUTimeListLink; 164}; 165 166 167struct 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 184protected: 185 virtual void HandleTimer(); 186 187private: 188 thread_id fThreadID; 189 Thread* fThread; // != NULL only when active 190 bool fAbsolute; 191 192public: 193 // conceptually package private 194 DoublyLinkedListLink<ThreadTimeUserTimer> fCPUTimeListLink; 195}; 196 197 198struct UserTimerList { 199 UserTimerList(); 200 ~UserTimerList(); 201 202 UserTimer* TimerFor(int32 id) const; 203 void AddTimer(UserTimer* timer); 204 void RemoveTimer(UserTimer* timer) 205 { fTimers.Remove(timer); } 206 int32 DeleteTimers(bool userDefinedOnly); 207 208private: 209 typedef DoublyLinkedList<UserTimer> TimerList; 210 211private: 212 TimerList fTimers; 213}; 214 215 216typedef DoublyLinkedList<RealTimeUserTimer, 217 DoublyLinkedListMemberGetLink<RealTimeUserTimer, 218 &RealTimeUserTimer::fGlobalListLink> > RealTimeUserTimerList; 219 220typedef DoublyLinkedList<TeamTimeUserTimer, 221 DoublyLinkedListMemberGetLink<TeamTimeUserTimer, 222 &TeamTimeUserTimer::fCPUTimeListLink> > TeamTimeUserTimerList; 223 224typedef DoublyLinkedList<TeamUserTimeUserTimer, 225 DoublyLinkedListMemberGetLink<TeamUserTimeUserTimer, 226 &TeamUserTimeUserTimer::fCPUTimeListLink> > TeamUserTimeUserTimerList; 227 228typedef DoublyLinkedList<ThreadTimeUserTimer, 229 DoublyLinkedListMemberGetLink<ThreadTimeUserTimer, 230 &ThreadTimeUserTimer::fCPUTimeListLink> > ThreadTimeUserTimerList; 231 232 233} // namespace BKernel 234 235 236using BKernel::RealTimeUserTimer; 237using BKernel::RealTimeUserTimerList; 238using BKernel::SystemTimeUserTimer; 239using BKernel::TeamUserTimeUserTimer; 240using BKernel::TeamUserTimeUserTimerList; 241using BKernel::TeamTimeUserTimer; 242using BKernel::TeamTimeUserTimerList; 243using BKernel::ThreadTimeUserTimer; 244using BKernel::ThreadTimeUserTimerList; 245using BKernel::UserTimer; 246using BKernel::UserTimerList; 247 248 249__BEGIN_DECLS 250 251status_t user_timer_create_thread_timers(Team* team, Thread* thread); 252status_t user_timer_create_team_timers(Team* team); 253 254status_t user_timer_get_clock(clockid_t clockID, bigtime_t& _time); 255void user_timer_real_time_clock_changed(); 256 257void user_timer_stop_cpu_timers(Thread* thread, Thread* nextThread); 258void user_timer_continue_cpu_timers(Thread* thread, 259 Thread* previousThread); 260void user_timer_check_team_user_timers(Team* team); 261 262status_t _user_get_clock(clockid_t clockID, bigtime_t* _time); 263status_t _user_set_clock(clockid_t clockID, bigtime_t time); 264 265int32 _user_create_timer(clockid_t clockID, thread_id threadID, 266 uint32 flags, const struct sigevent* event, 267 const thread_creation_attributes* threadAttributes); 268status_t _user_delete_timer(int32 timerID, thread_id threadID); 269status_t _user_get_timer(int32 timerID, thread_id threadID, 270 struct user_timer_info* info); 271status_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