From b7a96f02fd5d6ac737c389c9168cda91d7e1376a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 1 Jul 2005 00:31:38 +0000 Subject: [PATCH] Now fills in system_info::cpu_infos[] (ie. CPU activity) by looking at the active time of the idle thread. IOW Pulse now works :-) Renamed the idle thread/stack to start with 1 instead of 0 (first idle thread will be called "idle thread 1"). Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13373 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/thread.h | 3 +- src/system/kernel/scheduler.c | 2 +- src/system/kernel/system_info.c | 5 +++ src/system/kernel/thread.c | 75 +++++++++++++++++++++++---------- src/system/kernel/vm/vm.cpp | 2 +- 5 files changed, 61 insertions(+), 26 deletions(-) diff --git a/headers/private/kernel/thread.h b/headers/private/kernel/thread.h index c1380c911d..4a340eff05 100644 --- a/headers/private/kernel/thread.h +++ b/headers/private/kernel/thread.h @@ -36,9 +36,10 @@ void thread_at_kernel_entry(void); void thread_at_kernel_exit(void); status_t thread_init(struct kernel_args *args); -status_t thread_per_cpu_init(int32 cpu_num); +status_t thread_per_cpu_init(int32 cpuNum); void thread_exit(void); +bigtime_t thread_get_active_cpu_time(int32 cpuNum); int32 thread_max_threads(void); int32 thread_used_threads(void); diff --git a/src/system/kernel/scheduler.c b/src/system/kernel/scheduler.c index 43ee19d58b..16b1bccd67 100644 --- a/src/system/kernel/scheduler.c +++ b/src/system/kernel/scheduler.c @@ -128,7 +128,7 @@ scheduler_remove_from_run_queue(struct thread *thread) static void context_switch(struct thread *fromThread, struct thread *toThread) { - // track kernel & user time + // track kernel time (user time is tracked in thread_at_kernel_entry()) bigtime_t now = system_time(); fromThread->kernel_time += now - fromThread->last_time; toThread->last_time = now; diff --git a/src/system/kernel/system_info.c b/src/system/kernel/system_info.c index 5c15721cf3..ecab23bb70 100644 --- a/src/system/kernel/system_info.c +++ b/src/system/kernel/system_info.c @@ -30,6 +30,8 @@ const static char kKernelName[] = "kernel_" OBOS_ARCH; status_t _get_system_info(system_info *info, size_t size) { + int32 i; + if (size != sizeof(system_info)) return B_BAD_VALUE; @@ -38,6 +40,9 @@ _get_system_info(system_info *info, size_t size) info->boot_time = rtc_boot_time(); info->cpu_count = smp_get_num_cpus(); + for (i = 0; i < info->cpu_count; i++) + info->cpu_infos[i].active_time = thread_get_active_cpu_time(i); + // ToDo: Add page_faults info->max_pages = vm_page_num_pages(); info->used_pages = vm_page_num_pages() - vm_page_num_free_pages(); diff --git a/src/system/kernel/thread.c b/src/system/kernel/thread.c index b28940cfe3..20042f58aa 100644 --- a/src/system/kernel/thread.c +++ b/src/system/kernel/thread.c @@ -1184,6 +1184,32 @@ spawn_kernel_thread_etc(thread_func function, const char *name, int32 priority, } +bigtime_t +thread_get_active_cpu_time(int32 cpuNum) +{ + bigtime_t activeTime; + cpu_status state; + + if (cpuNum < 0 || cpuNum > B_MAX_CPU_COUNT || sIdleThreads[cpuNum] == NULL) + return 0; + + activeTime = system_time(); + + // we need to grab the thread lock here, because the thread activity + // time is not maintained atomically (because there is no need to) + + state = disable_interrupts(); + GRAB_THREAD_LOCK(); + + activeTime -= sIdleThreads[cpuNum]->kernel_time; + + RELEASE_THREAD_LOCK(); + restore_interrupts(state); + + return activeTime; +} + + int32 thread_max_threads(void) { @@ -1201,8 +1227,7 @@ thread_used_threads(void) status_t thread_init(kernel_args *args) { - struct thread *t; - unsigned int i; + uint32 i; TRACE(("thread_init: entry\n")); @@ -1229,34 +1254,38 @@ thread_init(kernel_args *args) // create an idle thread for each cpu for (i = 0; i < args->num_cpus; i++) { + struct thread *thread; area_info info; - char temp[64]; + char name[64]; - sprintf(temp, "idle thread %d", i); - t = create_thread_struct(temp, + sprintf(name, "idle thread %lu", i + 1); + thread = create_thread_struct(name, i == 0 ? team_get_kernel_team_id() : -1); - if (t == NULL) { + if (thread == NULL) { panic("error creating idle thread struct\n"); - return ENOMEM; + return B_NO_MEMORY; } - t->team = team_get_kernel_team(); - t->priority = B_IDLE_PRIORITY; - t->state = B_THREAD_RUNNING; - t->next_state = B_THREAD_READY; - sprintf(temp, "idle thread %d kstack", i); - t->kernel_stack_area = find_area(temp); - if (get_area_info(t->kernel_stack_area, &info) != B_OK) + thread->team = team_get_kernel_team(); + thread->priority = B_IDLE_PRIORITY; + thread->state = B_THREAD_RUNNING; + thread->next_state = B_THREAD_READY; + sprintf(name, "idle thread %lu kstack", i + 1); + thread->kernel_stack_area = find_area(name); + + if (get_area_info(thread->kernel_stack_area, &info) != B_OK) panic("error finding idle kstack area\n"); - t->kernel_stack_base = (addr_t)info.address; + thread->kernel_stack_base = (addr_t)info.address; + + hash_insert(sThreadHash, thread); + insert_thread_into_team(thread->team, thread); + sIdleThreads[i] = thread; - hash_insert(sThreadHash, t); - insert_thread_into_team(t->team, t); - sIdleThreads[i] = t; if (i == 0) - arch_thread_set_current_thread(t); - t->cpu = &cpu[i]; + arch_thread_set_current_thread(thread); + + thread->cpu = &cpu[i]; } sUsedThreads = args->num_cpus; @@ -1277,7 +1306,7 @@ thread_init(kernel_args *args) char temp[64]; for (i = 0; i < sNumDeathStacks; i++) { - sprintf(temp, "death_stack%d", i); + sprintf(temp, "death stack %lu", i); sDeathStacks[i].area = create_area(temp, (void **)&sDeathStacks[i].address, B_ANY_KERNEL_ADDRESS, KERNEL_STACK_SIZE, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_KERNEL_STACK_AREA); @@ -1302,9 +1331,9 @@ thread_init(kernel_args *args) status_t -thread_per_cpu_init(int32 cpu_num) +thread_per_cpu_init(int32 cpuNum) { - arch_thread_set_current_thread(sIdleThreads[cpu_num]); + arch_thread_set_current_thread(sIdleThreads[cpuNum]); return B_OK; } diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 19c5a2b487..f51d6ab063 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -2178,7 +2178,7 @@ vm_init(kernel_args *args) for (i = 0; i < args->num_cpus; i++) { char name[64]; - sprintf(name, "idle thread %lu kstack", i); + sprintf(name, "idle thread %lu kstack", i + 1); address = (void *)args->cpu_kstack[i].start; create_area(name, &address, B_EXACT_ADDRESS, args->cpu_kstack[i].size, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);