status_t user_timer_get_clock(clockid_t clockID, bigtime_t& _time) { switch (clockID) { case CLOCK_MONOTONIC: _time = system_time(); return B_OK; case CLOCK_REALTIME: _time = real_time_clock_usecs(); return B_OK; case CLOCK_THREAD_CPUTIME_ID: { Thread* thread = thread_get_current_thread(); InterruptsSpinLocker timeLocker(thread->time_lock); _time = thread->CPUTime(false); return B_OK; } case CLOCK_PROCESS_USER_CPUTIME_ID: { Team* team = thread_get_current_thread()->team; InterruptsSpinLocker timeLocker(team->time_lock); _time = team->UserCPUTime(); return B_OK; } case CLOCK_PROCESS_CPUTIME_ID: default: { // get the ID of the target team (or the respective placeholder) team_id teamID; if (clockID == CLOCK_PROCESS_CPUTIME_ID) { teamID = B_CURRENT_TEAM; } else { if (clockID < 0) return B_BAD_VALUE; if (clockID == team_get_kernel_team_id()) return B_NOT_ALLOWED; teamID = clockID; } // get the team Team* team = Team::Get(teamID); if (team == NULL) return B_BAD_VALUE; BReference<Team> teamReference(team, true); // get the time InterruptsSpinLocker timeLocker(team->time_lock); _time = team->CPUTime(false); return B_OK; } } }
status_t _user_set_clock(clockid_t clockID, bigtime_t time) { switch (clockID) { case CLOCK_MONOTONIC: return B_BAD_VALUE; case CLOCK_REALTIME: // only root may set the time if (geteuid() != 0) return B_NOT_ALLOWED; set_real_time_clock_usecs(time); return B_OK; case CLOCK_THREAD_CPUTIME_ID: { Thread* thread = thread_get_current_thread(); InterruptsSpinLocker timeLocker(thread->time_lock); bigtime_t diff = time - thread->CPUTime(false); thread->cpu_clock_offset += diff; thread_clock_changed(thread, diff); return B_OK; } case CLOCK_PROCESS_USER_CPUTIME_ID: // not supported -- this clock is an Haiku-internal extension return B_BAD_VALUE; case CLOCK_PROCESS_CPUTIME_ID: default: { // get the ID of the target team (or the respective placeholder) team_id teamID; if (clockID == CLOCK_PROCESS_CPUTIME_ID) { teamID = B_CURRENT_TEAM; } else { if (clockID < 0) return B_BAD_VALUE; if (clockID == team_get_kernel_team_id()) return B_NOT_ALLOWED; teamID = clockID; } // get the team Team* team = Team::Get(teamID); if (team == NULL) return B_BAD_VALUE; BReference<Team> teamReference(team, true); // set the time offset InterruptsSpinLocker timeLocker(team->time_lock); bigtime_t diff = time - team->CPUTime(false); team->cpu_clock_offset += diff; team_clock_changed(team, diff); return B_OK; } } return B_OK; }