Changeset 5723313b in mainline
- Timestamp:
- 2019-12-11T15:28:47Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 894afff
- Parents:
- 086cab0
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/stats/stats.c
r086cab0 r5723313b 52 52 #define MINUTE 60 53 53 54 #define KERNEL_NAME "kernel" 55 #define INIT_PREFIX "init:" 56 54 57 typedef enum { 55 58 LIST_TASKS, … … 57 60 LIST_IPCCS, 58 61 LIST_CPUS, 59 LIST_LOAD, 60 LIST_UPTIME 61 } list_toggle_t; 62 PRINT_LOAD, 63 PRINT_UPTIME, 64 PRINT_ARCH 65 } output_toggle_t; 62 66 63 67 static void list_tasks(void) … … 224 228 } 225 229 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 else 309 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 else 328 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 user 339 * space tasks to the kernel to increase 340 * 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 226 367 static void usage(const char *name) 227 368 { 228 369 printf( 229 "Usage: %s [-t task_id] [-i task_id] [-at] [-ai] [-c] [-l] [-u] \n"370 "Usage: %s [-t task_id] [-i task_id] [-at] [-ai] [-c] [-l] [-u] [-d]\n" 230 371 "\n" 231 372 "Options:\n" 232 "\t-t task_id\n" 233 "\t--task=task_id\n" 373 "\t-t task_id | --task=task_id\n" 234 374 "\t\tList threads of the given task\n" 235 375 "\n" 236 "\t-i task_id\n" 237 "\t--ipcc=task_id\n" 376 "\t-i task_id | --ipcc=task_id\n" 238 377 "\t\tList IPC connections of the given task\n" 239 378 "\n" 240 "\t-at\n" 241 "\t--all-threads\n" 379 "\t-at | --all-threads\n" 242 380 "\t\tList all threads\n" 243 381 "\n" 244 "\t-ai\n" 245 "\t--all-ipccs\n" 382 "\t-ai | --all-ipccs\n" 246 383 "\t\tList all IPC connections\n" 247 384 "\n" 248 "\t-c\n" 249 "\t--cpus\n" 385 "\t-c | --cpus\n" 250 386 "\t\tList CPUs\n" 251 387 "\n" 252 "\t-l\n" 253 "\t--load\n" 388 "\t-l | --load\n" 254 389 "\t\tPrint system load\n" 255 390 "\n" 256 "\t-u\n" 257 "\t--uptime\n" 391 "\t-u | --uptime\n" 258 392 "\t\tPrint system uptime\n" 259 393 "\n" 260 "\t-h\n" 261 "\t--help\n" 394 "\t-d | --design\n" 395 "\t\tPrint the current system architecture graph\n" 396 "\n" 397 "\t-h | --help\n" 262 398 "\t\tPrint this usage information\n" 263 399 "\n" … … 268 404 int main(int argc, char *argv[]) 269 405 { 270 list_toggle_t list_toggle = LIST_TASKS;406 output_toggle_t output_toggle = LIST_TASKS; 271 407 bool toggle_all = false; 272 408 task_id_t task_id = 0; … … 283 419 /* All IPC connections */ 284 420 if ((off = arg_parse_short_long(argv[i], "-ai", "--all-ipccs")) != -1) { 285 list_toggle = LIST_IPCCS;421 output_toggle = LIST_IPCCS; 286 422 toggle_all = true; 287 423 continue; … … 290 426 /* All threads */ 291 427 if ((off = arg_parse_short_long(argv[i], "-at", "--all-threads")) != -1) { 292 list_toggle = LIST_THREADS;428 output_toggle = LIST_THREADS; 293 429 toggle_all = true; 294 430 continue; … … 307 443 task_id = tmp; 308 444 309 list_toggle = LIST_IPCCS;445 output_toggle = LIST_IPCCS; 310 446 continue; 311 447 } … … 323 459 task_id = tmp; 324 460 325 list_toggle = LIST_THREADS;461 output_toggle = LIST_THREADS; 326 462 continue; 327 463 } … … 329 465 /* CPUs */ 330 466 if ((off = arg_parse_short_long(argv[i], "-c", "--cpus")) != -1) { 331 list_toggle = LIST_CPUS;467 output_toggle = LIST_CPUS; 332 468 continue; 333 469 } … … 335 471 /* Load */ 336 472 if ((off = arg_parse_short_long(argv[i], "-l", "--load")) != -1) { 337 list_toggle = LIST_LOAD;473 output_toggle = PRINT_LOAD; 338 474 continue; 339 475 } … … 341 477 /* Uptime */ 342 478 if ((off = arg_parse_short_long(argv[i], "-u", "--uptime")) != -1) { 343 list_toggle = LIST_UPTIME; 344 continue; 345 } 346 } 347 348 switch (list_toggle) { 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) { 349 491 case LIST_TASKS: 350 492 list_tasks(); … … 359 501 list_cpus(); 360 502 break; 361 case LIST_LOAD:503 case PRINT_LOAD: 362 504 print_load(); 363 505 break; 364 case LIST_UPTIME:506 case PRINT_UPTIME: 365 507 print_uptime(); 508 break; 509 case PRINT_ARCH: 510 print_arch(); 366 511 break; 367 512 }
Note:
See TracChangeset
for help on using the changeset viewer.