From 9b6593acaedbd0566335046d210c304e020a3788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 26 Nov 2004 14:58:01 +0000 Subject: [PATCH] Now remembers the time spent in children/threads that are already gone. Implemented get_team_usage_info() - not really tested, though. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10251 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/team.c | 72 +++++++++++++++++++++++++++++++++++++--- src/kernel/core/thread.c | 8 +++++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/kernel/core/team.c b/src/kernel/core/team.c index c297c5147c..fc764d4a6f 100644 --- a/src/kernel/core/team.c +++ b/src/kernel/core/team.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -651,9 +652,14 @@ create_team_struct(const char *name, bool kernel) team->death_sem = -1; team->user_env_base = 0; + team->dead_threads_kernel_time = 0; + team->dead_threads_user_time = 0; + list_init(&team->dead_children.list); team->dead_children.count = 0; team->dead_children.wait_for_any = 0; + team->dead_children.kernel_time = 0; + team->dead_children.user_time = 0; team->dead_children.sem = create_sem(0, "dead children"); if (team->dead_children.sem < B_OK) goto error1; @@ -1643,14 +1649,72 @@ err: status_t -_get_team_usage_info(team_id team, int32 who, team_usage_info *info, size_t size) +_get_team_usage_info(team_id id, int32 who, team_usage_info *info, size_t size) { - if (size != sizeof(team_usage_info)) + bigtime_t kernelTime = 0, userTime = 0; + status_t status = B_OK; + struct team *team; + cpu_status state; + + if (size != sizeof(team_usage_info) + || (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)) return B_BAD_VALUE; - // implement me! + state = disable_interrupts(); + GRAB_TEAM_LOCK(); - return B_ERROR; + team = team_get_team_struct_locked(id); + if (team == NULL) { + status = B_BAD_TEAM_ID; + goto out; + } + + switch (who) { + case RUSAGE_SELF: + { + struct thread *thread = team->thread_list; + + for (; thread != NULL; thread = thread->team_next) { + kernelTime += thread->kernel_time; + userTime += thread->user_time; + } + + kernelTime += team->dead_threads_kernel_time; + userTime += team->dead_threads_user_time; + break; + } + + case RUSAGE_CHILDREN: + { + struct team *child = team->children; + for (; child != NULL; child = child->siblings_next) { + struct thread *thread = team->thread_list; + + for (; thread != NULL; thread = thread->team_next) { + kernelTime += thread->kernel_time; + userTime += thread->user_time; + } + + kernelTime += child->dead_threads_kernel_time; + userTime += child->dead_threads_user_time; + } + + kernelTime += team->dead_children.kernel_time; + userTime += team->dead_children.user_time; + break; + } + } + +out: + RELEASE_TEAM_LOCK(); + restore_interrupts(state); + + if (status == B_OK) { + info->kernel_time = kernelTime; + info->user_time = userTime; + } + + return status; } diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c index 95b795337d..bbe64a40f0 100644 --- a/src/kernel/core/thread.c +++ b/src/kernel/core/thread.c @@ -809,6 +809,10 @@ thread_exit(void) state = disable_interrupts(); GRAB_TEAM_LOCK(); + // remember how long this thread lasted + team->dead_threads_kernel_time += thread->kernel_time; + team->dead_threads_user_time += thread->user_time; + remove_thread_from_team(team, thread); insert_thread_into_team(team_get_kernel_team(), thread); @@ -832,6 +836,10 @@ thread_exit(void) groupDeadSem = team->group->dead_child_sem; } + // remember how long this team lasted + parent->dead_children.kernel_time += team->dead_threads_kernel_time; + parent->dead_children.user_time += team->dead_threads_user_time; + team_remove_team(team, &freeGroup); } RELEASE_TEAM_LOCK();