Changeset 9dae191e in mainline
- Timestamp:
- 2010-04-18T00:24:40Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a80687e5
- Parents:
- d8e3467
- Files:
-
- 2 added
- 16 deleted
- 25 edited
- 3 moved
Legend:
- Unmodified
- Added
- Removed
-
boot/Makefile.common
rd8e3467 r9dae191e 94 94 $(USPACEDIR)/app/ping/ping \ 95 95 $(USPACEDIR)/app/ps/ps \ 96 $(USPACEDIR)/app/ top/top \97 $(USPACEDIR)/app/uptime/uptime\98 $(USPACEDIR)/app/dummy_load/dummy_load96 $(USPACEDIR)/app/uptime/uptime 97 # $(USPACEDIR)/app/top/top \ 98 # $(USPACEDIR)/app/dummy_load/dummy_load 99 99 100 100 COMPONENTS = \ -
kernel/Makefile
rd8e3467 r9dae191e 230 230 generic/src/security/cap.c \ 231 231 generic/src/sysinfo/sysinfo.c \ 232 generic/src/ps/ps.c \ 233 generic/src/ps/cpu.c \ 234 generic/src/ps/load.c \ 235 generic/src/ps/uptime.c \ 236 generic/src/ps/mem.c 232 generic/src/sysinfo/stats.c 237 233 238 234 ## Kernel console support -
kernel/generic/include/mm/frame.h
rd8e3467 r9dae191e 169 169 extern bool zone_merge(size_t, size_t); 170 170 extern void zone_merge_all(void); 171 extern uint64_t zone _total_size(void);172 extern void zone _busy_and_free(uint64_t *out_busy, uint64_t *out_free);171 extern uint64_t zones_total_size(void); 172 extern void zones_stats(uint64_t *, uint64_t *, uint64_t *, uint64_t *); 173 173 174 174 /* 175 175 * Console functions 176 176 */ 177 extern void zone _print_list(void);177 extern void zones_print_list(void); 178 178 extern void zone_print_one(size_t); 179 179 -
kernel/generic/include/proc/task.h
rd8e3467 r9dae191e 56 56 #include <ipc/kbox.h> 57 57 #include <mm/as.h> 58 59 #include <ps/taskinfo.h> 58 #include <sysinfo/abi.h> 60 59 61 60 struct thread; … … 81 80 task_id_t taskid; 82 81 /** Task security context. */ 83 context_id_t context; 82 context_id_t context; 84 83 85 84 /** Number of references (i.e. threads). */ … … 89 88 90 89 /** Task capabilities. */ 91 cap_t capabilities; 90 cap_t capabilities; 92 91 93 92 /* IPC stuff */ 94 93 answerbox_t answerbox; /**< Communication endpoint */ 95 94 phone_t phones[IPC_MAX_PHONES]; 96 task_ipc_info_t ipc_info;/**< IPC statistics */95 stats_ipc_t ipc_info; /**< IPC statistics */ 97 96 /** 98 97 * Active asynchronous messages. It is used for limiting uspace to … … 120 119 mutex_t futexes_lock; 121 120 /** B+tree of futexes referenced by this task. */ 122 btree_t futexes; 121 btree_t futexes; 123 122 124 123 /** Accumulated accounting. */ -
kernel/generic/include/proc/thread.h
rd8e3467 r9dae191e 69 69 #define THREAD_FLAG_NOATTACH (1 << 3) 70 70 71 /* We need state_t enum definition */ 72 #include <ps/taskinfo.h> 71 /** Thread states. */ 72 typedef enum { 73 /** It is an error, if thread is found in this state. */ 74 Invalid, 75 /** State of a thread that is currently executing on some CPU. */ 76 Running, 77 /** Thread in this state is waiting for an event. */ 78 Sleeping, 79 /** State of threads in a run queue. */ 80 Ready, 81 /** Threads are in this state before they are first readied. */ 82 Entering, 83 /** After a thread calls thread_exit(), it is put into Exiting state. */ 84 Exiting, 85 /** Threads that were not detached but exited are Lingering. */ 86 Lingering 87 } state_t; 73 88 74 89 /** Thread structure. There is one per thread. */ -
kernel/generic/include/syscall/syscall.h
rd8e3467 r9dae191e 71 71 SYS_IPC_REGISTER_IRQ, 72 72 SYS_IPC_UNREGISTER_IRQ, 73 73 74 74 SYS_EVENT_SUBSCRIBE, 75 75 … … 89 89 SYS_DEBUG_ENABLE_CONSOLE, 90 90 SYS_DEBUG_DISABLE_CONSOLE, 91 92 SYS_PS_GET_CPU_INFO, 93 SYS_PS_GET_MEM_INFO, 94 SYS_PS_GET_TASKS, 95 SYS_PS_GET_TASK_INFO, 96 SYS_PS_GET_THREADS, 97 SYS_PS_GET_UPTIME, 98 SYS_PS_GET_LOAD, 99 91 100 92 SYS_IPC_CONNECT_KBOX, 101 93 SYSCALL_END -
kernel/generic/include/sysinfo/abi.h
rd8e3467 r9dae191e 1 1 /* 2 * Copyright (c) 2010 Stanislav Kozina2 * Copyright (c) 2010 Martin Decky 3 3 * All rights reserved. 4 4 * … … 33 33 */ 34 34 35 #ifndef KERN_PS_CPU_H_ 36 #define KERN_PS_CPU_H_ 35 #ifndef KERN_ABI_H_ 36 #define KERN_ABI_H_ 37 38 #define LOAD_STEPS 3 39 #define TASK_NAME_BUFLEN 20 37 40 38 41 typedef struct { … … 41 44 uint64_t idle_ticks; 42 45 uint64_t busy_ticks; 43 } uspace_cpu_info_t; 46 } stats_cpu_t; 47 48 typedef struct { 49 uint64_t total; 50 uint64_t unavail; 51 uint64_t used; 52 uint64_t free; 53 } stats_physmem_t; 54 55 typedef struct { 56 uint64_t call_sent; 57 uint64_t call_recieved; 58 uint64_t answer_sent; 59 uint64_t answer_recieved; 60 uint64_t irq_notif_recieved; 61 uint64_t forwarded; 62 } stats_ipc_t; 63 64 typedef struct { 65 char name[TASK_NAME_BUFLEN]; 66 size_t virtmem; 67 size_t threads; 68 uint64_t ucycles; 69 uint64_t kcycles; 70 stats_ipc_t ipc_info; 71 } stats_task_t; 72 73 typedef uint32_t load_t; 44 74 45 75 #endif -
kernel/generic/include/sysinfo/stats.h
rd8e3467 r9dae191e 1 1 /* 2 * Copyright (c) 2010 Stanislav Kozina2 * Copyright (c) 2010 Martin Decky 3 3 * All rights reserved. 4 4 * … … 33 33 */ 34 34 35 #ifndef KERN_ PS_UPTIME_H_36 #define KERN_ PS_UPTIME_H_35 #ifndef KERN_STATS_H_ 36 #define KERN_STATS_H_ 37 37 38 extern int sys_ps_get_uptime(uint64_t *user_load); 38 extern void kload(void *arg); 39 extern void stats_init(void); 39 40 40 41 #endif -
kernel/generic/include/sysinfo/sysinfo.h
rd8e3467 r9dae191e 59 59 typedef unative_t (*sysinfo_fn_val_t)(struct sysinfo_item *); 60 60 typedef void *(*sysinfo_fn_data_t)(struct sysinfo_item *, size_t *); 61 typedef struct sysinfo_item *(*sysinfo_fn_subtree_t)(const char *);62 61 63 62 typedef struct { … … 73 72 } sysinfo_item_val_t; 74 73 74 typedef struct { 75 sysinfo_item_val_type_t tag; 76 union { 77 unative_t val; 78 sysinfo_data_t data; 79 }; 80 } sysinfo_return_t; 81 82 typedef sysinfo_return_t (*sysinfo_fn_subtree_t)(const char *); 83 75 84 typedef union { 76 85 struct sysinfo_item *table; 77 sysinfo_fn_subtree_t find_item;86 sysinfo_fn_subtree_t get_data; 78 87 } sysinfo_subtree_t; 79 88 … … 90 99 } sysinfo_item_t; 91 100 92 typedef struct {93 sysinfo_item_val_type_t tag;94 union {95 unative_t val;96 sysinfo_data_t data;97 };98 } sysinfo_return_t;99 100 extern void sysinfo_init(void);101 102 101 extern void sysinfo_set_item_val(const char *, sysinfo_item_t **, unative_t); 103 102 extern void sysinfo_set_item_data(const char *, sysinfo_item_t **, void *, 104 103 size_t); 105 extern void sysinfo_set_item_ val_fn(const char *, sysinfo_item_t **,104 extern void sysinfo_set_item_fn_val(const char *, sysinfo_item_t **, 106 105 sysinfo_fn_val_t); 107 extern void sysinfo_set_item_ data_fn(const char *, sysinfo_item_t **,106 extern void sysinfo_set_item_fn_data(const char *, sysinfo_item_t **, 108 107 sysinfo_fn_data_t); 109 108 extern void sysinfo_set_item_undefined(const char *, sysinfo_item_t **); 110 109 111 extern sysinfo_return_t sysinfo_get_item(const char *, sysinfo_item_t **); 112 extern void sysinfo_dump(sysinfo_item_t **, unsigned int); 110 extern void sysinfo_set_subtree_fn(const char *, sysinfo_item_t **, 111 sysinfo_fn_subtree_t); 112 113 extern void sysinfo_init(void); 114 extern void sysinfo_dump(sysinfo_item_t *); 113 115 114 116 unative_t sys_sysinfo_get_tag(void *, size_t); -
kernel/generic/src/console/cmd.c
rd8e3467 r9dae191e 886 886 int cmd_sysinfo(cmd_arg_t * argv) 887 887 { 888 sysinfo_dump(NULL , 0);888 sysinfo_dump(NULL); 889 889 return 1; 890 890 } … … 935 935 int cmd_zones(cmd_arg_t * argv) 936 936 { 937 zone _print_list();937 zones_print_list(); 938 938 return 1; 939 939 } -
kernel/generic/src/cpu/cpu.c
rd8e3467 r9dae191e 75 75 76 76 cpus[i].id = i; 77 cpus[i].idle_ticks = 0;78 cpus[i].busy_ticks = 0;79 77 80 78 spinlock_initialize(&cpus[i].lock, "cpu_t.lock"); … … 97 95 cpu_identify(); 98 96 cpu_arch_init(); 99 100 sysinfo_set_item_val("cpu.count", NULL, config.cpu_count);101 97 } 102 98 -
kernel/generic/src/main/kinit.c
rd8e3467 r9dae191e 67 67 #include <debug.h> 68 68 #include <str.h> 69 #include < ps/load.h>69 #include <sysinfo/stats.h> 70 70 71 71 #ifdef CONFIG_SMP … … 123 123 } else 124 124 panic("Unable to create kmp thread."); 125 125 126 thread_join(thread); 126 127 thread_detach(thread); … … 151 152 arch_post_smp_init(); 152 153 154 /* Start thread computing system load */ 155 thread = thread_create(kload, NULL, TASK, 0, "kload", false); 156 if (thread != NULL) 157 thread_ready(thread); 158 else 159 printf("Unable to create kload thread\n"); 160 153 161 #ifdef CONFIG_KCONSOLE 154 162 if (stdin) { … … 164 172 #endif /* CONFIG_KCONSOLE */ 165 173 166 /* Start thread computing system load */167 thread = thread_create(kload_thread, NULL, TASK, 0, "kload", false);168 if (thread != NULL)169 thread_ready(thread);170 else171 printf("Unable to create kload thread\n");172 173 174 interrupts_enable(); 174 175 -
kernel/generic/src/main/main.c
rd8e3467 r9dae191e 85 85 #include <ipc/event.h> 86 86 #include <sysinfo/sysinfo.h> 87 #include <sysinfo/stats.h> 87 88 88 89 /** Global configuration structure. */ … … 225 226 226 227 printf("Detected %" PRIs " CPU(s), %" PRIu64" MiB free memory\n", 227 config.cpu_count, SIZE2MB(zone _total_size()));228 config.cpu_count, SIZE2MB(zones_total_size())); 228 229 229 230 LOG_EXEC(cpu_init()); … … 249 250 LOG_EXEC(event_init()); 250 251 LOG_EXEC(klog_init()); 252 LOG_EXEC(stats_init()); 251 253 252 254 /* -
kernel/generic/src/mm/frame.c
rd8e3467 r9dae191e 1202 1202 1203 1203 /** Return total size of all zones. */ 1204 uint64_t zone _total_size(void)1204 uint64_t zones_total_size(void) 1205 1205 { 1206 1206 ipl_t ipl = interrupts_disable(); … … 1218 1218 } 1219 1219 1220 void zone_busy_and_free(uint64_t *out_busy, uint64_t *out_free) 1221 { 1220 void zones_stats(uint64_t *total, uint64_t *unavail, uint64_t *busy, 1221 uint64_t *free) 1222 { 1223 ASSERT(total != NULL); 1224 ASSERT(unavail != NULL); 1225 ASSERT(busy != NULL); 1226 ASSERT(free != NULL); 1227 1222 1228 ipl_t ipl = interrupts_disable(); 1223 1229 spinlock_lock(&zones.lock); 1224 1225 uint64_t busy = 0, free = 0; 1230 1231 *total = 0; 1232 *unavail = 0; 1233 *busy = 0; 1234 *free = 0; 1235 1226 1236 size_t i; 1227 1237 for (i = 0; i < zones.count; i++) { 1228 bool available = zone_flags_available(zones.info[i].flags); 1229 /* Do not count reserved memory */ 1230 if (available) { 1231 busy += (uint64_t) FRAMES2SIZE(zones.info[i].busy_count); 1232 free += (uint64_t) FRAMES2SIZE(zones.info[i].free_count); 1233 } 1234 } 1235 1238 *total += (uint64_t) FRAMES2SIZE(zones.info[i].count); 1239 1240 if (zone_flags_available(zones.info[i].flags)) { 1241 *busy += (uint64_t) FRAMES2SIZE(zones.info[i].busy_count); 1242 *free += (uint64_t) FRAMES2SIZE(zones.info[i].free_count); 1243 } else 1244 *unavail += (uint64_t) FRAMES2SIZE(zones.info[i].count); 1245 } 1246 1236 1247 spinlock_unlock(&zones.lock); 1237 1248 interrupts_restore(ipl); 1238 *out_busy = busy;1239 *out_free = free;1240 1249 } 1241 1250 1242 1251 /** Prints list of zones. */ 1243 void zone _print_list(void)1252 void zones_print_list(void) 1244 1253 { 1245 1254 #ifdef __32_BITS__ -
kernel/generic/src/syscall/syscall.c
rd8e3467 r9dae191e 54 54 #include <console/console.h> 55 55 #include <udebug/udebug.h> 56 #include <ps/ps.h>57 #include <ps/load.h>58 #include <ps/uptime.h>59 56 60 57 /** Dispatch system call */ … … 147 144 (syshandler_t) sys_ipc_register_irq, 148 145 (syshandler_t) sys_ipc_unregister_irq, 149 146 150 147 /* Event notification syscalls. */ 151 148 (syshandler_t) sys_event_subscribe, … … 170 167 (syshandler_t) sys_debug_enable_console, 171 168 (syshandler_t) sys_debug_disable_console, 172 173 /* Ps calls */174 (syshandler_t) sys_ps_get_cpu_info,175 (syshandler_t) sys_ps_get_mem_info,176 (syshandler_t) sys_ps_get_tasks,177 (syshandler_t) sys_ps_get_task_info,178 (syshandler_t) sys_ps_get_threads,179 (syshandler_t) sys_ps_get_uptime,180 (syshandler_t) sys_ps_get_load,181 169 182 170 (syshandler_t) sys_ipc_connect_kbox -
kernel/generic/src/sysinfo/sysinfo.c
rd8e3467 r9dae191e 37 37 #include <print.h> 38 38 #include <syscall/copy.h> 39 #include <synch/spinlock.h> 39 40 #include <errno.h> 40 41 … … 45 46 static sysinfo_item_t *global_root = NULL; 46 47 static slab_cache_t *sysinfo_item_slab; 48 49 SPINLOCK_STATIC_INITIALIZE_NAME(sysinfo_lock, "sysinfo_lock"); 47 50 48 51 static int sysinfo_item_constructor(void *obj, int kmflag) … … 76 79 } 77 80 81 /** Recursively find item in sysinfo tree 82 * 83 * Should be called with interrupts disabled 84 * and sysinfo_lock held. 85 * 86 */ 78 87 static sysinfo_item_t *sysinfo_find_item(const char *name, 79 sysinfo_item_t *subtree) 80 { 88 sysinfo_item_t *subtree, sysinfo_return_t **ret) 89 { 90 ASSERT(subtree != NULL); 91 ASSERT(ret != NULL); 92 81 93 sysinfo_item_t *cur = subtree; 82 94 … … 98 110 case SYSINFO_SUBTREE_TABLE: 99 111 /* Recursively find in subtree */ 100 return sysinfo_find_item(name + i + 1, cur->subtree.table); 112 return sysinfo_find_item(name + i + 1, 113 cur->subtree.table, ret); 101 114 case SYSINFO_SUBTREE_FUNCTION: 102 /* Get generated item */ 103 return cur->subtree.find_item(name + i + 1); 115 /* Get generated data */ 116 **ret = cur->subtree.get_data(name + i + 1); 117 return NULL; 104 118 default: 105 119 /* Not found */ 120 *ret = NULL; 106 121 return NULL; 107 122 } … … 111 126 } 112 127 128 *ret = NULL; 113 129 return NULL; 114 130 } 115 131 132 /** Recursively create items in sysinfo tree 133 * 134 * Should be called with interrupts disabled 135 * and sysinfo_lock held. 136 * 137 */ 116 138 static sysinfo_item_t *sysinfo_create_path(const char *name, 117 139 sysinfo_item_t **psubtree) … … 224 246 unative_t val) 225 247 { 248 ipl_t ipl = interrupts_disable(); 249 spinlock_lock(&sysinfo_lock); 250 226 251 if (root == NULL) 227 252 root = &global_root; … … 232 257 item->val.val = val; 233 258 } 259 260 spinlock_unlock(&sysinfo_lock); 261 interrupts_restore(ipl); 234 262 } 235 263 … … 237 265 void *data, size_t size) 238 266 { 267 ipl_t ipl = interrupts_disable(); 268 spinlock_lock(&sysinfo_lock); 269 239 270 if (root == NULL) 240 271 root = &global_root; … … 246 277 item->val.data.size = size; 247 278 } 248 } 249 250 void sysinfo_set_item_val_fn(const char *name, sysinfo_item_t **root, 279 280 spinlock_unlock(&sysinfo_lock); 281 interrupts_restore(ipl); 282 } 283 284 void sysinfo_set_item_fn_val(const char *name, sysinfo_item_t **root, 251 285 sysinfo_fn_val_t fn) 252 286 { 287 ipl_t ipl = interrupts_disable(); 288 spinlock_lock(&sysinfo_lock); 289 253 290 if (root == NULL) 254 291 root = &global_root; … … 259 296 item->val.fn_val = fn; 260 297 } 261 } 262 263 void sysinfo_set_item_data_fn(const char *name, sysinfo_item_t **root, 298 299 spinlock_unlock(&sysinfo_lock); 300 interrupts_restore(ipl); 301 } 302 303 void sysinfo_set_item_fn_data(const char *name, sysinfo_item_t **root, 264 304 sysinfo_fn_data_t fn) 265 305 { 306 ipl_t ipl = interrupts_disable(); 307 spinlock_lock(&sysinfo_lock); 308 266 309 if (root == NULL) 267 310 root = &global_root; … … 272 315 item->val.fn_data = fn; 273 316 } 317 318 spinlock_unlock(&sysinfo_lock); 319 interrupts_restore(ipl); 274 320 } 275 321 276 322 void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root) 277 323 { 324 ipl_t ipl = interrupts_disable(); 325 spinlock_lock(&sysinfo_lock); 326 278 327 if (root == NULL) 279 328 root = &global_root; … … 282 331 if (item != NULL) 283 332 item->val_type = SYSINFO_VAL_UNDEFINED; 284 } 285 333 334 spinlock_unlock(&sysinfo_lock); 335 interrupts_restore(ipl); 336 } 337 338 void sysinfo_set_subtree_fn(const char *name, sysinfo_item_t **root, 339 sysinfo_fn_subtree_t fn) 340 { 341 ipl_t ipl = interrupts_disable(); 342 spinlock_lock(&sysinfo_lock); 343 344 if (root == NULL) 345 root = &global_root; 346 347 sysinfo_item_t *item = sysinfo_create_path(name, root); 348 if ((item != NULL) && (item->subtree_type != SYSINFO_SUBTREE_TABLE)) { 349 item->subtree_type = SYSINFO_SUBTREE_FUNCTION; 350 item->subtree.get_data = fn; 351 } 352 353 spinlock_unlock(&sysinfo_lock); 354 interrupts_restore(ipl); 355 } 356 357 /** Sysinfo dump indentation helper routine 358 * 359 */ 286 360 static void sysinfo_indent(unsigned int depth) 287 361 { … … 291 365 } 292 366 293 void sysinfo_dump(sysinfo_item_t **proot, unsigned int depth) 294 { 295 if (proot == NULL) 296 proot = &global_root; 297 298 sysinfo_item_t *cur = *proot; 367 /** Dump the structure of sysinfo tree 368 * 369 * Should be called with interrupts disabled 370 * and sysinfo_lock held. Because this routine 371 * might take a reasonable long time to proceed, 372 * having the spinlock held is not optimal, but 373 * there is no better simple solution. 374 * 375 */ 376 static void sysinfo_dump_internal(sysinfo_item_t *root, unsigned int depth) 377 { 378 sysinfo_item_t *cur = root; 299 379 300 380 while (cur != NULL) { … … 302 382 303 383 unative_t val; 384 void *data; 304 385 size_t size; 305 386 … … 322 403 break; 323 404 case SYSINFO_VAL_FUNCTION_DATA: 324 cur->val.fn_data(cur, &size); 405 data = cur->val.fn_data(cur, &size); 406 if (data != NULL) 407 free(data); 408 325 409 printf("+ %s (%" PRIs" bytes) [generated]\n", cur->name, 326 410 size); … … 334 418 break; 335 419 case SYSINFO_SUBTREE_TABLE: 336 sysinfo_dump (&(cur->subtree.table), depth + 1);420 sysinfo_dump_internal(cur->subtree.table, depth + 1); 337 421 break; 338 422 case SYSINFO_SUBTREE_FUNCTION: 339 423 sysinfo_indent(depth + 1); 340 printf(" 424 printf("+ [generated subtree]\n"); 341 425 break; 342 426 default: 343 427 sysinfo_indent(depth + 1); 344 printf(" 428 printf("+ [unknown subtree]\n"); 345 429 } 346 430 … … 349 433 } 350 434 351 sysinfo_return_t sysinfo_get_item(const char *name, sysinfo_item_t **root) 435 void sysinfo_dump(sysinfo_item_t *root) 436 { 437 ipl_t ipl = interrupts_disable(); 438 spinlock_lock(&sysinfo_lock); 439 440 if (root == NULL) 441 sysinfo_dump_internal(global_root, 0); 442 else 443 sysinfo_dump_internal(root, 0); 444 445 spinlock_unlock(&sysinfo_lock); 446 interrupts_restore(ipl); 447 } 448 449 /** Return sysinfo item determined by name 450 * 451 * Should be called with interrupts disabled 452 * and sysinfo_lock held. 453 * 454 */ 455 static sysinfo_return_t sysinfo_get_item(const char *name, sysinfo_item_t **root) 352 456 { 353 457 if (root == NULL) 354 458 root = &global_root; 355 459 356 sysinfo_item_t *item = sysinfo_find_item(name, *root);357 460 sysinfo_return_t ret; 461 sysinfo_return_t *ret_ptr = &ret; 462 sysinfo_item_t *item = sysinfo_find_item(name, *root, &ret_ptr); 358 463 359 464 if (item != NULL) { 465 ret.tag = item->val_type; 360 466 switch (item->val_type) { 361 467 case SYSINFO_VAL_UNDEFINED: 468 break; 469 case SYSINFO_VAL_VAL: 470 ret.val = item->val.val; 471 break; 472 case SYSINFO_VAL_DATA: 473 ret.data = item->val.data; 474 break; 475 case SYSINFO_VAL_FUNCTION_VAL: 476 ret.val = item->val.fn_val(item); 477 break; 478 case SYSINFO_VAL_FUNCTION_DATA: 479 ret.data.data = item->val.fn_data(item, &ret.data.size); 480 break; 481 } 482 } else { 483 if (ret_ptr == NULL) 362 484 ret.tag = SYSINFO_VAL_UNDEFINED; 363 break; 364 case SYSINFO_VAL_VAL: 365 ret.tag = SYSINFO_VAL_VAL; 366 ret.val = item->val.val; 367 break; 368 case SYSINFO_VAL_DATA: 369 ret.tag = SYSINFO_VAL_DATA; 370 ret.data = item->val.data; 371 break; 372 case SYSINFO_VAL_FUNCTION_VAL: 373 ret.tag = SYSINFO_VAL_VAL; 374 ret.val = item->val.fn_val(item); 375 break; 376 case SYSINFO_VAL_FUNCTION_DATA: 377 ret.tag = SYSINFO_VAL_DATA; 378 ret.data.data = item->val.fn_data(item, &ret.data.size); 379 break; 380 } 381 } else 382 ret.tag = SYSINFO_VAL_UNDEFINED; 485 } 383 486 384 487 return ret; 385 488 } 386 489 490 /** Return sysinfo item determined by name from user space 491 * 492 * Should be called with interrupts disabled 493 * and sysinfo_lock held. 494 * 495 */ 387 496 static sysinfo_return_t sysinfo_get_item_uspace(void *ptr, size_t size) 388 497 { … … 397 506 398 507 if ((copy_from_uspace(path, ptr, size + 1) == 0) 399 && (path[size] == 0)) {508 && (path[size] == 0)) 400 509 ret = sysinfo_get_item(path, NULL); 401 free(path); 402 } 403 510 511 free(path); 404 512 return ret; 405 513 } … … 407 515 unative_t sys_sysinfo_get_tag(void *path_ptr, size_t path_size) 408 516 { 409 return (unative_t) sysinfo_get_item_uspace(path_ptr, path_size).tag; 517 ipl_t ipl = interrupts_disable(); 518 spinlock_lock(&sysinfo_lock); 519 520 sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size); 521 522 if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL)) 523 free(ret.data.data); 524 525 if (ret.tag == SYSINFO_VAL_FUNCTION_VAL) 526 ret.tag = SYSINFO_VAL_VAL; 527 else if (ret.tag == SYSINFO_VAL_FUNCTION_DATA) 528 ret.tag = SYSINFO_VAL_DATA; 529 530 spinlock_unlock(&sysinfo_lock); 531 interrupts_restore(ipl); 532 533 return (unative_t) ret.tag; 410 534 } 411 535 … … 413 537 void *value_ptr) 414 538 { 539 ipl_t ipl = interrupts_disable(); 540 spinlock_lock(&sysinfo_lock); 541 415 542 sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size); 416 417 if (ret.tag != SYSINFO_VAL_VAL) 418 return (unative_t) EINVAL; 419 420 return (unative_t) copy_to_uspace(value_ptr, &ret.val, 421 sizeof(ret.val)); 543 int rc; 544 545 if ((ret.tag == SYSINFO_VAL_VAL) || (ret.tag == SYSINFO_VAL_FUNCTION_VAL)) 546 rc = copy_to_uspace(value_ptr, &ret.val, sizeof(ret.val)); 547 else 548 rc = EINVAL; 549 550 if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL)) 551 free(ret.data.data); 552 553 spinlock_unlock(&sysinfo_lock); 554 interrupts_restore(ipl); 555 556 return (unative_t) rc; 422 557 } 423 558 … … 425 560 void *size_ptr) 426 561 { 562 ipl_t ipl = interrupts_disable(); 563 spinlock_lock(&sysinfo_lock); 564 427 565 sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size); 428 429 if (ret.tag != SYSINFO_VAL_DATA) 430 return (unative_t) EINVAL; 431 432 return (unative_t) copy_to_uspace(size_ptr, &ret.data.size, 433 sizeof(ret.data.size)); 566 int rc; 567 568 if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) 569 rc = copy_to_uspace(size_ptr, &ret.data.size, 570 sizeof(ret.data.size)); 571 else 572 rc = EINVAL; 573 574 if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL)) 575 free(ret.data.data); 576 577 spinlock_unlock(&sysinfo_lock); 578 interrupts_restore(ipl); 579 580 return (unative_t) rc; 434 581 } 435 582 … … 437 584 void *buffer_ptr, size_t buffer_size) 438 585 { 586 ipl_t ipl = interrupts_disable(); 587 spinlock_lock(&sysinfo_lock); 588 439 589 sysinfo_return_t ret = sysinfo_get_item_uspace(path_ptr, path_size); 440 441 if (ret.tag != SYSINFO_VAL_DATA) 442 return (unative_t) EINVAL; 443 444 if (ret.data.size != buffer_size) 445 return ENOMEM; 446 447 return (unative_t) copy_to_uspace(buffer_ptr, ret.data.data, 448 ret.data.size); 590 int rc; 591 592 if ((ret.tag == SYSINFO_VAL_DATA) || (ret.tag == SYSINFO_VAL_FUNCTION_DATA)) { 593 if (ret.data.size == buffer_size) 594 rc = copy_to_uspace(buffer_ptr, ret.data.data, 595 ret.data.size); 596 else 597 rc = ENOMEM; 598 } else 599 rc = EINVAL; 600 601 if ((ret.tag == SYSINFO_VAL_FUNCTION_DATA) && (ret.data.data != NULL)) 602 free(ret.data.data); 603 604 spinlock_unlock(&sysinfo_lock); 605 interrupts_restore(ipl); 606 607 return (unative_t) rc; 449 608 } 450 609 -
kernel/generic/src/time/clock.c
rd8e3467 r9dae191e 86 86 uptime->seconds1 = 0; 87 87 uptime->seconds2 = 0; 88 uptime->useconds = 0; 88 uptime->useconds = 0; 89 89 90 90 clock_parea.pbase = (uintptr_t) faddr; -
uspace/app/dummy_load/Makefile
rd8e3467 r9dae191e 29 29 30 30 USPACE_PREFIX = ../.. 31 BINARY = dummy_load31 # BINARY = dummy_load 32 32 33 33 SOURCES = \ -
uspace/app/ps/func.c
rd8e3467 r9dae191e 33 33 /** 34 34 * @file 35 * @brief 35 * @brief Miscellaneous functions. 36 36 */ 37 37 38 #include <stdio.h> 39 38 #include <stdint.h> 40 39 #include "func.h" 41 40 -
uspace/app/ps/func.h
rd8e3467 r9dae191e 36 36 #define FUNC_H_ 37 37 38 #include <stdint.h> 39 38 40 extern void order(const uint64_t val, uint64_t *rv, char *suffix); 39 41 -
uspace/app/ps/ps.c
rd8e3467 r9dae191e 38 38 #include <task.h> 39 39 #include <thread.h> 40 #include < ps.h>40 #include <stats.h> 41 41 #include <errno.h> 42 42 #include <stdlib.h> 43 43 #include <malloc.h> 44 #include <load.h> 45 #include <sysinfo.h> 46 44 #include <inttypes.h> 45 #include <arg_parse.h> 47 46 #include "func.h" 48 47 49 #define TASK_COUNT 10 50 #define THREAD_COUNT 50 51 52 #define ECHOLOAD1(x) ((x) >> 11) 53 #define ECHOLOAD2(x) (((x) & 0x7ff) / 2) 48 #define NAME "ps" 49 50 #define TASK_COUNT 10 51 #define THREAD_COUNT 50 52 53 #define PRINT_LOAD1(x) ((x) >> 11) 54 #define PRINT_LOAD2(x) (((x) & 0x7ff) / 2) 54 55 55 56 /** Thread states */ 56 static const char *thread_states[] = {57 "Invalid",58 "Running",59 "Sleeping",60 "Ready",61 "Entering",62 "Exiting",63 "Lingering"64 }; 57 //static const char *thread_states[] = { 58 // "Invalid", 59 // "Running", 60 // "Sleeping", 61 // "Ready", 62 // "Entering", 63 // "Exiting", 64 // "Lingering" 65 //}; 65 66 66 67 static void list_tasks(void) 67 68 { 68 int task_count = TASK_COUNT; 69 task_id_t *tasks = malloc(task_count * sizeof(task_id_t)); 70 int result = get_task_ids(tasks, sizeof(task_id_t) * task_count); 71 72 while (result > task_count) { 73 task_count *= 2; 74 tasks = realloc(tasks, task_count * sizeof(task_id_t)); 75 result = get_task_ids(tasks, sizeof(task_id_t) * task_count); 76 } 77 78 printf(" ID Threads Mem uCycles kCycles Cycle fault Name\n"); 79 80 int i; 81 for (i = 0; i < result; ++i) { 82 task_info_t taskinfo; 83 get_task_info(tasks[i], &taskinfo); 84 uint64_t mem, ucycles, kcycles; 85 char memsuffix, usuffix, ksuffix; 86 order(taskinfo.virt_mem, &mem, &memsuffix); 87 order(taskinfo.ucycles, &ucycles, &usuffix); 88 order(taskinfo.kcycles, &kcycles, &ksuffix); 89 printf("%8llu %8u %8llu%c %12llu%c %12llu%c %s\n", tasks[i], 90 taskinfo.thread_count, mem, memsuffix, ucycles, usuffix, 91 kcycles, ksuffix, taskinfo.name); 92 } 93 94 free(tasks); 95 } 96 97 static void list_threads(task_id_t taskid) 98 { 69 size_t count; 70 task_id_t *ids = 71 (task_id_t *) get_stats_tasks(&count); 72 73 if (ids == NULL) { 74 fprintf(stderr, "%s: Unable to get tasks\n", NAME); 75 return; 76 } 77 78 printf(" ID Threads Mem uCycles kCycles Name\n"); 79 80 size_t i; 81 for (i = 0; i < count; i++) { 82 stats_task_t *stats_task = get_stats_task(ids[i]); 83 if (stats_task != NULL) { 84 uint64_t virtmem, ucycles, kcycles; 85 char vmsuffix, usuffix, ksuffix; 86 87 order(stats_task->virtmem, &virtmem, &vmsuffix); 88 order(stats_task->ucycles, &ucycles, &usuffix); 89 order(stats_task->kcycles, &kcycles, &ksuffix); 90 91 printf("%8" PRIu64 "%8u %8" PRIu64"%c %12" 92 PRIu64"%c %12" PRIu64"%c %s\n", ids[i], stats_task->threads, 93 virtmem, vmsuffix, ucycles, usuffix, kcycles, ksuffix, 94 stats_task->name); 95 96 free(stats_task); 97 } else 98 printf("%8" PRIu64 "\n", ids[i]); 99 } 100 101 free(ids); 102 } 103 104 static void list_threads(task_id_t task_id) 105 { 106 /* TODO: 99 107 size_t thread_count = THREAD_COUNT; 100 108 thread_info_t *threads = malloc(thread_count * sizeof(thread_info_t)); … … 128 136 } 129 137 130 free(threads); 131 } 132 133 static void echo_load(void) 134 { 135 unsigned long load[3]; 136 get_load(load); 137 printf("load avarage: "); 138 print_load_fragment(load[0], 2); 139 puts(" "); 140 print_load_fragment(load[1], 2); 141 puts(" "); 142 print_load_fragment(load[2], 2); 143 puts("\n"); 144 } 145 146 static void echo_cpus(void) 147 { 148 size_t cpu_count = sysinfo_value("cpu.count"); 149 printf("Found %u cpu's:\n", cpu_count); 150 uspace_cpu_info_t *cpus = malloc(cpu_count * sizeof(uspace_cpu_info_t)); 151 get_cpu_info(cpus); 152 size_t i; 153 for (i = 0; i < cpu_count; ++i) { 154 printf("%2u (%4u Mhz): Busy ticks: %6llu, Idle ticks: %6llu\n", cpus[i].id, 155 (size_t)cpus[i].frequency_mhz, cpus[i].busy_ticks, cpus[i].idle_ticks); 156 } 138 free(threads); */ 139 } 140 141 static void print_load(void) 142 { 143 size_t count; 144 load_t *load = get_stats_load(&count); 145 146 if (load == NULL) { 147 fprintf(stderr, "%s: Unable to get load\n", NAME); 148 return; 149 } 150 151 printf("%s: Load avarage: ", NAME); 152 153 size_t i; 154 for (i = 0; i < count; i++) { 155 if (i > 0) 156 printf(" "); 157 158 print_load_fragment(load[i], 2); 159 } 160 161 printf("\n"); 162 163 free(load); 164 } 165 166 static void list_cpus(void) 167 { 168 size_t count; 169 stats_cpu_t *cpus = get_stats_cpus(&count); 170 171 if (cpus == NULL) { 172 fprintf(stderr, "%s: Unable to get CPU statistics\n", NAME); 173 return; 174 } 175 176 printf("%s: %u CPU(s) detected\n", NAME, count); 177 178 size_t i; 179 for (i = 0; i < count; i++) { 180 printf("cpu%u: %" PRIu16 " MHz, busy ticks: " 181 "%" PRIu64 ", idle ticks: %" PRIu64 "\n", 182 cpus[i].id, cpus[i].frequency_mhz, cpus[i].busy_ticks, 183 cpus[i].idle_ticks); 184 } 185 186 free(cpus); 157 187 } 158 188 159 189 static void usage() 160 190 { 161 printf("Usage: ps [-t pid|-l|-c]\n"); 191 printf( 192 "Usage: ps [-t task_id] [-l] [-c]\n" \ 193 "\n" \ 194 "Options:\n" \ 195 "\t-t task_id\n" \ 196 "\t--task=task_id\n" \ 197 "\t\tList threads of the given task\n" \ 198 "\n" \ 199 "\t-l\n" \ 200 "\t--load\n" \ 201 "\t\tPrint system load\n" \ 202 "\n" \ 203 "\t-c\n" \ 204 "\t--cpu\n" \ 205 "\t\tList CPUs\n" \ 206 "\n" \ 207 "\t-h\n" \ 208 "\t--help\n" \ 209 "\t\tPrint this usage information\n" 210 "\n" \ 211 "Without any options all tasks are listed\n" 212 ); 162 213 } 163 214 164 215 int main(int argc, char *argv[]) 165 216 { 166 --argc; ++argv; 167 168 if (argc > 0) 169 { 170 if (str_cmp(*argv, "-t") == 0) { 171 --argc; ++argv; 172 if (argc != 1) { 173 printf("Bad argument count!\n"); 174 usage(); 175 exit(1); 217 bool toggle_tasks = true; 218 bool toggle_threads = false; 219 bool toggle_load = false; 220 bool toggle_cpus = false; 221 222 task_id_t task_id; 223 224 int i; 225 for (i = 1; i < argc; i++) { 226 int off; 227 228 /* Usage */ 229 if ((off = arg_parse_short_long(argv[i], "-h", "--help")) != -1) { 230 usage(); 231 return 0; 232 } 233 234 /* Load */ 235 if ((off = arg_parse_short_long(argv[i], "-l", "--load")) != -1) { 236 toggle_tasks = false; 237 toggle_load = true; 238 continue; 239 } 240 241 /* CPUs */ 242 if ((off = arg_parse_short_long(argv[i], "-c", "--cpus")) != -1) { 243 toggle_tasks = false; 244 toggle_cpus = true; 245 continue; 246 } 247 248 /* Threads */ 249 if ((off = arg_parse_short_long(argv[i], "-t", "--task=")) != -1) { 250 // TODO: Support for 64b range 251 int tmp; 252 int ret = arg_parse_int(argc, argv, &i, &tmp, off); 253 if (ret != EOK) { 254 printf("%s: Malformed task_id '%s'\n", NAME, argv[i]); 255 return -1; 176 256 } 177 task_id_t taskid = strtol(*argv, NULL, 10); 178 list_threads(taskid); 179 } else if (str_cmp(*argv, "-l") == 0) { 180 --argc; ++argv; 181 if (argc != 0) { 182 printf("Bad argument count!\n"); 183 usage(); 184 exit(1); 185 } 186 echo_load(); 187 } else if (str_cmp(*argv, "-c") == 0) { 188 --argc; ++argv; 189 if (argc != 0) { 190 printf("Bad argument count!\n"); 191 usage(); 192 exit(1); 193 } 194 echo_cpus(); 195 } else { 196 printf("Unknown argument %s!\n", *argv); 197 usage(); 198 exit(1); 199 } 200 } else { 257 258 task_id = tmp; 259 260 toggle_tasks = false; 261 toggle_threads = true; 262 continue; 263 } 264 } 265 266 if (toggle_tasks) 201 267 list_tasks(); 202 } 203 268 269 if (toggle_threads) 270 list_threads(task_id); 271 272 if (toggle_load) 273 print_load(); 274 275 if (toggle_cpus) 276 list_cpus(); 277 204 278 return 0; 205 279 } -
uspace/app/top/Makefile
rd8e3467 r9dae191e 29 29 30 30 USPACE_PREFIX = ../.. 31 BINARY = top31 # BINARY = top 32 32 33 33 SOURCES = \ -
uspace/app/top/func.c
rd8e3467 r9dae191e 33 33 /** 34 34 * @file 35 * @brief 35 * @brief Miscellaneous functions. 36 36 */ 37 37 38 #include <stdio.h> 39 38 #include <stdint.h> 40 39 #include "func.h" 41 40 -
uspace/app/top/func.h
rd8e3467 r9dae191e 27 27 */ 28 28 29 /** @addtogroup ps29 /** @addtogroup top 30 30 * @{ 31 31 */ … … 36 36 #define FUNC_H_ 37 37 38 extern void order(const uint64_t val, uint64_t *rv, char *suffix); 38 #include <stdint.h> 39 40 extern void order(const uint64_t, uint64_t *, char *); 39 41 40 42 #endif -
uspace/app/uptime/uptime.c
rd8e3467 r9dae191e 28 28 29 29 /** @addtogroup uptime 30 * @brief Echosystem uptime.30 * @brief Print system uptime. 31 31 * @{ 32 32 */ … … 36 36 37 37 #include <stdio.h> 38 #include < uptime.h>38 #include <stats.h> 39 39 #include <sys/time.h> 40 #include < load.h>40 #include <inttypes.h> 41 41 42 #define DAY 86400 43 #define HOUR 3600 44 #define MINUTE 60 42 #define NAME "uptime" 43 44 #define DAY 86400 45 #define HOUR 3600 46 #define MINUTE 60 45 47 46 48 int main(int argc, char *argv[]) 47 49 { 48 50 struct timeval time; 49 uint64_t sec;50 51 if (gettimeofday(&time, NULL) != 0) { 51 printf("Cannot get time of day!\n");52 return 1;52 fprintf(stderr, "%s: Cannot get time of day\n", NAME); 53 return -1; 53 54 } 54 sec = time.tv_sec; 55 printf("%02llu:%02llu:%02llu", (sec % DAY) / HOUR, 56 (sec % HOUR) / MINUTE, sec % MINUTE); 57 58 uint64_t uptime; 59 get_uptime(&uptime); 60 printf(", up %4llu days, %02llu:%02llu:%02llu", 61 uptime / DAY, (uptime % DAY) / HOUR, (uptime % HOUR) / MINUTE, uptime % MINUTE); 62 63 unsigned long load[3]; 64 get_load(load); 65 puts(", load avarage: "); 66 print_load_fragment(load[0], 2); 67 puts(" "); 68 print_load_fragment(load[1], 2); 69 puts(" "); 70 print_load_fragment(load[2], 2); 71 72 puts("\n"); 55 56 uint64_t sec = time.tv_sec; 57 printf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64, (sec % DAY) / HOUR, 58 (sec % HOUR) / MINUTE, sec % MINUTE); 59 60 sysarg_t uptime = get_stats_uptime(); 61 printf(", up %u days, %02u:%02u:%02u", uptime / DAY, 62 (uptime % DAY) / HOUR, (uptime % HOUR) / MINUTE, uptime % MINUTE); 63 64 size_t count; 65 load_t *load = get_stats_load(&count); 66 if (load != NULL) { 67 printf(", load avarage: "); 68 69 size_t i; 70 for (i = 0; i < count; i++) { 71 if (i > 0) 72 printf(" "); 73 74 print_load_fragment(load[i], 2); 75 } 76 } 77 78 printf("\n"); 73 79 return 0; 74 80 } -
uspace/lib/c/Makefile
rd8e3467 r9dae191e 96 96 generic/stacktrace.c \ 97 97 generic/arg_parse.c \ 98 generic/ps.c \ 99 generic/cpuinfo.c \ 100 generic/meminfo.c \ 101 generic/load.c \ 102 generic/uptime.c 98 generic/stats.c 103 99 104 100 SOURCES = \ -
uspace/lib/c/generic/sysinfo.c
rd8e3467 r9dae191e 58 58 } 59 59 60 externvoid *sysinfo_get_data(const char *path, size_t *size)60 void *sysinfo_get_data(const char *path, size_t *size) 61 61 { 62 62 while (true) { … … 74 74 return data; 75 75 76 free(data); 77 76 78 if (ret != ENOMEM) 77 79 return NULL; 78 79 free(data);80 80 } 81 81 } -
uspace/lib/c/include/stats.h
rd8e3467 r9dae191e 31 31 */ 32 32 /** @file 33 */ 33 */ 34 34 35 #ifndef LIBC_ PS_H_36 #define LIBC_ PS_H_35 #ifndef LIBC_STATS_H_ 36 #define LIBC_STATS_H_ 37 37 38 38 #include <task.h> 39 #include <kernel/ps/taskinfo.h> 40 #include <kernel/ps/cpuinfo.h> 41 #include <kernel/ps/meminfo.h> 39 #include <kernel/sysinfo/abi.h> 42 40 43 extern int get_cpu_info(uspace_cpu_info_t *cpus); 44 extern int get_mem_info(uspace_mem_info_t *meminfo); 45 extern size_t get_task_ids(task_id_t *ids, size_t size); 46 extern int get_task_info(task_id_t id, task_info_t *info); 47 extern size_t get_task_threads(thread_info_t *infos, size_t size); 41 extern stats_cpu_t *get_stats_cpus(size_t *); 42 extern stats_physmem_t *get_stats_physmem(void); 43 extern task_id_t *get_stats_tasks(size_t *); 44 extern stats_task_t *get_stats_task(task_id_t); 45 extern load_t *get_stats_load(size_t *); 46 extern sysarg_t get_stats_uptime(void); 47 48 extern void print_load_fragment(load_t, unsigned int); 48 49 49 50 #endif
Note:
See TracChangeset
for help on using the changeset viewer.