diff --git a/kern/include/lib.h b/kern/include/lib.h index 7478ce6..498ec28 100644 --- a/kern/include/lib.h +++ b/kern/include/lib.h @@ -129,6 +129,7 @@ uint32_t random(void); void *kmalloc(size_t size); void kfree(void *ptr); void kheap_printstats(void); +void kheap_printused(void); void kheap_nextgeneration(void); void kheap_dump(void); void kheap_dumpall(void); diff --git a/kern/main/menu.c b/kern/main/menu.c index 4aeb5db..945a91d 100644 --- a/kern/main/menu.c +++ b/kern/main/menu.c @@ -376,6 +376,18 @@ cmd_kheapstats(int nargs, char **args) return 0; } +static +int +cmd_kheapused(int nargs, char **args) +{ + (void)nargs; + (void)args; + + kheap_printused(); + + return 0; +} + static int cmd_kheapgeneration(int nargs, char **args) @@ -541,6 +553,7 @@ static const char *mainmenu[] = { "[?o] Operations menu ", "[?t] Tests menu ", "[kh] Kernel heap stats ", + "[khu] Kernel heap usage ", "[khgen] Next kernel heap generation ", "[khdump] Dump kernel heap ", "[q] Quit and shut down ", @@ -593,6 +606,7 @@ static struct { /* stats */ { "kh", cmd_kheapstats }, + { "khu", cmd_kheapused }, { "khgen", cmd_kheapgeneration }, { "khdump", cmd_kheapdump }, diff --git a/kern/vm/kmalloc.c b/kern/vm/kmalloc.c index 453b3cc..4921a85 100644 --- a/kern/vm/kmalloc.c +++ b/kern/vm/kmalloc.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include /* * Kernel malloc. @@ -743,8 +745,8 @@ kheap_dumpall(void) * Print the allocated/freed map of a single kernel heap page. */ static -void -subpage_stats(struct pageref *pr) +unsigned long +subpage_stats(struct pageref *pr, bool quiet) { vaddr_t prpage, fla; struct freelist *fl; @@ -779,19 +781,22 @@ subpage_stats(struct pageref *pr) freemap[index/32] |= (1<<(index%32)); } } - - kprintf("at 0x%08lx: size %-4lu %u/%u free\n", - (unsigned long)prpage, (unsigned long) sizes[blktype], - (unsigned) pr->nfree, n); - kprintf(" "); - for (i=0; infree, n); + kprintf(" "); + for (i=0; infree)); } /* @@ -806,14 +811,36 @@ kheap_printstats(void) spinlock_acquire(&kmalloc_spinlock); kprintf("Subpage allocator status:\n"); - + for (pr = allbase; pr != NULL; pr = pr->next_all) { - subpage_stats(pr); + subpage_stats(pr, false); } spinlock_release(&kmalloc_spinlock); } +/* + * Print the whole heap. + */ +void +kheap_printused(void) +{ + struct pageref *pr; + unsigned long total = 0; + /* print the whole thing with interrupts off */ + spinlock_acquire(&kmalloc_spinlock); + + for (pr = allbase; pr != NULL; pr = pr->next_all) { + total += subpage_stats(pr, true); + } + + spinlock_release(&kmalloc_spinlock); + + char total_string[32]; + snprintf(total_string, sizeof(total_string), "%lu", total); + ksecprintf(SECRET, total_string, "khu"); +} + //////////////////////////////////////// /*