Author: bonefish Date: 2011-06-06 17:12:30 +0200 (Mon, 06 Jun 2011) New Revision: 41969 Changeset: https://dev.haiku-os.org/changeset/41969 Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h haiku/branches/developer/bonefish/signals/headers/private/system/user_timer_defs.h haiku/branches/developer/bonefish/signals/src/system/kernel/UserTimer.cpp haiku/branches/developer/bonefish/signals/src/system/kernel/arch/x86/arch_interrupts.S haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp Log: * Thread::in_kernel: Is now guarded by time_lock, too. * Added Team::UserCPUTime(), returning the team's user CPU time. * Introduced a clock ID CLOCK_PROCESS_USER_CPUTIME_ID, referring to the current team's user time. Implemented in user_timer_get_clock() only, yet. Modified: haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h 2011-06-06 14:44:57 UTC (rev 41968) +++ haiku/branches/developer/bonefish/signals/headers/private/kernel/thread_types.h 2011-06-06 15:12:30 UTC (rev 41969) @@ -375,6 +375,7 @@ { return fCPUTimeUserTimers.GetIterator(); } bigtime_t CPUTime(bool ignoreCurrentRun) const; + bigtime_t UserCPUTime() const; private: Team(team_id id, bool kernel); @@ -429,7 +430,8 @@ size_t signal_stack_size; // only accessed by this thread bool signal_stack_enabled; // only accessed by this thread - bool in_kernel; + bool in_kernel; // protected by time_lock, only written by + // this thread bool was_yielded; // protected by scheduler lock struct scheduler_thread_data* scheduler_data; // protected by scheduler lock Modified: haiku/branches/developer/bonefish/signals/headers/private/system/user_timer_defs.h =================================================================== --- haiku/branches/developer/bonefish/signals/headers/private/system/user_timer_defs.h 2011-06-06 14:44:57 UTC (rev 41968) +++ haiku/branches/developer/bonefish/signals/headers/private/system/user_timer_defs.h 2011-06-06 15:12:30 UTC (rev 41969) @@ -12,6 +12,9 @@ #include <SupportDefs.h> +#define CLOCK_PROCESS_USER_CPUTIME_ID ((clock_t)-4) + /* clock measuring the used user CPU time of the current process */ + // limits #define MAX_USER_TIMERS_PER_TEAM _POSIX_TIMER_MAX // maximum numbers of user-defined user timers (timer_create()) Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/UserTimer.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/UserTimer.cpp 2011-06-06 14:44:57 UTC (rev 41968) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/UserTimer.cpp 2011-06-06 15:12:30 UTC (rev 41969) @@ -1006,6 +1006,10 @@ timer = new(std::nothrow) TeamTimeUserTimer(team->id); break; + case CLOCK_PROCESS_USER_CPUTIME_ID: + // TODO:... + return B_BAD_VALUE; + default: { // The clock ID is a ID of the team whose CPU time the clock refers @@ -1233,6 +1237,14 @@ return B_OK; } + case CLOCK_PROCESS_USER_CPUTIME_ID: + { + Team* team = thread_get_current_thread()->team; + InterruptsSpinLocker schedulerLocker(gSchedulerLock); + _time = team->UserCPUTime(); + return B_OK; + } + case CLOCK_PROCESS_CPUTIME_ID: default: { @@ -1370,6 +1382,10 @@ 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: { Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/arch/x86/arch_interrupts.S =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/arch/x86/arch_interrupts.S 2011-06-06 14:44:57 UTC (rev 41968) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/arch/x86/arch_interrupts.S 2011-06-06 15:12:30 UTC (rev 41969) @@ -91,10 +91,10 @@ movl %ebx, THREAD_last_time(%edi); \ movl %ecx, (THREAD_last_time + 4)(%edi); \ \ + /* thread->in_kernel = false; */ \ + movb $0, THREAD_in_kernel(%edi); \ + \ UNLOCK_THREAD_TIME() \ - \ - /* thread->in_kernel = false; */ \ - movb $0, THREAD_in_kernel(%edi) #define PUSH_IFRAME_BOTTOM(iframeType) \ pusha; \ Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp 2011-06-06 14:44:57 UTC (rev 41968) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/team.cpp 2011-06-06 15:12:30 UTC (rev 41969) @@ -903,7 +903,7 @@ updated. Should be used in "thread unscheduled" scheduler callbacks, since although the thread is still running at that time, its time has already been stopped. - \return The thread's current total CPU time. + \return The team's current total CPU time. */ bigtime_t Team::CPUTime(bool ignoreCurrentRun) const @@ -929,6 +929,32 @@ } +/*! Returns the team's current user CPU time. + + The caller must hold the scheduler lock. + + \return The team's current user CPU time. +*/ +bigtime_t +Team::UserCPUTime() const +{ + bigtime_t time = dead_threads_user_time; + + bigtime_t now = system_time(); + + for (Thread* thread = thread_list; thread != NULL; + thread = thread->team_next) { + SpinLocker threadTimeLocker(thread->time_lock); + time += thread->user_time; + + if (thread->IsRunning() && !thread->in_kernel) + time += now - thread->last_time; + } + + return time; +} + + // #pragma mark - ProcessGroup Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp 2011-06-06 14:44:57 UTC (rev 41968) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/thread.cpp 2011-06-06 15:12:30 UTC (rev 41969) @@ -2227,9 +2227,8 @@ SpinLocker threadTimeLocker(thread->time_lock); thread->user_time += now - thread->last_time; thread->last_time = now; - threadTimeLocker.Unlock(); - thread->in_kernel = true; + threadTimeLocker.Unlock(); } @@ -2251,11 +2250,10 @@ disable_interrupts(); - thread->in_kernel = false; - // track kernel time bigtime_t now = system_time(); SpinLocker threadTimeLocker(thread->time_lock); + thread->in_kernel = false; thread->kernel_time += now - thread->last_time; thread->last_time = now; } @@ -2272,11 +2270,10 @@ TRACE(("thread_at_kernel_exit_no_signals: exit thread %ld\n", thread->id)); - thread->in_kernel = false; - // track kernel time bigtime_t now = system_time(); SpinLocker threadTimeLocker(thread->time_lock); + thread->in_kernel = false; thread->kernel_time += now - thread->last_time; thread->last_time = now; }