diff options
author | H. Peter Anvin <hpa@zytor.com> | 2001-10-20 02:34:02 +0000 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2001-10-20 02:34:02 +0000 |
commit | c315f1e4bb97c797fb7b3e22e40e23384d17008d (patch) | |
tree | 9d00e14e6757e8172071acf2cf5ac805602dc4c5 /stats.c | |
parent | be9d8ab8ec452c46777b2eb4ae925843d7361c7b (diff) | |
download | lpsm-c315f1e4bb97c797fb7b3e22e40e23384d17008d.tar.gz lpsm-c315f1e4bb97c797fb7b3e22e40e23384d17008d.tar.xz lpsm-c315f1e4bb97c797fb7b3e22e40e23384d17008d.zip |
Add missing file (statistics generation.)lpsm-0.1.2
Diffstat (limited to 'stats.c')
-rw-r--r-- | stats.c | 146 |
1 files changed, 146 insertions, 0 deletions
@@ -0,0 +1,146 @@ +#ident "$Id$" +/* ----------------------------------------------------------------------- * + * + * Copyright 2000-2001 H. Peter Anvin - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, Inc., + * 59 Temple Place Ste 330, Boston MA 02111-1307, USA, version 2.1, + * incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +/* + * stats.c + * + * Produce memory allocation statistics. + */ + +#include <assert.h> +#include <stdlib.h> +#include <inttypes.h> +#include <limits.h> +#include <string.h> + +#include "lpsm.h" +#include "internals.h" +#include "bitops.h" + +#ifdef PRINT_DEBUG_INFO +/* + * Debugging routine to print the number of allocations of each size + */ +void lpsm_print_statistics(void) +{ + int i, o, obit, ebit, xbit; + int fcount, acount, total_slabs; + unsigned long bt = 0, bf = 0, ba = 0; + struct slab_info *si; + + /* Print buddy system stats */ + + for ( i = 0, o = AH->arena_size_lg2 ; + o >= BUDDY_ORDER_MIN ; + i++, o-- ) { + obit = 1 << i; + ebit = obit << 1; + fcount = acount = 0; + for ( xbit = obit ; xbit < ebit ; xbit++ ) { + if ( test_bit(AH->free_bitmap, xbit) ) + fcount++; + } + for ( xbit = obit ; xbit < ebit ; xbit++ ) { + if ( test_bit(AH->alloc_bitmap, xbit) ) + acount++; + } + + DPRINTF((" rorder %2d order %2d free %8d used %8d\n", + i, AH->arena_size_lg2-i, fcount, acount)); + + bt += (fcount+acount) * (1UL << o); + bf += fcount * (1UL << o); + ba += acount * (1UL << o); + } + DPRINTF((" buddy: %lu bytes free, %lu bytes allocated, %lu total\n", + bf, ba, bt)); + + bt = bf = ba = 0; + + for ( si = &AH->slab[0], i = 0 ; + i < SLAB_INFO_COUNT ; + i++, si++ ) { + if ( !si->size ) + break; + total_slabs = si->total_pages * si->count; + DPRINTF((" slab size %4d free %8d used %8d\n", + si->size, total_slabs-si->alloc_slabs, si->alloc_slabs)); + bt += total_slabs * si->size; + bf += (total_slabs-si->alloc_slabs) * si->size; + ba += si->alloc_slabs * si->size; + } + DPRINTF((" slab: %lu bytes free, %lu bytes allocated, %lu total\n", + bf, ba, bt)); +} +#endif + +/* + * Get allocation statistics. This returned a malloc()'d list of + * {block size, free blocks, allocated blocks} followed by an + * all-zero datum. + */ +struct lpsm_alloc_stats *lpsm_alloc_stats(void) +{ + struct lpsm_alloc_stats *as, *asp; + struct slab_info *si; + int nb, ns; + int i, o; + int xbit, obit, ebit; + size_t fcount, acount, *last_buddy_alloc; + + /* Compute number of buddy and slab allocation types */ + nb = AH->arena_size_lg2-BUDDY_ORDER_MIN+1; + for ( ns = 0 ; ns < SLAB_INFO_COUNT ; ns++ ) + if ( !AH->slab[ns].size ) + break; + + as = malloc((nb+ns+1) * sizeof(struct lpsm_alloc_stats)); + if ( !as ) + return NULL; + + for ( asp = as, i = 0, o = AH->arena_size_lg2 ; + o >= BUDDY_ORDER_MIN ; + asp++, i++, o-- ) { + asp->size = (size_t)1 << o; + obit = 1 << i; + ebit = obit << 1; + fcount = acount = 0; + for ( xbit = obit ; xbit < ebit ; xbit++ ) { + if ( test_bit(AH->free_bitmap, xbit) ) + fcount++; + } + asp->free = fcount; + for ( xbit = obit ; xbit < ebit ; xbit++ ) { + if ( test_bit(AH->alloc_bitmap, xbit) ) + acount++; + } + asp->alloc = acount; + } + + /* The alloc counter for the last buddy size include all the slab blocks. + We want to count them separately. */ + last_buddy_alloc = &asp[-1].alloc; + + for ( i = 0, si = &AH->slab[0] ; + i < SLAB_INFO_COUNT && si->size ; + i++, si++, asp++ ) { + last_buddy_alloc -= si->total_pages; + asp->size = si->size; + asp->alloc = si->alloc_slabs; + asp->free = (si->total_pages * si->count) - si->alloc_slabs; + } + /* Sentinel block at end */ + asp->size = asp->alloc = asp->free = 0; + return as; +} + |