- Timestamp:
- 2010-06-10T14:24:50Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c0f13d2
- Parents:
- 1113c9e
- Location:
- kernel/generic
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/interrupt.h
r1113c9e r8eec3c8 46 46 typedef void (* iroutine)(int, istate_t *); 47 47 48 typedef struct { 49 const char *name; 50 iroutine f; 51 uint64_t cycles; 52 uint64_t count; 53 } exc_table_t; 54 55 IRQ_SPINLOCK_EXTERN(exctbl_lock); 56 extern exc_table_t exc_table[]; 57 48 58 extern void fault_if_from_uspace(istate_t *, const char *, ...); 49 59 extern iroutine exc_register(int, const char *, iroutine); -
kernel/generic/include/sysinfo/abi.h
r1113c9e r8eec3c8 40 40 #define LOAD_STEPS 3 41 41 42 /** Maximum task name size*/42 /** Maximum name sizes */ 43 43 #define TASK_NAME_BUFLEN 20 44 #define EXC_NAME_BUFLEN 20 44 45 45 46 /** Thread states */ … … 123 124 } stats_thread_t; 124 125 126 /** Statistics about a single exception 127 * 128 */ 129 typedef struct { 130 unsigned int id; /**< Exception ID */ 131 char desc[EXC_NAME_BUFLEN]; /**< Description */ 132 uint64_t cycles; /**< Number of CPU cycles in the handler */ 133 uint64_t count; /**< Number of handled exceptions */ 134 } stats_exc_t; 135 125 136 /** Load fixed-point value */ 126 137 typedef uint32_t load_t; -
kernel/generic/src/interrupt/interrupt.c
r1113c9e r8eec3c8 53 53 #include <symtab.h> 54 54 #include <proc/thread.h> 55 56 static struct { 57 const char *name; 58 iroutine f; 59 } exc_table[IVT_ITEMS]; 60 61 SPINLOCK_INITIALIZE(exctbl_lock); 55 #include <arch/cycle.h> 56 #include <str.h> 57 58 exc_table_t exc_table[IVT_ITEMS]; 59 IRQ_SPINLOCK_INITIALIZE(exctbl_lock); 62 60 63 61 /** Register exception handler … … 72 70 ASSERT(n < IVT_ITEMS); 73 71 74 spinlock_lock(&exctbl_lock);72 irq_spinlock_lock(&exctbl_lock, true); 75 73 76 74 iroutine old = exc_table[n].f; 77 75 exc_table[n].f = handler; 78 76 exc_table[n].name = name; 79 80 spinlock_unlock(&exctbl_lock); 77 exc_table[n].cycles = 0; 78 exc_table[n].count = 0; 79 80 irq_spinlock_unlock(&exctbl_lock, true); 81 81 82 82 return old; … … 92 92 { 93 93 ASSERT(n < IVT_ITEMS); 94 95 uint64_t begin_cycle = get_cycle(); 94 96 95 97 /* Account user cycles */ 96 98 if (THREAD) { 97 99 irq_spinlock_lock(&THREAD->lock, false); 98 thread_update_accounting(true);100 THREAD->ucycles += begin_cycle - THREAD->last_cycle; 99 101 irq_spinlock_unlock(&THREAD->lock, false); 100 102 } … … 116 118 thread_exit(); 117 119 120 /* Account exception handling */ 121 uint64_t end_cycle = get_cycle(); 122 exc_table[n].cycles += end_cycle - begin_cycle; 123 exc_table[n].count++; 124 125 /* Do not charge THREAD for exception cycles */ 118 126 if (THREAD) { 119 127 irq_spinlock_lock(&THREAD->lock, false); 120 thread_update_accounting(false);128 THREAD->last_cycle = end_cycle; 121 129 irq_spinlock_unlock(&THREAD->lock, false); 122 130 } … … 185 193 unsigned int i; 186 194 187 spinlock_lock(&exctbl_lock);195 irq_spinlock_lock(&exctbl_lock, true); 188 196 189 197 #ifdef __32_BITS__ 190 printf("Exc Description Handler Symbol\n");191 printf("--- -------------------- ---------- -------- \n");198 printf("Exc Description Count Cycles Handler Symbol\n"); 199 printf("--- -------------------- ---------- ---------- ---------- --------\n"); 192 200 #endif 193 201 194 202 #ifdef __64_BITS__ 195 printf("Exc Description Handler Symbol\n");196 printf("--- -------------------- ---------- -------- --------\n");203 printf("Exc Description Count Cycles Handler Symbol\n"); 204 printf("--- -------------------- ---------- ---------- ------------------ --------\n"); 197 205 #endif 198 206 199 207 for (i = 0; i < IVT_ITEMS; i++) { 200 const char *symbol = symtab_fmt_name_lookup((unative_t) exc_table[i].f); 208 uint64_t count; 209 char count_suffix; 210 211 order_suffix(exc_table[i].count, &count, &count_suffix); 212 213 uint64_t cycles; 214 char cycles_suffix; 215 216 order_suffix(exc_table[i].cycles, &cycles, &cycles_suffix); 217 218 const char *symbol = 219 symtab_fmt_name_lookup((unative_t) exc_table[i].f); 201 220 202 221 #ifdef __32_BITS__ 203 printf("%-3u %-20s %10p %s\n", i + IVT_FIRST, exc_table[i].name, 204 exc_table[i].f, symbol); 222 printf("%-3u %-20s %9" PRIu64 "%c %9" PRIu64 "%c %10p %s\n", 223 i + IVT_FIRST, exc_table[i].name, count, count_suffix, 224 cycles, cycles_suffix, exc_table[i].f, symbol); 205 225 #endif 206 226 207 227 #ifdef __64_BITS__ 208 printf("%-3u %-20s %18p %s\n", i + IVT_FIRST, exc_table[i].name, 209 exc_table[i].f, symbol); 228 printf("%-3u %-20s %9" PRIu64 "%c %9" PRIu64 "%c %18p %s\n", 229 i + IVT_FIRST, exc_table[i].name, count, count_suffix, 230 cycles, cycles_suffix, exc_table[i].f, symbol); 210 231 #endif 211 232 212 233 if (((i + 1) % 20) == 0) { 213 234 printf(" -- Press any key to continue -- "); 214 spinlock_unlock(&exctbl_lock);235 irq_spinlock_unlock(&exctbl_lock, true); 215 236 indev_pop_character(stdin); 216 spinlock_lock(&exctbl_lock);237 irq_spinlock_lock(&exctbl_lock, true); 217 238 printf("\n"); 218 239 } 219 240 } 220 241 221 spinlock_unlock(&exctbl_lock);242 irq_spinlock_unlock(&exctbl_lock, true); 222 243 #endif 223 244 -
kernel/generic/src/sysinfo/stats.c
r1113c9e r8eec3c8 44 44 #include <proc/task.h> 45 45 #include <proc/thread.h> 46 #include <interrupt.h> 46 47 #include <str.h> 47 48 #include <errno.h> … … 535 536 } 536 537 538 /** Get exceptions statistics 539 * 540 * @param item Sysinfo item (unused). 541 * @param size Size of the returned data. 542 * @param dry_run Do not get the data, just calculate the size. 543 * 544 * @return Data containing several stats_exc_t structures. 545 * If the return value is not NULL, it should be freed 546 * in the context of the sysinfo request. 547 */ 548 static void *get_stats_exceptions(struct sysinfo_item *item, size_t *size, 549 bool dry_run) 550 { 551 *size = sizeof(stats_exc_t) * IVT_ITEMS; 552 553 if ((dry_run) || (IVT_ITEMS == 0)) 554 return NULL; 555 556 stats_exc_t *stats_exceptions = 557 (stats_exc_t *) malloc(*size, FRAME_ATOMIC); 558 if (stats_exceptions == NULL) { 559 /* No free space for allocation */ 560 *size = 0; 561 return NULL; 562 } 563 564 /* Messing with exception table, avoid deadlock */ 565 irq_spinlock_lock(&exctbl_lock, true); 566 567 unsigned int i; 568 for (i = 0; i < IVT_ITEMS; i++) { 569 stats_exceptions[i].id = i + IVT_FIRST; 570 str_cpy(stats_exceptions[i].desc, EXC_NAME_BUFLEN, exc_table[i].name); 571 stats_exceptions[i].cycles = exc_table[i].cycles; 572 stats_exceptions[i].count = exc_table[i].count; 573 } 574 575 irq_spinlock_unlock(&exctbl_lock, true); 576 577 return ((void *) stats_exceptions); 578 } 579 580 /** Get exception statistics 581 * 582 * Get statistics of a given exception. The exception number 583 * is passed as a string (current limitation of the sysinfo 584 * interface, but it is still reasonable for the given purpose). 585 * 586 * @param name Exception number (string-encoded number). 587 * @param dry_run Do not get the data, just calculate the size. 588 * 589 * @return Sysinfo return holder. The type of the returned 590 * data is either SYSINFO_VAL_UNDEFINED (unknown 591 * exception number or memory allocation error) or 592 * SYSINFO_VAL_FUNCTION_DATA (in that case the 593 * generated data should be freed within the 594 * sysinfo request context). 595 * 596 */ 597 static sysinfo_return_t get_stats_exception(const char *name, bool dry_run) 598 { 599 /* Initially no return value */ 600 sysinfo_return_t ret; 601 ret.tag = SYSINFO_VAL_UNDEFINED; 602 603 /* Parse the exception number */ 604 uint64_t excn; 605 if (str_uint64(name, NULL, 0, true, &excn) != EOK) 606 return ret; 607 608 #if IVT_FIRST > 0 609 if (excn < IVT_FIRST) 610 return ret; 611 #endif 612 613 if (excn >= IVT_ITEMS + IVT_FIRST) 614 return ret; 615 616 if (dry_run) { 617 ret.tag = SYSINFO_VAL_FUNCTION_DATA; 618 ret.data.data = NULL; 619 ret.data.size = sizeof(stats_thread_t); 620 } else { 621 /* Update excn index for accessing exc_table */ 622 excn -= IVT_FIRST; 623 624 /* Allocate stats_exc_t structure */ 625 stats_exc_t *stats_exception = 626 (stats_exc_t *) malloc(sizeof(stats_exc_t), FRAME_ATOMIC); 627 if (stats_exception == NULL) 628 return ret; 629 630 /* Messing with exception table, avoid deadlock */ 631 irq_spinlock_lock(&exctbl_lock, true); 632 633 /* Correct return value */ 634 ret.tag = SYSINFO_VAL_FUNCTION_DATA; 635 ret.data.data = (void *) stats_exception; 636 ret.data.size = sizeof(stats_exc_t); 637 638 stats_exception->id = excn; 639 str_cpy(stats_exception->desc, EXC_NAME_BUFLEN, exc_table[excn].name); 640 stats_exception->cycles = exc_table[excn].cycles; 641 stats_exception->count = exc_table[excn].count; 642 643 irq_spinlock_unlock(&exctbl_lock, true); 644 } 645 646 return ret; 647 } 648 537 649 /** Get physical memory statistics 538 650 * … … 651 763 sysinfo_set_item_fn_data("system.tasks", NULL, get_stats_tasks); 652 764 sysinfo_set_item_fn_data("system.threads", NULL, get_stats_threads); 765 sysinfo_set_item_fn_data("system.exceptions", NULL, get_stats_exceptions); 653 766 sysinfo_set_subtree_fn("system.tasks", NULL, get_stats_task); 654 767 sysinfo_set_subtree_fn("system.threads", NULL, get_stats_thread); 768 sysinfo_set_subtree_fn("system.exceptions", NULL, get_stats_exception); 655 769 } 656 770
Note:
See TracChangeset
for help on using the changeset viewer.