1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

New monitoring function for slab allocator

Added __get_slab_usage() function which can be used to query the slab allocator memory usage at runtime.
This commit is contained in:
obarthel
2016-11-19 15:49:21 +01:00
parent 3425e33cf9
commit 799ee705e8
23 changed files with 241 additions and 106 deletions

View File

@ -332,6 +332,7 @@ C_LIB = \
stdlib_getmemstats.o \
stdlib_getsp.o \
stdlib_get_errno.o \
stdlib_get_slab_usage.o \
stdlib_isresident.o \
stdlib_labs.o \
stdlib_llabs.o \
@ -1134,6 +1135,8 @@ $(LIBC_OBJS)/stdlib_slab.o : stdlib_slab.c stdlib_memory.h
$(LIBC_OBJS)/stdlib_free_unused_slabs.o : stdlib_free_unused_slabs.c stdlib_memory.h
$(LIBC_OBJS)/stdlib_get_slab_usage.o : stdlib_get_slab_usage.c stdlib_memory.h
$(LIBC_OBJS)/stdlib_realloc.o : stdlib_realloc.c stdlib_memory.h
$(LIBC_OBJS)/stdlib_red_black.o : stdlib_red_black.c stdlib_memory.h

View File

@ -1,6 +1,6 @@
#define VERSION 1
#define REVISION 207
#define DATE "18.11.2016"
#define VERS "amiga.lib 1.207"
#define VSTRING "amiga.lib 1.207 (18.11.2016)\r\n"
#define VERSTAG "\0$VER: amiga.lib 1.207 (18.11.2016)"
#define REVISION 208
#define DATE "19.11.2016"
#define VERS "amiga.lib 1.208"
#define VSTRING "amiga.lib 1.208 (19.11.2016)\r\n"
#define VERSTAG "\0$VER: amiga.lib 1.208 (19.11.2016)"

View File

@ -1 +1 @@
207
208

View File

@ -1,6 +1,6 @@
#define VERSION 1
#define REVISION 207
#define DATE "18.11.2016"
#define VERS "c.lib 1.207"
#define VSTRING "c.lib 1.207 (18.11.2016)\r\n"
#define VERSTAG "\0$VER: c.lib 1.207 (18.11.2016)"
#define REVISION 208
#define DATE "19.11.2016"
#define VERS "c.lib 1.208"
#define VSTRING "c.lib 1.208 (19.11.2016)\r\n"
#define VERSTAG "\0$VER: c.lib 1.208 (19.11.2016)"

View File

@ -1 +1 @@
207
208

View File

@ -1,3 +1,12 @@
c.lib 1.208 (19.11.2016)
- Updated <stdlib.h> with new functions and data structures for
use with the slab allocator.
- Added __get_slab_usage() function which can be used to query
the slab allocator memory usage at runtime.
c.lib 1.207 (18.11.2016)
- Added a slab allocator which replaces the use of memory pools or the

View File

@ -1,6 +1,6 @@
#define VERSION 1
#define REVISION 207
#define DATE "18.11.2016"
#define VERS "debug.lib 1.207"
#define VSTRING "debug.lib 1.207 (18.11.2016)\r\n"
#define VERSTAG "\0$VER: debug.lib 1.207 (18.11.2016)"
#define REVISION 208
#define DATE "19.11.2016"
#define VERS "debug.lib 1.208"
#define VSTRING "debug.lib 1.208 (19.11.2016)\r\n"
#define VERSTAG "\0$VER: debug.lib 1.208 (19.11.2016)"

View File

@ -1 +1 @@
207
208

View File

@ -218,6 +218,7 @@ C_LIB := \
stdlib_getmemstats.o \
stdlib_getsp.o \
stdlib_get_errno.o \
stdlib_get_slab_usage.o \
stdlib_isresident.o \
stdlib_labs.o \
stdlib_llabs.o \

View File

@ -1,6 +1,6 @@
#define VERSION 1
#define REVISION 207
#define DATE "18.11.2016"
#define VERS "m.lib 1.207"
#define VSTRING "m.lib 1.207 (18.11.2016)\r\n"
#define VERSTAG "\0$VER: m.lib 1.207 (18.11.2016)"
#define REVISION 208
#define DATE "19.11.2016"
#define VERS "m.lib 1.208"
#define VSTRING "m.lib 1.208 (19.11.2016)\r\n"
#define VERSTAG "\0$VER: m.lib 1.208 (19.11.2016)"

View File

@ -1 +1 @@
207
208

View File

@ -1,6 +1,6 @@
#define VERSION 1
#define REVISION 207
#define DATE "18.11.2016"
#define VERS "m881.lib 1.207"
#define VSTRING "m881.lib 1.207 (18.11.2016)\r\n"
#define VERSTAG "\0$VER: m881.lib 1.207 (18.11.2016)"
#define REVISION 208
#define DATE "19.11.2016"
#define VERS "m881.lib 1.208"
#define VSTRING "m881.lib 1.208 (19.11.2016)\r\n"
#define VERSTAG "\0$VER: m881.lib 1.208 (19.11.2016)"

View File

@ -1 +1 @@
207
208

View File

@ -1,6 +1,6 @@
#define VERSION 1
#define REVISION 207
#define DATE "18.11.2016"
#define VERS "net.lib 1.207"
#define VSTRING "net.lib 1.207 (18.11.2016)\r\n"
#define VERSTAG "\0$VER: net.lib 1.207 (18.11.2016)"
#define REVISION 208
#define DATE "19.11.2016"
#define VERS "net.lib 1.208"
#define VSTRING "net.lib 1.208 (19.11.2016)\r\n"
#define VERSTAG "\0$VER: net.lib 1.208 (19.11.2016)"

View File

@ -1 +1 @@
207
208

View File

@ -518,6 +518,8 @@ STDLIB_OBJ = \
stdlib_getenv.o \
stdlib_getmemstats.o \
stdlib_getsp.o \
stdlib_get_errno.o \
stdlib_get_slab_usage.o \
stdlib_isresident.o \
stdlib_labs.o \
stdlib_ldiv.o \
@ -801,6 +803,8 @@ stdlib_slab.o : stdlib_slab.c stdlib_memory.h
stdlib_free_unused_slabs.o : stdlib_free_unused_slabs.c stdlib_memory.h
stdlib_get_slab_usage.o : stdlib_get_slab_usage.c stdlib_memory.h
stdlib_realloc.o : stdlib_realloc.c stdlib_memory.h
stdlib_red_black.o : stdlib_red_black.c stdlib_memory.h

View File

@ -47,6 +47,8 @@
void
__free_unused_slabs(void)
{
if(__slab_data.sd_InUse)
{
struct MinNode * free_node;
struct MinNode * free_node_next;
struct SlabNode * sn;
@ -74,4 +76,5 @@ __free_unused_slabs(void)
}
__memory_unlock();
}
}

View File

@ -0,0 +1,104 @@
/*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDLIB_HEADERS_H
#include "stdlib_headers.h"
#endif /* _STDLIB_HEADERS_H */
/****************************************************************************/
#ifndef _STDLIB_MEMORY_H
#include "stdlib_memory.h"
#endif /* _STDLIB_MEMORY_H */
/****************************************************************************/
void
__get_slab_usage(__slab_usage_callback callback)
{
if(__slab_data.sd_InUse)
{
struct __slab_usage_information sui;
struct SlabNode * sn;
BOOL stop;
int i;
memset(&sui,0,sizeof(sui));
__memory_lock();
sui.sui_slab_size = __slab_data.sd_MaxSlabSize;
sui.sui_num_single_allocations = __slab_data.sd_NumSingleAllocations;
sui.sui_total_single_allocation_size = __slab_data.sd_TotalSingleAllocationSize;
for(i = 0 ; i < (int)NUM_ENTRIES(__slab_data.sd_Slabs) ; i++)
{
for(sn = (struct SlabNode *)__slab_data.sd_Slabs[i].mlh_Head ;
sn->sn_MinNode.mln_Succ != NULL ;
sn = (struct SlabNode *)sn->sn_MinNode.mln_Succ)
{
if (sn->sn_UseCount == 0)
sui.sui_num_empty_slabs++;
else if (sn->sn_Count == sn->sn_UseCount)
sui.sui_num_full_slabs++;
sui.sui_num_slabs++;
sui.sui_total_slab_allocation_size += sizeof(*sn) + __slab_data.sd_MaxSlabSize;
}
}
if(sui.sui_num_slabs > 0)
{
for(i = 0, stop = FALSE ; NOT stop && i < (int)NUM_ENTRIES(__slab_data.sd_Slabs) ; i++)
{
for(sn = (struct SlabNode *)__slab_data.sd_Slabs[i].mlh_Head ;
sn->sn_MinNode.mln_Succ != NULL ;
sn = (struct SlabNode *)sn->sn_MinNode.mln_Succ)
{
sui.sui_chunk_size = sn->sn_ChunkSize;
sui.sui_num_chunks = sn->sn_Count;
sui.sui_num_chunks_used = sn->sn_UseCount;
sui.sui_slab_index++;
if((*callback)(&sui) != 0)
{
stop = TRUE;
break;
}
}
}
}
__memory_unlock();
}
}

View File

@ -65,7 +65,6 @@
*/
#define __USE_SLAB_ALLOCATOR
/****************************************************************************/
/*
@ -271,10 +270,12 @@ struct SlabData
*/
size_t sd_MaxSlabSize;
/* This field keeps track of how many entries there are in
* the sd_SingleAllocations list.
/* These fields kees track of how many entries there are in
* the sd_SingleAllocations list, and how much memory these
* allocations occupy.
*/
ULONG sd_NumSingleAllocations;
size_t sd_NumSingleAllocations;
size_t sd_TotalSingleAllocationSize;
/* If this is set to TRUE, then memory allocations will be
* be managed through slabs.
@ -285,7 +286,7 @@ struct SlabData
/****************************************************************************/
extern struct SlabData NOCOMMON __slab_data;
extern ULONG NOCOMMON __slab_max_size;
extern unsigned long NOCOMMON __slab_max_size;
/****************************************************************************/

View File

@ -84,6 +84,7 @@ __slab_allocate(size_t allocation_size)
AddTail((struct List *)&__slab_data.sd_SingleAllocations,(struct Node *)single_allocation);
__slab_data.sd_NumSingleAllocations++;
__slab_data.sd_TotalSingleAllocationSize += sizeof(*single_allocation) + allocation_size;
allocation = &single_allocation[1];
@ -118,7 +119,7 @@ __slab_allocate(size_t allocation_size)
* size that still works.
*/
for(slab_index = 2, chunk_size = (1UL << slab_index) ;
slab_index < 31 ;
slab_index < (int)NUM_ENTRIES(__slab_data.sd_Slabs) ;
slab_index++, chunk_size += chunk_size)
{
if(entry_size <= chunk_size)
@ -374,6 +375,10 @@ __slab_free(void * address,size_t allocation_size)
__slab_data.sd_NumSingleAllocations--;
assert( __slab_data.sd_TotalSingleAllocationSize <= sizeof(*mn) + allocation_size );
__slab_data.sd_TotalSingleAllocationSize -= sizeof(*mn) + allocation_size;
D(("number of single allocations = %ld", __slab_data.sd_NumSingleAllocations));
}
/* Otherwise the allocation should have come from a slab. */
@ -400,7 +405,7 @@ __slab_free(void * address,size_t allocation_size)
* size that still works.
*/
for(slab_index = 2, chunk_size = (1UL << slab_index) ;
slab_index < 31 ;
slab_index < (int)NUM_ENTRIES(__slab_data.sd_Slabs) ;
slab_index++, chunk_size += chunk_size)
{
if(entry_size <= chunk_size)
@ -517,10 +522,12 @@ __slab_init(size_t slab_size)
D(("activating slab allocator"));
memset(&__slab_data,0,sizeof(__slab_data));
assert( size <= slab_size );
/* Start with an empty list of slabs for each chunk size. */
for(i = 0 ; i < 31 ; i++)
for(i = 0 ; i < (int)NUM_ENTRIES(__slab_data.sd_Slabs) ; i++)
NewList((struct List *)&__slab_data.sd_Slabs[i]);
NewList((struct List *)&__slab_data.sd_SingleAllocations);
@ -536,18 +543,20 @@ __slab_init(size_t slab_size)
void
__slab_exit(void)
{
ENTER();
if(__slab_data.sd_InUse)
{
struct SlabNode * sn;
struct SlabNode * sn_next;
struct MinNode * mn;
struct MinNode * mn_next;
int i;
ENTER();
D(("freeing slabs"));
/* Free the memory allocated for each slab. */
for(i = 0 ; i < 31 ; i++)
for(i = 0 ; i < (int)NUM_ENTRIES(__slab_data.sd_Slabs) ; i++)
{
if(__slab_data.sd_Slabs[i].mlh_Head->mln_Succ != NULL)
D(("freeing slab #%ld (%lu bytes per chunk)", i, (1UL << i)));
@ -578,6 +587,7 @@ __slab_exit(void)
}
__slab_data.sd_InUse = FALSE;
}
LEAVE();
}

View File

@ -35,4 +35,4 @@
/****************************************************************************/
ULONG NOCOMMON __slab_max_size;
unsigned long __slab_max_size;

View File

@ -1,6 +1,6 @@
#define VERSION 1
#define REVISION 207
#define DATE "18.11.2016"
#define VERS "unix.lib 1.207"
#define VSTRING "unix.lib 1.207 (18.11.2016)\r\n"
#define VERSTAG "\0$VER: unix.lib 1.207 (18.11.2016)"
#define REVISION 208
#define DATE "19.11.2016"
#define VERS "unix.lib 1.208"
#define VSTRING "unix.lib 1.208 (19.11.2016)\r\n"
#define VERSTAG "\0$VER: unix.lib 1.208 (19.11.2016)"

View File

@ -1 +1 @@
207
208