Changeset dec16a2 in mainline
- Timestamp:
- 2010-04-18T16:52:47Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5c45ca8
- Parents:
- e535eeb
- Files:
-
- 2 deleted
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/Makefile.common
re535eeb rdec16a2 94 94 $(USPACEDIR)/app/ping/ping \ 95 95 $(USPACEDIR)/app/stats/stats \ 96 $(USPACEDIR)/app/tasks/tasks 97 # $(USPACEDIR)/app/top/top \ 96 $(USPACEDIR)/app/tasks/tasks \ 97 $(USPACEDIR)/app/top/top 98 98 # $(USPACEDIR)/app/dummy_load/dummy_load 99 99 -
kernel/generic/include/sysinfo/abi.h
re535eeb rdec16a2 99 99 */ 100 100 typedef struct { 101 task_id_t task_id; /**< Task ID */ 101 102 char name[TASK_NAME_BUFLEN]; /**< Task name (in kernel) */ 102 103 size_t virtmem; /**< Size of VAS (bytes) */ … … 111 112 */ 112 113 typedef struct { 113 task_id_t task_id; 114 state_t state; 115 int priority; 116 uint64_t ucycles; 117 uint64_t kcycles; 118 bool on_cpu; 119 unsigned int cpu; 114 thread_id_t thread_id; /**< Thread ID */ 115 task_id_t task_id; /**< Associated task ID */ 116 state_t state; /**< Thread state */ 117 int priority; /**< Thread priority */ 118 uint64_t ucycles; /**< Number of CPU cycles in user space */ 119 uint64_t kcycles; /**< Number of CPU cycles in kernel */ 120 bool on_cpu; /**< Associated with a CPU */ 121 unsigned int cpu; /**< Associated CPU ID (if on_cpu is true) */ 120 122 } stats_thread_t; 121 123 -
kernel/generic/src/sysinfo/stats.c
re535eeb rdec16a2 146 146 } 147 147 148 /** Gather tasks149 *150 * AVL task tree walker for gathering task IDs. Interrupts should151 * be already disabled while walking the tree.152 *153 * @param node AVL task tree node.154 * @param arg Pointer to the iterator into the array of task IDs.155 *156 * @param Always true (continue the walk).157 *158 */159 static bool task_serialize_walker(avltree_node_t *node, void *arg)160 {161 task_id_t **ids = (task_id_t **) arg;162 task_t *task = avltree_get_instance(node, task_t, tasks_tree_node);163 164 /* Interrupts are already disabled */165 spinlock_lock(&(task->lock));166 167 /* Record the ID and increment the iterator */168 **ids = task->taskid;169 (*ids)++;170 171 spinlock_unlock(&(task->lock));172 173 return true;174 }175 176 /** Get task IDs177 *178 * @param item Sysinfo item (unused).179 * @param size Size of the returned data.180 * @param dry_run Do not get the data, just calculate the size.181 *182 * @return Data containing task IDs of all tasks.183 * If the return value is not NULL, it should be freed184 * in the context of the sysinfo request.185 */186 static void *get_stats_tasks(struct sysinfo_item *item, size_t *size,187 bool dry_run)188 {189 /* Messing with task structures, avoid deadlock */190 ipl_t ipl = interrupts_disable();191 spinlock_lock(&tasks_lock);192 193 /* First walk the task tree to count the tasks */194 size_t count = 0;195 avltree_walk(&tasks_tree, avl_count_walker, (void *) &count);196 197 if (count == 0) {198 /* No tasks found (strange) */199 spinlock_unlock(&tasks_lock);200 interrupts_restore(ipl);201 202 *size = 0;203 return NULL;204 }205 206 *size = sizeof(task_id_t) * count;207 if (dry_run) {208 spinlock_unlock(&tasks_lock);209 interrupts_restore(ipl);210 return NULL;211 }212 213 task_id_t *task_ids = (task_id_t *) malloc(*size, FRAME_ATOMIC);214 if (task_ids == NULL) {215 /* No free space for allocation */216 spinlock_unlock(&tasks_lock);217 interrupts_restore(ipl);218 219 *size = 0;220 return NULL;221 }222 223 /* Walk tha task tree again to gather the IDs */224 task_id_t *iterator = task_ids;225 avltree_walk(&tasks_tree, task_serialize_walker, (void *) &iterator);226 227 spinlock_unlock(&tasks_lock);228 interrupts_restore(ipl);229 230 return ((void *) task_ids);231 }232 233 /** Gather threads234 *235 * AVL three tree walker for gathering thread IDs. Interrupts should236 * be already disabled while walking the tree.237 *238 * @param node AVL thread tree node.239 * @param arg Pointer to the iterator into the array of thread IDs.240 *241 * @param Always true (continue the walk).242 *243 */244 static bool thread_serialize_walker(avltree_node_t *node, void *arg)245 {246 thread_id_t **ids = (thread_id_t **) arg;247 thread_t *thread = avltree_get_instance(node, thread_t, threads_tree_node);248 249 /* Interrupts are already disabled */250 spinlock_lock(&(thread->lock));251 252 /* Record the ID and increment the iterator */253 **ids = thread->tid;254 (*ids)++;255 256 spinlock_unlock(&(thread->lock));257 258 return true;259 }260 261 /** Get thread IDs262 *263 * @param item Sysinfo item (unused).264 * @param size Size of the returned data.265 * @param dry_run Do not get the data, just calculate the size.266 *267 * @return Data containing thread IDs of all threads.268 * If the return value is not NULL, it should be freed269 * in the context of the sysinfo request.270 */271 static void *get_stats_threads(struct sysinfo_item *item, size_t *size,272 bool dry_run)273 {274 /* Messing with threads structures, avoid deadlock */275 ipl_t ipl = interrupts_disable();276 spinlock_lock(&threads_lock);277 278 /* First walk the thread tree to count the threads */279 size_t count = 0;280 avltree_walk(&threads_tree, avl_count_walker, (void *) &count);281 282 if (count == 0) {283 /* No threads found (strange) */284 spinlock_unlock(&threads_lock);285 interrupts_restore(ipl);286 287 *size = 0;288 return NULL;289 }290 291 *size = sizeof(thread_id_t) * count;292 if (dry_run) {293 spinlock_unlock(&threads_lock);294 interrupts_restore(ipl);295 return NULL;296 }297 298 thread_id_t *thread_ids = (thread_id_t *) malloc(*size, FRAME_ATOMIC);299 if (thread_ids == NULL) {300 /* No free space for allocation */301 spinlock_unlock(&threads_lock);302 interrupts_restore(ipl);303 304 *size = 0;305 return NULL;306 }307 308 /* Walk tha thread tree again to gather the IDs */309 thread_id_t *iterator = thread_ids;310 avltree_walk(&threads_tree, thread_serialize_walker, (void *) &iterator);311 312 spinlock_unlock(&threads_lock);313 interrupts_restore(ipl);314 315 return ((void *) thread_ids);316 }317 318 148 /** Get the size of a virtual address space 319 149 * … … 351 181 } 352 182 183 /* Produce task statistics 184 * 185 * Summarize task information into task statistics. 186 * Task lock should be held and interrupts disabled 187 * before executing this function. 188 * 189 * @param task Task. 190 * @param stats_task Task statistics. 191 * 192 */ 193 static void produce_stats_task(task_t *task, stats_task_t *stats_task) 194 { 195 stats_task->task_id = task->taskid; 196 str_cpy(stats_task->name, TASK_NAME_BUFLEN, task->name); 197 stats_task->virtmem = get_task_virtmem(task->as); 198 stats_task->threads = atomic_get(&task->refcount); 199 task_get_accounting(task, &(stats_task->ucycles), 200 &(stats_task->kcycles)); 201 stats_task->ipc_info = task->ipc_info; 202 } 203 204 /** Gather statistics of all tasks 205 * 206 * AVL task tree walker for gathering task statistics. Interrupts should 207 * be already disabled while walking the tree. 208 * 209 * @param node AVL task tree node. 210 * @param arg Pointer to the iterator into the array of stats_task_t. 211 * 212 * @param Always true (continue the walk). 213 * 214 */ 215 static bool task_serialize_walker(avltree_node_t *node, void *arg) 216 { 217 stats_task_t **iterator = (stats_task_t **) arg; 218 task_t *task = avltree_get_instance(node, task_t, tasks_tree_node); 219 220 /* Interrupts are already disabled */ 221 spinlock_lock(&(task->lock)); 222 223 /* Record the statistics and increment the iterator */ 224 produce_stats_task(task, *iterator); 225 (*iterator)++; 226 227 spinlock_unlock(&(task->lock)); 228 229 return true; 230 } 231 353 232 /** Get task statistics 233 * 234 * @param item Sysinfo item (unused). 235 * @param size Size of the returned data. 236 * @param dry_run Do not get the data, just calculate the size. 237 * 238 * @return Data containing several stats_task_t structures. 239 * If the return value is not NULL, it should be freed 240 * in the context of the sysinfo request. 241 */ 242 static void *get_stats_tasks(struct sysinfo_item *item, size_t *size, 243 bool dry_run) 244 { 245 /* Messing with task structures, avoid deadlock */ 246 ipl_t ipl = interrupts_disable(); 247 spinlock_lock(&tasks_lock); 248 249 /* First walk the task tree to count the tasks */ 250 size_t count = 0; 251 avltree_walk(&tasks_tree, avl_count_walker, (void *) &count); 252 253 if (count == 0) { 254 /* No tasks found (strange) */ 255 spinlock_unlock(&tasks_lock); 256 interrupts_restore(ipl); 257 258 *size = 0; 259 return NULL; 260 } 261 262 *size = sizeof(stats_task_t) * count; 263 if (dry_run) { 264 spinlock_unlock(&tasks_lock); 265 interrupts_restore(ipl); 266 return NULL; 267 } 268 269 stats_task_t *stats_tasks = (stats_task_t *) malloc(*size, FRAME_ATOMIC); 270 if (stats_tasks == NULL) { 271 /* No free space for allocation */ 272 spinlock_unlock(&tasks_lock); 273 interrupts_restore(ipl); 274 275 *size = 0; 276 return NULL; 277 } 278 279 /* Walk tha task tree again to gather the statistics */ 280 stats_task_t *iterator = stats_tasks; 281 avltree_walk(&tasks_tree, task_serialize_walker, (void *) &iterator); 282 283 spinlock_unlock(&tasks_lock); 284 interrupts_restore(ipl); 285 286 return ((void *) stats_tasks); 287 } 288 289 /* Produce thread statistics 290 * 291 * Summarize thread information into thread statistics. 292 * Thread lock should be held and interrupts disabled 293 * before executing this function. 294 * 295 * @param thread Thread. 296 * @param stats_thread Thread statistics. 297 * 298 */ 299 static void produce_stats_thread(thread_t *thread, stats_thread_t *stats_thread) 300 { 301 stats_thread->thread_id = thread->tid; 302 stats_thread->task_id = thread->task->taskid; 303 stats_thread->state = thread->state; 304 stats_thread->priority = thread->priority; 305 stats_thread->ucycles = thread->ucycles; 306 stats_thread->kcycles = thread->kcycles; 307 308 if (thread->cpu != NULL) { 309 stats_thread->on_cpu = true; 310 stats_thread->cpu = thread->cpu->id; 311 } else 312 stats_thread->on_cpu = false; 313 } 314 315 /** Gather statistics of all threads 316 * 317 * AVL three tree walker for gathering thread statistics. Interrupts should 318 * be already disabled while walking the tree. 319 * 320 * @param node AVL thread tree node. 321 * @param arg Pointer to the iterator into the array of thread statistics. 322 * 323 * @param Always true (continue the walk). 324 * 325 */ 326 static bool thread_serialize_walker(avltree_node_t *node, void *arg) 327 { 328 stats_thread_t **iterator = (stats_thread_t **) arg; 329 thread_t *thread = avltree_get_instance(node, thread_t, threads_tree_node); 330 331 /* Interrupts are already disabled */ 332 spinlock_lock(&(thread->lock)); 333 334 /* Record the statistics and increment the iterator */ 335 produce_stats_thread(thread, *iterator); 336 (*iterator)++; 337 338 spinlock_unlock(&(thread->lock)); 339 340 return true; 341 } 342 343 /** Get thread statistics 344 * 345 * @param item Sysinfo item (unused). 346 * @param size Size of the returned data. 347 * @param dry_run Do not get the data, just calculate the size. 348 * 349 * @return Data containing several stats_task_t structures. 350 * If the return value is not NULL, it should be freed 351 * in the context of the sysinfo request. 352 */ 353 static void *get_stats_threads(struct sysinfo_item *item, size_t *size, 354 bool dry_run) 355 { 356 /* Messing with threads structures, avoid deadlock */ 357 ipl_t ipl = interrupts_disable(); 358 spinlock_lock(&threads_lock); 359 360 /* First walk the thread tree to count the threads */ 361 size_t count = 0; 362 avltree_walk(&threads_tree, avl_count_walker, (void *) &count); 363 364 if (count == 0) { 365 /* No threads found (strange) */ 366 spinlock_unlock(&threads_lock); 367 interrupts_restore(ipl); 368 369 *size = 0; 370 return NULL; 371 } 372 373 *size = sizeof(stats_thread_t) * count; 374 if (dry_run) { 375 spinlock_unlock(&threads_lock); 376 interrupts_restore(ipl); 377 return NULL; 378 } 379 380 stats_thread_t *stats_threads = (stats_thread_t *) malloc(*size, FRAME_ATOMIC); 381 if (stats_threads == NULL) { 382 /* No free space for allocation */ 383 spinlock_unlock(&threads_lock); 384 interrupts_restore(ipl); 385 386 *size = 0; 387 return NULL; 388 } 389 390 /* Walk tha thread tree again to gather the statistics */ 391 stats_thread_t *iterator = stats_threads; 392 avltree_walk(&threads_tree, thread_serialize_walker, (void *) &iterator); 393 394 spinlock_unlock(&threads_lock); 395 interrupts_restore(ipl); 396 397 return ((void *) stats_threads); 398 } 399 400 /** Get a single task statistics 354 401 * 355 402 * Get statistics of a given task. The task ID is passed … … 416 463 spinlock_unlock(&tasks_lock); 417 464 418 /* Copy task's statistics */ 419 str_cpy(stats_task->name, TASK_NAME_BUFLEN, task->name); 420 stats_task->virtmem = get_task_virtmem(task->as); 421 stats_task->threads = atomic_get(&task->refcount); 422 task_get_accounting(task, &(stats_task->ucycles), 423 &(stats_task->kcycles)); 424 stats_task->ipc_info = task->ipc_info; 465 produce_stats_task(task, stats_task); 425 466 426 467 spinlock_unlock(&task->lock); … … 492 533 ret.data.data = (void *) stats_thread; 493 534 ret.data.size = sizeof(stats_thread_t); 494 535 495 536 /* Hand-over-hand locking */ 496 537 spinlock_lock(&thread->lock); 497 538 spinlock_unlock(&threads_lock); 498 539 499 /* Copy thread's statistics */ 500 stats_thread->task_id = thread->task->taskid; 501 stats_thread->state = thread->state; 502 stats_thread->priority = thread->priority; 503 stats_thread->ucycles = thread->ucycles; 504 stats_thread->kcycles = thread->kcycles; 505 506 if (thread->cpu != NULL) { 507 stats_thread->on_cpu = true; 508 stats_thread->cpu = thread->cpu->id; 509 } else 510 stats_thread->on_cpu = false; 540 produce_stats_thread(thread, stats_thread); 511 541 512 542 spinlock_unlock(&thread->lock); -
uspace/app/tasks/tasks.c
re535eeb rdec16a2 59 59 { 60 60 size_t count; 61 task_id_t *ids = 62 (task_id_t *) stats_get_tasks(&count); 63 64 if (ids == NULL) { 61 stats_task_t *stats_tasks = stats_get_tasks(&count); 62 63 if (stats_tasks == NULL) { 65 64 fprintf(stderr, "%s: Unable to get tasks\n", NAME); 66 65 return; … … 71 70 size_t i; 72 71 for (i = 0; i < count; i++) { 73 stats_task_t *stats_task = stats_get_task(ids[i]); 74 if (stats_task != NULL) { 75 uint64_t virtmem, ucycles, kcycles; 76 char vmsuffix, usuffix, ksuffix; 77 78 order_suffix(stats_task->virtmem, &virtmem, &vmsuffix); 79 order_suffix(stats_task->ucycles, &ucycles, &usuffix); 80 order_suffix(stats_task->kcycles, &kcycles, &ksuffix); 81 82 printf("%8" PRIu64 "%8u %8" PRIu64"%c %12" 83 PRIu64 "%c %12" PRIu64 "%c %s\n", ids[i], stats_task->threads, 84 virtmem, vmsuffix, ucycles, usuffix, kcycles, ksuffix, 85 stats_task->name); 86 87 free(stats_task); 88 } else 89 printf("%8" PRIu64 "\n", ids[i]); 90 } 91 92 free(ids); 72 uint64_t virtmem, ucycles, kcycles; 73 char vmsuffix, usuffix, ksuffix; 74 75 order_suffix(stats_tasks[i].virtmem, &virtmem, &vmsuffix); 76 order_suffix(stats_tasks[i].ucycles, &ucycles, &usuffix); 77 order_suffix(stats_tasks[i].kcycles, &kcycles, &ksuffix); 78 79 printf("%8" PRIu64 "%8u %8" PRIu64"%c %12" 80 PRIu64 "%c %12" PRIu64 "%c %s\n", stats_tasks[i].task_id, 81 stats_tasks[i].threads, virtmem, vmsuffix, ucycles, usuffix, 82 kcycles, ksuffix, stats_tasks[i].name); 83 } 84 85 free(stats_tasks); 93 86 } 94 87 … … 96 89 { 97 90 size_t count; 98 thread_id_t *ids = 99 (thread_id_t *) stats_get_threads(&count); 100 101 if (ids == NULL) { 91 stats_thread_t *stats_threads = stats_get_threads(&count); 92 93 if (stats_threads == NULL) { 102 94 fprintf(stderr, "%s: Unable to get threads\n", NAME); 103 95 return; … … 107 99 size_t i; 108 100 for (i = 0; i < count; i++) { 109 stats_thread_t *stats_thread = stats_get_thread(ids[i]); 110 if (stats_thread != NULL) { 111 if ((all) || (stats_thread->task_id == task_id)) { 112 uint64_t ucycles, kcycles; 113 char usuffix, ksuffix; 114 115 order_suffix(stats_thread->ucycles, &ucycles, &usuffix); 116 order_suffix(stats_thread->kcycles, &kcycles, &ksuffix); 117 118 if (stats_thread->on_cpu) { 119 printf("%8" PRIu64 " %-8s %4u %6d %12" 120 PRIu64"%c %12" PRIu64"%c\n", ids[i], 121 thread_get_state(stats_thread->state), 122 stats_thread->cpu, stats_thread->priority, 123 ucycles, usuffix, kcycles, ksuffix); 124 } else { 125 printf("%8" PRIu64 " %-8s ---- %6d %12" 126 PRIu64"%c %12" PRIu64"%c\n", ids[i], 127 thread_get_state(stats_thread->state), 128 stats_thread->priority, 129 ucycles, usuffix, kcycles, ksuffix); 130 } 101 if ((all) || (stats_threads[i].task_id == task_id)) { 102 uint64_t ucycles, kcycles; 103 char usuffix, ksuffix; 104 105 order_suffix(stats_threads[i].ucycles, &ucycles, &usuffix); 106 order_suffix(stats_threads[i].kcycles, &kcycles, &ksuffix); 107 108 if (stats_threads[i].on_cpu) { 109 printf("%8" PRIu64 " %-8s %4u %6d %12" 110 PRIu64"%c %12" PRIu64"%c\n", stats_threads[i].thread_id, 111 thread_get_state(stats_threads[i].state), 112 stats_threads[i].cpu, stats_threads[i].priority, 113 ucycles, usuffix, kcycles, ksuffix); 114 } else { 115 printf("%8" PRIu64 " %-8s ---- %6d %12" 116 PRIu64"%c %12" PRIu64"%c\n", stats_threads[i].thread_id, 117 thread_get_state(stats_threads[i].state), 118 stats_threads[i].priority, 119 ucycles, usuffix, kcycles, ksuffix); 131 120 } 132 133 free(stats_thread); 134 } else if (all) 135 printf("%8" PRIu64 "\n", ids[i]); 136 } 137 138 free(ids); 121 } 122 } 123 124 free(stats_threads); 139 125 } 140 126 -
uspace/app/top/Makefile
re535eeb rdec16a2 29 29 30 30 USPACE_PREFIX = ../.. 31 #BINARY = top31 BINARY = top 32 32 33 33 SOURCES = \ 34 34 top.c \ 35 35 screen.c \ 36 input.c \ 37 ps.c 36 input.c 38 37 39 38 include $(USPACE_PREFIX)/Makefile.common -
uspace/app/top/screen.c
re535eeb rdec16a2 1 1 /* 2 2 * Copyright (c) 2010 Stanislav Kozina 3 * Copyright (c) 2010 Martin Decky 3 4 * All rights reserved. 4 5 * … … 38 39 #include <io/console.h> 39 40 #include <vfs/vfs.h> 40 #include < load.h>41 #include < kernel/ps/taskinfo.h>42 #include < ps.h>41 #include <stdarg.h> 42 #include <stats.h> 43 #include <inttypes.h> 43 44 #include "screen.h" 44 45 #include "top.h" 45 #include "func.h" 46 47 int rows; 48 int colls; 49 int up_rows;50 51 #define WHITE 0xf0f0f0 52 #define BLACK 0x000000 53 54 static void print_float(ps_float f, int precision) 55 { 56 printf("%2u.", f.upper / f.lower);57 int i;58 u nsigned int rest = (f.upper % f.lower) * 10;59 for (i = 0; i < precision; ++i) {60 printf("% d", rest / f.lower);61 rest = (rest % f .lower) * 10;62 } 63 } 64 65 static void resume_normal(void)46 47 #define WHITE 0xf0f0f0 48 #define BLACK 0x000000 49 50 static int rows; 51 static int colls; 52 static int up_rows; 53 54 static void print_float(fixed_float ffloat, unsigned int precision) 55 { 56 printf("%2" PRIu64 ".", ffloat.upper / ffloat.lower); 57 58 unsigned int i; 59 uint64_t rest = (ffloat.upper % ffloat.lower) * 10; 60 for (i = 0; i < precision; i++) { 61 printf("%" PRIu64, rest / ffloat.lower); 62 rest = (rest % ffloat.lower) * 10; 63 } 64 } 65 66 static void screen_resume_normal(void) 66 67 { 67 68 fflush(stdout); … … 69 70 } 70 71 72 static void screen_moveto(int r, int c) 73 { 74 fflush(stdout); 75 console_goto(fphone(stdout), c, r); 76 } 77 78 static void screen_clear(void) 79 { 80 console_clear(fphone(stdout)); 81 screen_moveto(0, 0); 82 up_rows = 0; 83 fflush(stdout); 84 } 85 71 86 void screen_init(void) 72 87 { 88 console_cursor_visibility(fphone(stdout), 0); 89 screen_resume_normal(); 90 screen_clear(); 91 73 92 console_get_size(fphone(stdout), &colls, &rows); 74 up_rows = 0; 75 console_cursor_visibility(fphone(stdout), 0); 76 resume_normal(); 77 clear_screen(); 78 } 79 80 void clear_screen(void) 81 { 82 console_clear(fphone(stdout)); 83 moveto(0, 0); 84 up_rows = 0; 85 fflush(stdout); 86 } 87 88 void moveto(int r, int c) 89 { 90 fflush(stdout); 91 console_goto(fphone(stdout), c, r); 93 } 94 95 void screen_done(void) 96 { 97 screen_resume_normal(); 98 screen_clear(); 99 console_cursor_visibility(fphone(stdout), 1); 92 100 } 93 101 94 102 static inline void print_time(data_t *data) 95 103 { 96 printf("%02 d:%02d:%02d", data->hours, data->minutes, data->seconds);104 printf("%02lu:%02lu:%02lu ", data->hours, data->minutes, data->seconds); 97 105 } 98 106 99 107 static inline void print_uptime(data_t *data) 100 108 { 101 printf("up % 4d days, %02d:%02d:%02d, ", data->uptime_d, data->uptime_h,102 data->uptime_m, data->uptime_s);109 printf("up %u days, %02u:%02u:%02u, ", data->udays, data->uhours, 110 data->uminutes, data->useconds); 103 111 } 104 112 105 113 static inline void print_load(data_t *data) 106 114 { 107 puts("load avarage: "); 108 print_load_fragment(data->load[0], 2); 109 puts(" "); 110 print_load_fragment(data->load[1], 2); 111 puts(" "); 112 print_load_fragment(data->load[2], 2); 113 } 114 115 static inline void print_taskstat(data_t *data) 116 { 117 puts("Tasks: "); 118 printf("%4u total", data->task_count); 119 } 120 121 static inline void print_threadstat(data_t *data) 122 { 115 printf("load avarage: "); 116 117 size_t i; 118 for (i = 0; i < data->load_count; i++) { 119 stats_print_load_fragment(data->load[i], 2); 120 printf(" "); 121 } 122 } 123 124 static inline void print_task_summary(data_t *data) 125 { 126 printf("tasks: %u total", data->tasks_count); 127 } 128 129 static inline void print_thread_summary(data_t *data) 130 { 131 size_t total = 0; 132 size_t running = 0; 133 size_t ready = 0; 123 134 size_t sleeping = 0; 124 size_t running = 0; 135 size_t lingering = 0; 136 size_t other = 0; 125 137 size_t invalid = 0; 126 size_t other = 0; 127 size_t total = 0; 128 size_t i; 129 for (i = 0; i < data->thread_count; ++i) { 130 ++total; 131 switch (data->thread_infos[i].state) { 132 case Invalid: 133 case Lingering: 134 ++invalid; 135 break; 136 case Running: 137 case Ready: 138 ++running; 139 break; 140 case Sleeping: 141 ++sleeping; 142 break; 143 case Entering: 144 case Exiting: 145 ++other; 146 break; 138 139 140 size_t i; 141 for (i = 0; i < data->threads_count; i++) { 142 total++; 143 144 switch (data->threads[i].state) { 145 case Running: 146 running++; 147 break; 148 case Ready: 149 ready++; 150 break; 151 case Sleeping: 152 sleeping++; 153 break; 154 case Lingering: 155 lingering++; 156 break; 157 case Entering: 158 case Exiting: 159 other++; 160 break; 161 default: 162 invalid++; 147 163 } 148 164 } 149 printf("Threads: %5u total, %5u running, %5u sleeping, %5u invalid, %5u other", 150 total, running, sleeping, invalid, other); 151 } 152 153 static inline void print_cpuinfo(data_t *data) 154 { 155 unsigned int i; 156 uspace_cpu_info_t *cpus = data->cpus; 157 for (i = 0; i < data->cpu_count; ++i) { 158 printf("Cpu%u (%4u Mhz): Busy ticks: %6llu, Idle Ticks: %6llu", 159 i, (unsigned int)cpus[i].frequency_mhz, cpus[i].busy_ticks, 160 cpus[i].idle_ticks); 165 166 printf("threads: %u total, %u running, %u ready, %u sleeping, %u lingering, " 167 "%u other, %u invalid", 168 total, running, ready, sleeping, lingering, other, invalid); 169 } 170 171 static inline void print_cpu_info(data_t *data) 172 { 173 size_t i; 174 for (i = 0; i < data->cpus_count; i++) { 175 printf("cpu%u (%4" PRIu16 " MHz): busy ticks: " 176 "%" PRIu64 ", idle ticks: %" PRIu64, 177 data->cpus[i].id, data->cpus[i].frequency_mhz, 178 data->cpus[i].busy_ticks, data->cpus[i].idle_ticks); 161 179 printf(", idle: "); 162 print_float(data->cpu_perc[i].idle, 2); 163 puts("%, busy: "); 164 print_float(data->cpu_perc[i].busy, 2); 165 puts("%\n"); 166 ++up_rows; 167 } 168 } 169 170 static inline void print_meminfo(data_t *data) 171 { 172 uint64_t newsize; 173 char suffix; 174 order(data->mem_info.total, &newsize, &suffix); 175 printf("Mem: %8llu %c total", newsize, suffix); 176 order(data->mem_info.used, &newsize, &suffix); 177 printf(", %8llu %c used", newsize, suffix); 178 order(data->mem_info.free, &newsize, &suffix); 179 printf(", %8llu %c free", newsize, suffix); 180 print_float(data->cpus_perc[i].idle, 2); 181 printf("%%, busy: "); 182 print_float(data->cpus_perc[i].busy, 2); 183 184 printf("%%\n"); 185 up_rows++; 186 } 187 } 188 189 static inline void print_physmem_info(data_t *data) 190 { 191 uint64_t total; 192 uint64_t unavail; 193 uint64_t used; 194 uint64_t free; 195 char total_suffix; 196 char unavail_suffix; 197 char used_suffix; 198 char free_suffix; 199 200 order_suffix(data->physmem->total, &total, &total_suffix); 201 order_suffix(data->physmem->unavail, &unavail, &unavail_suffix); 202 order_suffix(data->physmem->used, &used, &used_suffix); 203 order_suffix(data->physmem->free, &free, &free_suffix); 204 205 printf("memory: %" PRIu64 "%c total, %" PRIu64 "%c unavail, %" 206 PRIu64 "%c used, %" PRIu64 "%c free", total, total_suffix, 207 unavail, unavail_suffix, used, used_suffix, free, free_suffix); 180 208 } 181 209 182 210 static inline void print_tasks(data_t *data, int row) 183 211 { 184 int i; 185 for (i = 0; i < (int)data->task_count; ++i) { 186 if (row + i > rows) 187 return; 188 task_info_t *taskinfo = &data->taskinfos[i]; 189 uint64_t mem; 190 char suffix; 191 order(taskinfo->virt_mem, &mem, &suffix); 192 printf("%8llu %8u %8llu%c ", taskinfo->taskid, 193 taskinfo->thread_count, mem, suffix); 194 task_perc_t *taskperc = &data->task_perc[i]; 195 puts(" "); 196 print_float(taskperc->mem, 2); 197 puts("% "); 198 print_float(taskperc->ucycles, 2); 199 puts("% "); 200 print_float(taskperc->kcycles, 2); 201 puts("% "); 202 printf("%s\n", taskinfo->name); 212 size_t i; 213 for (i = 0; i < data->tasks_count; i++, row++) { 214 if (row > rows) 215 break; 216 217 uint64_t virtmem; 218 char virtmem_suffix; 219 order_suffix(data->tasks[i].virtmem, &virtmem, &virtmem_suffix); 220 221 printf("%8" PRIu64 " %8u %8" PRIu64 "%c ", data->tasks[i].task_id, 222 data->tasks[i].threads, virtmem, virtmem_suffix); 223 printf(" "); 224 print_float(data->tasks_perc[i].virtmem, 2); 225 printf("%% "); 226 print_float(data->tasks_perc[i].ucycles, 2); 227 printf("%% "); 228 print_float(data->tasks_perc[i].kcycles, 2); 229 printf("%% %s\n", data->tasks[i].name); 203 230 } 204 231 } … … 208 235 fflush(stdout); 209 236 console_set_rgb_color(fphone(stdout), WHITE, BLACK); 237 210 238 printf(" ID Threads Mem %%Mem %%uCycles %%kCycles Name"); 239 211 240 int i; 212 241 for (i = 61; i < colls; ++i) 213 puts(" "); 242 printf(" "); 243 214 244 fflush(stdout); 215 245 console_set_rgb_color(fphone(stdout), BLACK, WHITE); … … 220 250 fflush(stdout); 221 251 console_set_rgb_color(fphone(stdout), WHITE, BLACK); 252 222 253 printf(" ID Calls sent Calls recv Answs sent Answs recv IRQn recv Forw Name"); 254 223 255 int i; 224 256 for (i = 80; i < colls; ++i) 225 puts(" "); 257 printf(" "); 258 226 259 fflush(stdout); 227 260 console_set_rgb_color(fphone(stdout), BLACK, WHITE); … … 230 263 static inline void print_ipc(data_t *data, int row) 231 264 { 232 int i; 233 for (i = 0; i < (int)data->task_count; ++i) { 234 if (row + i > rows) 235 return; 236 task_info_t *taskinfo = &data->taskinfos[i]; 237 task_ipc_info_t *ipcinfo = &taskinfo->ipc_info; 238 printf("%8llu ", taskinfo->taskid); 239 printf("%10llu %10llu %10llu %10llu %10llu %10llu ", 240 ipcinfo->call_sent, ipcinfo->call_recieved, 241 ipcinfo->answer_sent, ipcinfo->answer_recieved, 242 ipcinfo->irq_notif_recieved, ipcinfo->forwarded); 243 printf("%s\n", taskinfo->name); 265 size_t i; 266 for (i = 0; i < data->tasks_count; i++, row++) { 267 if (row > rows) 268 break; 269 270 printf("%8" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 271 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %s\n", 272 data->tasks[i].task_id, data->tasks[i].ipc_info.call_sent, 273 data->tasks[i].ipc_info.call_recieved, 274 data->tasks[i].ipc_info.answer_sent, 275 data->tasks[i].ipc_info.answer_recieved, 276 data->tasks[i].ipc_info.irq_notif_recieved, 277 data->tasks[i].ipc_info.forwarded, data->tasks[i].name); 244 278 } 245 279 } … … 247 281 void print_data(data_t *data) 248 282 { 249 clear_screen(); 250 fflush(stdout); 283 screen_clear(); 284 fflush(stdout); 285 251 286 printf("top - "); 252 287 print_time(data); 253 288 print_uptime(data); 254 289 print_load(data); 255 puts("\n"); 256 ++up_rows; 257 print_taskstat(data); 258 puts("\n"); 259 ++up_rows; 260 print_threadstat(data); 261 puts("\n"); 262 ++up_rows; 263 print_cpuinfo(data); 264 print_meminfo(data); 265 puts("\n"); 266 ++up_rows; 267 puts("\n"); 268 ++up_rows; 290 291 printf("\n"); 292 up_rows++; 293 294 print_task_summary(data); 295 296 printf("\n"); 297 up_rows++; 298 299 print_thread_summary(data); 300 301 printf("\n"); 302 up_rows++; 303 304 print_cpu_info(data); 305 print_physmem_info(data); 306 307 printf("\n"); 308 up_rows++; 309 310 /* Empty row for warnings */ 311 printf("\n"); 312 269 313 if (operation_type == OP_IPC) { 270 314 print_ipc_head(); 271 p uts("\n");315 printf("\n"); 272 316 print_ipc(data, up_rows); 273 317 } else { 274 318 print_task_head(); 275 p uts("\n");319 printf("\n"); 276 320 print_tasks(data, up_rows); 277 321 } 322 323 fflush(stdout); 324 } 325 326 void print_warning(const char *fmt, ...) 327 { 328 screen_moveto(up_rows, 0); 329 330 va_list args; 331 va_start(args, fmt); 332 vprintf(fmt, args); 333 va_end(args); 334 278 335 fflush(stdout); 279 336 } -
uspace/app/top/screen.h
re535eeb rdec16a2 1 1 /* 2 * Copyright (c) 2008 Stanislav Kozina 2 * Copyright (c) 2010 Stanislav Kozina 3 * Copyright (c) 2010 Martin Decky 3 4 * All rights reserved. 4 5 * … … 36 37 #include "top.h" 37 38 38 extern int rows;39 extern int colls;40 41 39 extern void screen_init(void); 42 extern void clear_screen(void); 43 extern void moveto(int r, int c); 44 extern void print_data(data_t *data); 45 46 extern int up_rows; 47 #define PRINT_WARNING(message, ...) \ 48 do { \ 49 moveto(up_rows - 1, 0); \ 50 printf(message, ##__VA_ARGS__); \ 51 fflush(stdout); \ 52 } while (0) 40 extern void screen_done(void); 41 extern void print_data(data_t *); 42 extern void print_warning(const char *, ...); 53 43 54 44 #endif -
uspace/app/top/top.c
re535eeb rdec16a2 1 1 /* 2 2 * Copyright (c) 2010 Stanislav Kozina 3 * Copyright (c) 2010 Martin Decky 3 4 * All rights reserved. 4 5 * … … 38 39 #include <stdlib.h> 39 40 #include <unistd.h> 40 #include <uptime.h>41 41 #include <task.h> 42 42 #include <thread.h> 43 43 #include <sys/time.h> 44 #include <load.h>45 #include <ps.h>46 44 #include <arch/barrier.h> 45 #include <errno.h> 47 46 #include "screen.h" 48 47 #include "input.h" 49 48 #include "top.h" 50 #include "ps.h" 51 52 #define UPDATE_INTERVAL 1 53 54 #define DAY 86400 55 #define HOUR 3600 56 #define MINUTE 60 49 50 #define NAME "top" 51 52 #define UPDATE_INTERVAL 1 53 54 #define DAY 86400 55 #define HOUR 3600 56 #define MINUTE 60 57 57 58 58 int operation_type; 59 59 60 static voidread_data(data_t *target)60 static const char *read_data(data_t *target) 61 61 { 62 /* Read current time */ 62 /* Initialize data */ 63 target->load = NULL; 64 target->cpus = NULL; 65 target->cpus_perc = NULL; 66 target->tasks = NULL; 67 target->tasks_perc = NULL; 68 target->threads = NULL; 69 target->physmem = NULL; 70 71 /* Get current time */ 63 72 struct timeval time; 64 if (gettimeofday(&time, NULL) != 0) { 65 printf("Cannot get time of day!\n"); 66 exit(1); 67 } 73 if (gettimeofday(&time, NULL) != EOK) 74 return "Cannot get time of day"; 75 68 76 target->hours = (time.tv_sec % DAY) / HOUR; 69 77 target->minutes = (time.tv_sec % HOUR) / MINUTE; 70 78 target->seconds = time.tv_sec % MINUTE; 71 72 /* Read uptime */ 73 uint64_t uptime; 74 get_uptime(&uptime); 75 target->uptime_d = uptime / DAY; 76 target->uptime_h = (uptime % DAY) / HOUR; 77 target->uptime_m = (uptime % HOUR) / MINUTE; 78 target->uptime_s = uptime % MINUTE; 79 80 /* Read load */ 81 get_load(target->load); 82 83 /* Read task ids */ 84 target->task_count = get_tasks(&target->taskinfos); 85 86 /* Read all threads */ 87 target->thread_count = get_threads(&target->thread_infos); 88 89 /* Read cpu infos */ 90 target->cpu_count = get_cpu_infos(&target->cpus); 91 92 /* Read mem info */ 93 get_mem_info(&target->mem_info); 79 80 /* Get uptime */ 81 sysarg_t uptime = stats_get_uptime(); 82 target->udays = uptime / DAY; 83 target->uhours = (uptime % DAY) / HOUR; 84 target->uminutes = (uptime % HOUR) / MINUTE; 85 target->useconds = uptime % MINUTE; 86 87 /* Get load */ 88 target->load = stats_get_load(&(target->load_count)); 89 if (target->load == NULL) 90 return "Cannot get system load"; 91 92 /* Get CPUs */ 93 target->cpus = stats_get_cpus(&(target->cpus_count)); 94 if (target->cpus == NULL) 95 return "Cannot get CPUs"; 96 97 target->cpus_perc = 98 (perc_cpu_t *) calloc(target->cpus_count, sizeof(perc_cpu_t)); 99 if (target->cpus_perc == NULL) 100 return "Not enough memory for CPU utilization"; 101 102 /* Get tasks */ 103 target->tasks = stats_get_tasks(&(target->tasks_count)); 104 if (target->tasks == NULL) 105 return "Cannot get tasks"; 106 107 target->tasks_perc = 108 (perc_task_t *) calloc(target->tasks_count, sizeof(perc_task_t)); 109 if (target->tasks_perc == NULL) 110 return "Not enough memory for task utilization"; 111 112 /* Get threads */ 113 target->threads = stats_get_threads(&(target->threads_count)); 114 if (target->threads == NULL) 115 return "Cannot get threads"; 116 117 /* Get physical memory */ 118 target->physmem = stats_get_physmem(); 119 if (target->physmem == NULL) 120 return "Cannot get physical memory"; 121 122 return NULL; 94 123 } 95 124 96 125 /** Computes percentage differencies from old_data to new_data 97 126 * 98 * @param old_data 99 * @param new_data 100 * 101 */ 102 static voidcompute_percentages(data_t *old_data, data_t *new_data)127 * @param old_data Pointer to old data strucutre. 128 * @param new_data Pointer to actual data where percetages are stored. 129 * 130 */ 131 static const char *compute_percentages(data_t *old_data, data_t *new_data) 103 132 { 104 /* Foreach cpu, compute total ticks and divide it between user and 105 * system */ 106 unsigned int i; 107 new_data->cpu_perc = malloc(new_data->cpu_count * sizeof(cpu_perc_t)); 108 for (i = 0; i < new_data->cpu_count; ++i) { 109 uint64_t idle = new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks; 110 uint64_t busy = new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks; 133 /* Allocate memory */ 134 135 uint64_t *ucycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t)); 136 if (ucycles_diff == NULL) 137 return "Not enough memory for user utilization"; 138 139 uint64_t *kcycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t)); 140 if (kcycles_diff == NULL) { 141 free(ucycles_diff); 142 return "Not enough memory for kernel utilization"; 143 } 144 145 /* For each CPU: Compute total ticks and divide it between 146 user and kernel */ 147 148 size_t i; 149 for (i = 0; i < new_data->cpus_count; i++) { 150 uint64_t idle = 151 new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks; 152 uint64_t busy = 153 new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks; 111 154 uint64_t sum = idle + busy; 112 FRACTION_TO_FLOAT(new_data->cpu_perc[i].idle, idle * 100, sum); 113 FRACTION_TO_FLOAT(new_data->cpu_perc[i].busy, busy * 100, sum); 114 } 115 155 156 FRACTION_TO_FLOAT(new_data->cpus_perc[i].idle, idle * 100, sum); 157 FRACTION_TO_FLOAT(new_data->cpus_perc[i].busy, busy * 100, sum); 158 } 159 116 160 /* For all tasks compute sum and differencies of all cycles */ 117 uint64_t mem_total = 1; /*< Must NOT be null! */ 118 uint64_t ucycles_total = 1; /*< Must NOT be null! */ 119 uint64_t kcycles_total = 1; /*< Must NOT be null! */ 120 uint64_t *ucycles_diff = malloc(new_data->task_count * sizeof(uint64_t)); 121 uint64_t *kcycles_diff = malloc(new_data->task_count * sizeof(uint64_t)); 122 unsigned int j = 0; 123 for (i = 0; i < new_data->task_count; ++i) { 124 /* Jump over all death tasks */ 125 while (old_data->taskinfos[j].taskid < new_data->taskinfos[i].taskid) 126 ++j; 127 if (old_data->taskinfos[j].taskid > new_data->taskinfos[i].taskid) { 161 162 uint64_t virtmem_total = 1; /* Must NOT be zero */ 163 uint64_t ucycles_total = 1; /* Must NOT be zero */ 164 uint64_t kcycles_total = 1; /* Must NOT be zero */ 165 166 for (i = 0; i < new_data->tasks_count; i++) { 167 /* Match task with the previous instance */ 168 169 bool found = false; 170 size_t j; 171 for (j = 0; j < old_data->tasks_count; j++) { 172 if (new_data->tasks[i].task_id == old_data->tasks[j].task_id) { 173 found = true; 174 break; 175 } 176 } 177 178 if (!found) { 128 179 /* This is newly borned task, ignore it */ 129 180 ucycles_diff[i] = 0; … … 131 182 continue; 132 183 } 133 /* Now we now we have task with same id */ 134 ucycles_diff[i] = new_data->taskinfos[i].ucycles - old_data->taskinfos[j].ucycles; 135 kcycles_diff[i] = new_data->taskinfos[i].kcycles - old_data->taskinfos[j].kcycles; 136 137 mem_total += new_data->taskinfos[i].virt_mem; 184 185 ucycles_diff[i] = 186 new_data->tasks[i].ucycles - old_data->tasks[j].ucycles; 187 kcycles_diff[i] = 188 new_data->tasks[i].kcycles - old_data->tasks[j].kcycles; 189 190 virtmem_total += new_data->tasks[i].virtmem; 138 191 ucycles_total += ucycles_diff[i]; 139 192 kcycles_total += kcycles_diff[i]; 140 193 } 141 142 /* And now compute percental change */ 143 new_data->task_perc = malloc(new_data->task_count * sizeof(task_perc_t)); 144 for (i = 0; i < new_data->task_count; ++i) { 145 FRACTION_TO_FLOAT(new_data->task_perc[i].mem, new_data->taskinfos[i].virt_mem * 100, mem_total); 146 FRACTION_TO_FLOAT(new_data->task_perc[i].ucycles, ucycles_diff[i] * 100, ucycles_total); 147 FRACTION_TO_FLOAT(new_data->task_perc[i].kcycles, kcycles_diff[i] * 100, kcycles_total); 148 } 149 150 /* Wait until coprocessor finishes its work */ 151 write_barrier(); 152 153 /* And free temporary structures */ 194 195 /* For each task: Compute percential change */ 196 197 for (i = 0; i < new_data->tasks_count; i++) { 198 FRACTION_TO_FLOAT(new_data->tasks_perc[i].virtmem, 199 new_data->tasks[i].virtmem * 100, virtmem_total); 200 FRACTION_TO_FLOAT(new_data->tasks_perc[i].ucycles, 201 ucycles_diff[i] * 100, ucycles_total); 202 FRACTION_TO_FLOAT(new_data->tasks_perc[i].kcycles, 203 kcycles_diff[i] * 100, kcycles_total); 204 } 205 206 /* Cleanup */ 207 154 208 free(ucycles_diff); 155 209 free(kcycles_diff); 210 211 return NULL; 156 212 } 157 213 158 214 static void free_data(data_t *target) 159 215 { 160 free(target->taskinfos); 161 free(target->thread_infos); 162 free(target->cpus); 163 free(target->cpu_perc); 164 free(target->task_perc); 216 if (target->load != NULL) 217 free(target->load); 218 219 if (target->cpus != NULL) 220 free(target->cpus); 221 222 if (target->cpus_perc != NULL) 223 free(target->cpus_perc); 224 225 if (target->tasks != NULL) 226 free(target->tasks); 227 228 if (target->tasks_perc != NULL) 229 free(target->tasks_perc); 230 231 if (target->threads != NULL) 232 free(target->threads); 233 234 if (target->physmem != NULL) 235 free(target->physmem); 165 236 } 166 167 static inline void swap(data_t **first, data_t **second)168 {169 data_t *temp;170 temp = *first;171 *first = *second;172 *second = temp;173 }174 175 static data_t data[2];176 237 177 238 int main(int argc, char *argv[]) 178 239 { 179 data_t *data1 = &data[0]; 180 data_t *data2 = &data[1]; 240 data_t data; 241 data_t data_prev; 242 const char *ret = NULL; 243 181 244 screen_init(); 182 183 /* Read initial stats */184 245 printf("Reading initial data...\n"); 185 read_data(data1); 246 247 if ((ret = read_data(&data_prev)) != NULL) 248 goto out; 249 186 250 /* Compute some rubbish to have initialised values */ 187 compute_percentages(data1, data1); 188 189 /* And paint screen until death... */ 251 if ((ret = compute_percentages(&data_prev, &data_prev)) != NULL) 252 goto out; 253 254 /* And paint screen until death */ 190 255 operation_type = OP_TASKS; 191 256 while (true) { 192 257 char c = tgetchar(UPDATE_INTERVAL); 193 258 if (c < 0) { 194 read_data(data2); 195 compute_percentages(data1, data2); 196 free_data(data1); 197 print_data(data2); 198 swap(&data1, &data2); 259 if ((ret = read_data(&data)) != NULL) { 260 free_data(&data); 261 goto out; 262 } 263 264 if ((ret = compute_percentages(&data_prev, &data)) != NULL) { 265 free_data(&data); 266 goto out; 267 } 268 269 print_data(&data); 270 free_data(&data_prev); 271 data_prev = data; 272 199 273 continue; 200 274 } 275 201 276 switch (c) { 202 277 case 'q': 203 clear_screen(); 204 return 0; 278 goto out; 205 279 case 'i': 206 PRINT_WARNING("Showing IPC statistics", c);280 print_warning("Showing IPC statistics"); 207 281 operation_type = OP_IPC; 208 282 break; 209 283 case 't': 210 PRINT_WARNING("Showing task stats", c);284 print_warning("Showing task statistics"); 211 285 operation_type = OP_TASKS; 212 286 break; 213 287 default: 214 PRINT_WARNING("Unknown command: %c", c);288 print_warning("Unknown command: %c", c); 215 289 break; 216 290 } 217 218 } 219 220 free_data(data1); 221 free_data(data2); 291 } 292 293 out: 294 screen_done(); 295 free_data(&data_prev); 296 297 if (ret != NULL) { 298 fprintf(stderr, "%s: %s\n", NAME, ret); 299 return 1; 300 } 301 222 302 return 0; 223 303 } -
uspace/app/top/top.h
re535eeb rdec16a2 1 1 /* 2 * Copyright (c) 2008 Stanislav Kozina 2 * Copyright (c) 2010 Stanislav Kozina 3 * Copyright (c) 2010 Martin Decky 3 4 * All rights reserved. 4 5 * … … 35 36 36 37 #include <task.h> 37 #include < kernel/ps/cpuinfo.h>38 #include < kernel/ps/taskinfo.h>38 #include <stats.h> 39 #include <time.h> 39 40 40 41 #define FRACTION_TO_FLOAT(float, a, b) { \ … … 43 44 } 44 45 45 #define OP_TASKS 1 46 #define OP_IPC 2 46 #define OP_TASKS 1 47 #define OP_IPC 2 48 47 49 extern int operation_type; 48 50 … … 50 52 uint64_t upper; 51 53 uint64_t lower; 52 } ps_float;54 } fixed_float; 53 55 54 56 typedef struct { 55 ps_float idle;56 ps_float busy;57 } cpu_perc_t;57 fixed_float idle; 58 fixed_float busy; 59 } perc_cpu_t; 58 60 59 61 typedef struct { 60 ps_float ucycles;61 ps_float kcycles;62 ps_floatmem;63 } task_perc_t;62 fixed_float ucycles; 63 fixed_float kcycles; 64 fixed_float virtmem; 65 } perc_task_t; 64 66 65 67 typedef struct { 66 unsigned int hours; 67 unsigned int minutes; 68 unsigned int seconds; 69 70 unsigned int uptime_d; 71 unsigned int uptime_h; 72 unsigned int uptime_m; 73 unsigned int uptime_s; 74 75 unsigned long load[3]; 76 77 size_t task_count; 78 task_info_t *taskinfos; 79 task_perc_t *task_perc; 80 81 size_t thread_count; 82 thread_info_t *thread_infos; 83 84 unsigned int cpu_count; 85 uspace_cpu_info_t *cpus; 86 cpu_perc_t *cpu_perc; 87 88 uspace_mem_info_t mem_info; 68 time_t hours; 69 time_t minutes; 70 time_t seconds; 71 72 sysarg_t udays; 73 sysarg_t uhours; 74 sysarg_t uminutes; 75 sysarg_t useconds; 76 77 size_t load_count; 78 load_t *load; 79 80 size_t cpus_count; 81 stats_cpu_t *cpus; 82 perc_cpu_t *cpus_perc; 83 84 size_t tasks_count; 85 stats_task_t *tasks; 86 perc_task_t *tasks_perc; 87 88 size_t threads_count; 89 stats_thread_t *threads; 90 91 stats_physmem_t *physmem; 89 92 } data_t; 90 93 -
uspace/lib/c/generic/stats.c
re535eeb rdec16a2 96 96 } 97 97 98 /** Get task IDs99 * 100 * @param count Number of IDs returned.101 * 102 * @return Array of IDs (task_id_t).103 * If non-NULL then it should be eventually freed 104 * by free(). 105 * 106 */ 107 task_id_t *stats_get_tasks(size_t *count)108 { 109 size_t size = 0; 110 task_id_t *ids =111 ( task_id_t *) sysinfo_get_data("system.tasks", &size);112 113 assert((size % sizeof( task_id_t)) == 0);114 115 *count = size / sizeof( task_id_t);116 return ids;98 /** Get task statistics 99 * 100 * @param count Number of records returned. 101 * 102 * @return Array of stats_task_t structures. 103 * If non-NULL then it should be eventually freed 104 * by free(). 105 * 106 */ 107 stats_task_t *stats_get_tasks(size_t *count) 108 { 109 size_t size = 0; 110 stats_task_t *stats_tasks = 111 (stats_task_t *) sysinfo_get_data("system.tasks", &size); 112 113 assert((size % sizeof(stats_task_t)) == 0); 114 115 *count = size / sizeof(stats_task_t); 116 return stats_tasks; 117 117 } 118 118 … … 140 140 } 141 141 142 /** Get thread IDs143 * 144 * @param count Number of IDs returned.145 * 146 * @return Array of IDs (thread_id_t).147 * If non-NULL then it should be eventually freed 148 * by free(). 149 * 150 */ 151 thread_id_t *stats_get_threads(size_t *count)152 { 153 size_t size = 0; 154 thread_id_t *ids =155 ( thread_id_t *) sysinfo_get_data("system.threads", &size);156 157 assert((size % sizeof( thread_id_t)) == 0);158 159 *count = size / sizeof( thread_id_t);160 return ids;142 /** Get thread statistics. 143 * 144 * @param count Number of records returned. 145 * 146 * @return Array of stats_thread_t structures. 147 * If non-NULL then it should be eventually freed 148 * by free(). 149 * 150 */ 151 stats_thread_t *stats_get_threads(size_t *count) 152 { 153 size_t size = 0; 154 stats_thread_t *stats_threads = 155 (stats_thread_t *) sysinfo_get_data("system.threads", &size); 156 157 assert((size % sizeof(stats_thread_t)) == 0); 158 159 *count = size / sizeof(stats_thread_t); 160 return stats_threads; 161 161 } 162 162 -
uspace/lib/c/include/stats.h
re535eeb rdec16a2 47 47 extern sysarg_t stats_get_uptime(void); 48 48 49 extern task_id_t *stats_get_tasks(size_t *);49 extern stats_task_t *stats_get_tasks(size_t *); 50 50 extern stats_task_t *stats_get_task(task_id_t); 51 51 52 extern thread_id_t *stats_get_threads(size_t *);52 extern stats_thread_t *stats_get_threads(size_t *); 53 53 extern stats_thread_t *stats_get_thread(thread_id_t); 54 54
Note:
See TracChangeset
for help on using the changeset viewer.