Changes in uspace/app/stats/stats.c [894afff:a63966d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/stats/stats.c
r894afff ra63966d 52 52 #define MINUTE 60 53 53 54 #define KERNEL_NAME "kernel"55 #define INIT_PREFIX "init:"56 57 typedef enum {58 LIST_TASKS,59 LIST_THREADS,60 LIST_IPCCS,61 LIST_CPUS,62 PRINT_LOAD,63 PRINT_UPTIME,64 PRINT_ARCH65 } output_toggle_t;66 67 54 static void list_tasks(void) 68 55 { … … 78 65 " [kcycles] [name\n"); 79 66 80 for (size_t i = 0; i < count; i++) { 67 size_t i; 68 for (i = 0; i < count; i++) { 81 69 uint64_t resmem; 82 70 uint64_t virtmem; … … 115 103 printf("[taskid] [threadid] [state ] [prio] [cpu ] [ucycles] [kcycles]\n"); 116 104 117 for (size_t i = 0; i < count; i++) { 105 size_t i; 106 for (i = 0; i < count; i++) { 118 107 if ((all) || (stats_threads[i].task_id == task_id)) { 119 108 uint64_t ucycles, kcycles; … … 141 130 } 142 131 143 static void list_ipccs(task_id_t task_id, bool all)144 {145 size_t count;146 stats_ipcc_t *stats_ipccs = stats_get_ipccs(&count);147 148 if (stats_ipccs == NULL) {149 fprintf(stderr, "%s: Unable to get IPC connections\n", NAME);150 return;151 }152 153 printf("[caller] [callee]\n");154 155 for (size_t i = 0; i < count; i++) {156 if ((all) || (stats_ipccs[i].caller == task_id)) {157 printf("%-8" PRIu64 " %-8" PRIu64 "\n",158 stats_ipccs[i].caller, stats_ipccs[i].callee);159 }160 }161 162 free(stats_ipccs);163 }164 165 132 static void list_cpus(void) 166 133 { … … 175 142 printf("[id] [MHz ] [busy cycles] [idle cycles]\n"); 176 143 177 for (size_t i = 0; i < count; i++) { 144 size_t i; 145 for (i = 0; i < count; i++) { 178 146 printf("%-4u ", cpus[i].id); 179 147 if (cpus[i].active) { … … 206 174 printf("%s: Load average: ", NAME); 207 175 208 for (size_t i = 0; i < count; i++) { 176 size_t i; 177 for (i = 0; i < count; i++) { 209 178 if (i > 0) 210 179 printf(" "); … … 228 197 } 229 198 230 static char *escape_dot(const char *str)231 {232 size_t size = 0;233 for (size_t i = 0; str[i] != 0; i++) {234 if (str[i] == '"')235 size++;236 237 size++;238 }239 240 char *escaped_str = calloc(size + 1, sizeof(char));241 if (escaped_str == NULL)242 return NULL;243 244 size_t pos = 0;245 for (size_t i = 0; str[i] != 0; i++) {246 if (str[i] == '"') {247 escaped_str[pos] = '\\';248 pos++;249 }250 251 escaped_str[pos] = str[i];252 pos++;253 }254 255 escaped_str[pos] = 0;256 257 return escaped_str;258 }259 260 static void print_arch(void)261 {262 size_t count_tasks;263 stats_task_t *stats_tasks = stats_get_tasks(&count_tasks);264 265 if (stats_tasks == NULL) {266 fprintf(stderr, "%s: Unable to get tasks\n", NAME);267 return;268 }269 270 size_t count_ipccs;271 stats_ipcc_t *stats_ipccs = stats_get_ipccs(&count_ipccs);272 273 if (stats_ipccs == NULL) {274 fprintf(stderr, "%s: Unable to get IPC connections\n", NAME);275 return;276 }277 278 /* Global dot language attributes */279 printf("digraph HelenOS {\n");280 printf("\tlayout=sfdp\n");281 printf("\t// layout=neato\n");282 printf("\tsplines=true\n");283 printf("\t// splines=ortho\n");284 printf("\tconcentrate=true\n");285 printf("\tcenter=true\n");286 printf("\toverlap=false\n");287 printf("\toutputorder=edgesfirst\n");288 printf("\tfontsize=12\n");289 printf("\tnode [shape=component style=filled color=red "290 "fillcolor=yellow]\n\t\n");291 292 bool kernel_found = false;293 task_id_t kernel_id = 0;294 295 /* Tasks as vertices (components) */296 for (size_t i = 0; i < count_tasks; i++) {297 /* Kernel task */298 bool kernel = (str_cmp(stats_tasks[i].name, KERNEL_NAME) == 0);299 300 /* Init task */301 bool init = str_test_prefix(stats_tasks[i].name, INIT_PREFIX);302 303 char *escaped_name = NULL;304 305 if (init)306 escaped_name = escape_dot(str_suffix(stats_tasks[i].name,307 str_length(INIT_PREFIX)));308 else309 escaped_name = escape_dot(stats_tasks[i].name);310 311 if (escaped_name == NULL)312 continue;313 314 if (kernel) {315 if (kernel_found) {316 fprintf(stderr, "%s: Duplicate kernel tasks\n", NAME);317 } else {318 kernel_found = true;319 kernel_id = stats_tasks[i].task_id;320 }321 322 printf("\ttask%" PRIu64 " [label=\"%s\" shape=invtrapezium "323 "fillcolor=gold]\n", stats_tasks[i].task_id, escaped_name);324 } else if (init)325 printf("\ttask%" PRIu64 " [label=\"%s\" fillcolor=orange]\n",326 stats_tasks[i].task_id, escaped_name);327 else328 printf("\ttask%" PRIu64 " [label=\"%s\"]\n", stats_tasks[i].task_id,329 escaped_name);330 331 free(escaped_name);332 }333 334 printf("\t\n");335 336 if (kernel_found) {337 /*338 * Add an invisible edge from all user339 * space tasks to the kernel to increase340 * the kernel ranking.341 */342 343 for (size_t i = 0; i < count_tasks; i++) {344 /* Skip the kernel itself */345 if (stats_tasks[i].task_id == kernel_id)346 continue;347 348 printf("\ttask%" PRIu64 " -> task%" PRIu64 " [style=\"invis\"]\n",349 stats_tasks[i].task_id, kernel_id);350 }351 }352 353 printf("\t\n");354 355 /* IPC connections as edges */356 for (size_t i = 0; i < count_ipccs; i++) {357 printf("\ttask%" PRIu64 " -> task%" PRIu64 "\n",358 stats_ipccs[i].caller, stats_ipccs[i].callee);359 }360 361 printf("}\n");362 363 free(stats_tasks);364 free(stats_ipccs);365 }366 367 199 static void usage(const char *name) 368 200 { 369 201 printf( 370 "Usage: %s [-t task_id] [- i task_id] [-at] [-ai] [-c] [-l] [-u] [-d]\n"202 "Usage: %s [-t task_id] [-a] [-c] [-l] [-u]\n" 371 203 "\n" 372 204 "Options:\n" 373 "\t-t task_id | --task=task_id\n" 205 "\t-t task_id\n" 206 "\t--task=task_id\n" 374 207 "\t\tList threads of the given task\n" 375 208 "\n" 376 "\t-i task_id | --ipcc=task_id\n" 377 "\t\tList IPC connections of the given task\n" 378 "\n" 379 "\t-at | --all-threads\n" 209 "\t-a\n" 210 "\t--all\n" 380 211 "\t\tList all threads\n" 381 212 "\n" 382 "\t-ai | --all-ipccs\n" 383 "\t\tList all IPC connections\n" 384 "\n" 385 "\t-c | --cpus\n" 213 "\t-c\n" 214 "\t--cpus\n" 386 215 "\t\tList CPUs\n" 387 216 "\n" 388 "\t-l | --load\n" 217 "\t-l\n" 218 "\t--load\n" 389 219 "\t\tPrint system load\n" 390 220 "\n" 391 "\t-u | --uptime\n" 221 "\t-u\n" 222 "\t--uptime\n" 392 223 "\t\tPrint system uptime\n" 393 224 "\n" 394 "\t-d | --design\n" 395 "\t\tPrint the current system architecture graph\n" 396 "\n" 397 "\t-h | --help\n" 225 "\t-h\n" 226 "\t--help\n" 398 227 "\t\tPrint this usage information\n" 399 228 "\n" … … 404 233 int main(int argc, char *argv[]) 405 234 { 406 output_toggle_t output_toggle = LIST_TASKS; 235 bool toggle_tasks = true; 236 bool toggle_threads = false; 407 237 bool toggle_all = false; 238 bool toggle_cpus = false; 239 bool toggle_load = false; 240 bool toggle_uptime = false; 241 408 242 task_id_t task_id = 0; 409 243 410 for (int i = 1; i < argc; i++) { 244 int i; 245 for (i = 1; i < argc; i++) { 411 246 int off; 412 247 … … 417 252 } 418 253 419 /* All IPC connections */ 420 if ((off = arg_parse_short_long(argv[i], "-ai", "--all-ipccs")) != -1) { 421 output_toggle = LIST_IPCCS; 254 /* All threads */ 255 if ((off = arg_parse_short_long(argv[i], "-a", "--all")) != -1) { 256 toggle_tasks = false; 257 toggle_threads = true; 422 258 toggle_all = true; 423 259 continue; 424 260 } 425 261 426 /* All threads */ 427 if ((off = arg_parse_short_long(argv[i], "-at", "--all-threads")) != -1) { 428 output_toggle = LIST_THREADS; 429 toggle_all = true; 430 continue; 431 } 432 433 /* IPC connections */ 434 if ((off = arg_parse_short_long(argv[i], "-i", "--ipcc=")) != -1) { 435 // TODO: Support for 64b range 436 int tmp; 437 errno_t ret = arg_parse_int(argc, argv, &i, &tmp, off); 438 if (ret != EOK) { 439 printf("%s: Malformed task id '%s'\n", NAME, argv[i]); 440 return -1; 441 } 442 443 task_id = tmp; 444 445 output_toggle = LIST_IPCCS; 446 continue; 447 } 448 449 /* Tasks */ 262 /* CPUs */ 263 if ((off = arg_parse_short_long(argv[i], "-c", "--cpus")) != -1) { 264 toggle_tasks = false; 265 toggle_cpus = true; 266 continue; 267 } 268 269 /* Threads */ 450 270 if ((off = arg_parse_short_long(argv[i], "-t", "--task=")) != -1) { 451 271 // TODO: Support for 64b range … … 453 273 errno_t ret = arg_parse_int(argc, argv, &i, &tmp, off); 454 274 if (ret != EOK) { 455 printf("%s: Malformed task 275 printf("%s: Malformed task_id '%s'\n", NAME, argv[i]); 456 276 return -1; 457 277 } … … 459 279 task_id = tmp; 460 280 461 output_toggle = LIST_THREADS; 462 continue; 463 } 464 465 /* CPUs */ 466 if ((off = arg_parse_short_long(argv[i], "-c", "--cpus")) != -1) { 467 output_toggle = LIST_CPUS; 281 toggle_tasks = false; 282 toggle_threads = true; 468 283 continue; 469 284 } … … 471 286 /* Load */ 472 287 if ((off = arg_parse_short_long(argv[i], "-l", "--load")) != -1) { 473 output_toggle = PRINT_LOAD; 288 toggle_tasks = false; 289 toggle_load = true; 474 290 continue; 475 291 } … … 477 293 /* Uptime */ 478 294 if ((off = arg_parse_short_long(argv[i], "-u", "--uptime")) != -1) { 479 output_toggle = PRINT_UPTIME; 480 continue; 481 } 482 483 /* Architecture */ 484 if ((off = arg_parse_short_long(argv[i], "-d", "--design")) != -1) { 485 output_toggle = PRINT_ARCH; 486 continue; 487 } 488 } 489 490 switch (output_toggle) { 491 case LIST_TASKS: 295 toggle_tasks = false; 296 toggle_uptime = true; 297 continue; 298 } 299 } 300 301 if (toggle_tasks) 492 302 list_tasks(); 493 break; 494 case LIST_THREADS:303 304 if (toggle_threads) 495 305 list_threads(task_id, toggle_all); 496 break; 497 case LIST_IPCCS: 498 list_ipccs(task_id, toggle_all); 499 break; 500 case LIST_CPUS: 306 307 if (toggle_cpus) 501 308 list_cpus(); 502 break; 503 case PRINT_LOAD:309 310 if (toggle_load) 504 311 print_load(); 505 break; 506 case PRINT_UPTIME:312 313 if (toggle_uptime) 507 314 print_uptime(); 508 break;509 case PRINT_ARCH:510 print_arch();511 break;512 }513 315 514 316 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.