From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/lib/fusion/shmalloc.c | 679 ++++++++++++++++++++++++++++++++++ 1 file changed, 679 insertions(+) create mode 100755 Source/DirectFB/lib/fusion/shmalloc.c (limited to 'Source/DirectFB/lib/fusion/shmalloc.c') diff --git a/Source/DirectFB/lib/fusion/shmalloc.c b/Source/DirectFB/lib/fusion/shmalloc.c new file mode 100755 index 0000000..5fd3408 --- /dev/null +++ b/Source/DirectFB/lib/fusion/shmalloc.c @@ -0,0 +1,679 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library 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; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + + +#if FUSION_BUILD_MULTI + +/*************************** MULTI APPLICATION CORE ***************************/ + +#if DIRECT_BUILD_DEBUGS /* Build with debug support? */ + +D_DEBUG_DOMAIN( Fusion_SHM, "Fusion/SHM", "Fusion Shared Memory" ); + +void +fusion_dbg_print_memleaks( FusionSHMPoolShared *pool ) +{ + DirectResult ret; + SHMemDesc *desc; + unsigned int total = 0; + + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + + ret = fusion_skirmish_prevail( &pool->lock ); + if (ret) { + D_DERROR( ret, "Fusion/SHM: Could not lock shared memory pool!\n" ); + return; + } + + if (pool->allocs) { + direct_log_printf( NULL, "\nShared memory allocations remaining (%d) in '%s': \n", + direct_list_count_elements_EXPENSIVE( pool->allocs ), pool->name ); + + direct_list_foreach (desc, pool->allocs) { + direct_log_printf( NULL, " %9zu bytes at %p [%8lu] in %-30s [%3lx] (%s: %u)\n", + desc->bytes, desc->mem, (ulong)desc->mem - (ulong)pool->heap, + desc->func, desc->fid, desc->file, desc->line ); + + total += desc->bytes; + } + + direct_log_printf( NULL, " -------\n %7dk total\n", total >> 10 ); + direct_log_printf( NULL, "\nShared memory file size: %dk\n", pool->heap->size >> 10 ); + } + + fusion_skirmish_dismiss( &pool->lock ); +} + +static SHMemDesc * +fill_shmem_desc( SHMemDesc *desc, int bytes, const char *func, const char *file, int line, FusionID fusion_id ) +{ + D_ASSERT( desc != NULL ); + + desc->mem = desc + 1; + desc->bytes = bytes; + + snprintf( desc->func, SHMEMDESC_FUNC_NAME_LENGTH, func ); + snprintf( desc->file, SHMEMDESC_FILE_NAME_LENGTH, file ); + + desc->line = line; + desc->fid = fusion_id; + + return desc; +} + +/* Allocate SIZE bytes of memory. */ +void * +fusion_dbg_shmalloc( FusionSHMPoolShared *pool, + const char *file, int line, + const char *func, size_t __size ) +{ + DirectResult ret; + SHMemDesc *desc; + void *data = NULL; + + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( file != NULL ); + D_ASSERT( line > 0 ); + D_ASSERT( func != NULL ); + D_ASSERT( __size > 0 ); + + if (!pool->debug) + return fusion_shmalloc( pool, __size ); + + /* Lock the pool. */ + ret = fusion_skirmish_prevail( &pool->lock ); + if (ret) { + D_DERROR( ret, "Fusion/SHM: Could not lock shared memory pool!\n" ); + return NULL; + } + + /* Allocate memory from the pool. */ + ret = fusion_shm_pool_allocate( pool, __size + sizeof(SHMemDesc), false, false, &data ); + if (ret) { + D_DERROR( ret, "Fusion/SHM: Could not allocate %zu bytes from pool!\n", __size + sizeof(SHMemDesc) ); + fusion_skirmish_dismiss( &pool->lock ); + return NULL; + } + + /* Fill description. */ + desc = fill_shmem_desc( data, __size, func, file, line, _fusion_id(pool->shm->world) ); + + D_DEBUG_AT( Fusion_SHM, "allocating %9zu bytes at %p [%8lu] in %-30s [%3lx] (%s: %u)\n", + desc->bytes, desc->mem, (ulong)desc->mem - (ulong)pool->heap, + desc->func, desc->fid, desc->file, desc->line ); + + /* Add description to list. */ + direct_list_append( &pool->allocs, &desc->link ); + + /* Unlock the pool. */ + fusion_skirmish_dismiss( &pool->lock ); + + return data + sizeof(SHMemDesc); +} + +/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ +void * +fusion_dbg_shcalloc( FusionSHMPoolShared *pool, + const char *file, int line, + const char *func, size_t __nmemb, size_t __size) +{ + DirectResult ret; + SHMemDesc *desc; + void *data = NULL; + + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( file != NULL ); + D_ASSERT( line > 0 ); + D_ASSERT( func != NULL ); + D_ASSERT( __nmemb > 0 ); + D_ASSERT( __size > 0 ); + + if (!pool->debug) + return fusion_shcalloc( pool, __nmemb, __size ); + + /* Lock the pool. */ + ret = fusion_skirmish_prevail( &pool->lock ); + if (ret) { + D_DERROR( ret, "Fusion/SHM: Could not lock shared memory pool!\n" ); + return NULL; + } + + /* Allocate memory from the pool. */ + ret = fusion_shm_pool_allocate( pool, __nmemb * __size + sizeof(SHMemDesc), true, false, &data ); + if (ret) { + D_DERROR( ret, "Fusion/SHM: Could not allocate %zu bytes from pool!\n", __nmemb * __size + sizeof(SHMemDesc) ); + fusion_skirmish_dismiss( &pool->lock ); + return NULL; + } + + /* Fill description. */ + desc = fill_shmem_desc( data, __nmemb * __size, func, file, line, _fusion_id(pool->shm->world) ); + + D_DEBUG_AT( Fusion_SHM, "allocating %9zu bytes at %p [%8lu] in %-30s [%3lx] (%s: %u)\n", + desc->bytes, desc->mem, (ulong)desc->mem - (ulong)pool->heap, + desc->func, desc->fid, desc->file, desc->line ); + + /* Add description to list. */ + direct_list_append( &pool->allocs, &desc->link ); + + /* Unlock the pool. */ + fusion_skirmish_dismiss( &pool->lock ); + + return data + sizeof(SHMemDesc); +} + +/* Re-allocate the previously allocated block + in __ptr, making the new block SIZE bytes long. */ +void * +fusion_dbg_shrealloc( FusionSHMPoolShared *pool, + const char *file, int line, + const char *func, const char *what, void *__ptr, + size_t __size ) +{ + DirectResult ret; + SHMemDesc *desc; + void *data = NULL; + + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( file != NULL ); + D_ASSERT( line > 0 ); + D_ASSERT( func != NULL ); + D_ASSERT( what != NULL ); + + if (!pool->debug) + return fusion_shrealloc( pool, __ptr, __size ); + + if (!__ptr) + return fusion_dbg_shmalloc( pool, file, line, func, __size ); + + if (!__size) { + fusion_dbg_shfree( pool, file, line, func, what, __ptr ); + return NULL; + } + + /* Lock the pool. */ + ret = fusion_skirmish_prevail( &pool->lock ); + if (ret) { + D_DERROR( ret, "Fusion/SHM: Could not lock shared memory pool!\n" ); + return NULL; + } + + /* Lookup the corresponding description. */ + direct_list_foreach (desc, pool->allocs) { + if (desc->mem == __ptr) + break; + } + + if (!desc) { + D_ERROR( "Fusion/SHM: Cannot reallocate unknown chunk at %p (%s) from [%s:%d in %s()]!\n", + __ptr, what, file, line, func ); + D_BREAK( "unknown chunk" ); + return NULL; /* shouldn't happen due to the break */ + } + + /* Remove the description in case the block moves. */ + direct_list_remove( &pool->allocs, &desc->link ); + + /* Reallocate the memory block. */ + ret = fusion_shm_pool_reallocate( pool, __ptr - sizeof(SHMemDesc), __size + sizeof(SHMemDesc), false, &data ); + if (ret) { + D_DERROR( ret, "Fusion/SHM: Could not reallocate from %zu to %zu bytes!\n", + desc->bytes + sizeof(SHMemDesc), __size + sizeof(SHMemDesc) ); + fusion_skirmish_dismiss( &pool->lock ); + return NULL; + } + + /* Fill description. */ + desc = fill_shmem_desc( data, __size, func, file, line, _fusion_id(pool->shm->world) ); + + D_DEBUG_AT( Fusion_SHM, "reallocating %9zu bytes at %p [%8lu] in %-30s [%3lx] (%s: %u) '%s'\n", + desc->bytes, desc->mem, (ulong)desc->mem - (ulong)pool->heap, + desc->func, desc->fid, desc->file, desc->line, what ); + + /* Add description to list. */ + direct_list_append( &pool->allocs, &desc->link ); + + /* Unlock the pool. */ + fusion_skirmish_dismiss( &pool->lock ); + + return data + sizeof(SHMemDesc); +} + +/* Free a block allocated by `shmalloc', `shrealloc' or `shcalloc'. */ +void +fusion_dbg_shfree( FusionSHMPoolShared *pool, + const char *file, int line, + const char *func, const char *what, void *__ptr ) +{ + DirectResult ret; + SHMemDesc *desc; + + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( file != NULL ); + D_ASSERT( line > 0 ); + D_ASSERT( func != NULL ); + D_ASSERT( what != NULL ); + D_ASSERT( __ptr != NULL ); + + if (!pool->debug) + return fusion_shfree( pool, __ptr ); + + /* Lock the pool. */ + ret = fusion_skirmish_prevail( &pool->lock ); + if (ret) { + D_DERROR( ret, "Fusion/SHM: Could not lock shared memory pool!\n" ); + return; + } + + /* Lookup the corresponding description. */ + direct_list_foreach (desc, pool->allocs) { + if (desc->mem == __ptr) + break; + } + + if (!desc) { + D_ERROR( "Fusion/SHM: Cannot free unknown chunk at %p (%s) from [%s:%d in %s()]!\n", + __ptr, what, file, line, func ); + D_BREAK( "unknown chunk" ); + return; /* shouldn't happen due to the break */ + } + + D_DEBUG_AT( Fusion_SHM, "freeing %9zu bytes at %p [%8lu] in %-30s [%3lx] (%s: %u) '%s'\n", + desc->bytes, desc->mem, (ulong)desc->mem - (ulong)pool->heap, + desc->func, desc->fid, desc->file, desc->line, what ); + + /* Remove the description. */ + direct_list_remove( &pool->allocs, &desc->link ); + + /* Free the memory block. */ + fusion_shm_pool_deallocate( pool, __ptr - sizeof(SHMemDesc), false ); + + /* Unlock the pool. */ + fusion_skirmish_dismiss( &pool->lock ); +} + +/* Duplicate string in shared memory. */ +char * +fusion_dbg_shstrdup( FusionSHMPoolShared *pool, + const char *file, int line, + const char *func, const char *string ) +{ + DirectResult ret; + SHMemDesc *desc; + void *data = NULL; + int length; + + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( file != NULL ); + D_ASSERT( line > 0 ); + D_ASSERT( func != NULL ); + D_ASSERT( string != NULL ); + + if (!pool->debug) + return fusion_shstrdup( pool, string ); + + length = strlen( string ) + 1; + + /* Lock the pool. */ + ret = fusion_skirmish_prevail( &pool->lock ); + if (ret) { + D_DERROR( ret, "Fusion/SHM: Could not lock shared memory pool!\n" ); + return NULL; + } + + /* Allocate memory from the pool. */ + ret = fusion_shm_pool_allocate( pool, length + sizeof(SHMemDesc), false, false, &data ); + if (ret) { + D_DERROR( ret, "Fusion/SHM: Could not allocate %zu bytes from pool!\n", length + sizeof(SHMemDesc) ); + fusion_skirmish_dismiss( &pool->lock ); + return NULL; + } + + /* Fill description. */ + desc = fill_shmem_desc( data, length, func, file, line, _fusion_id(pool->shm->world) ); + + D_DEBUG_AT( Fusion_SHM, "allocating %9zu bytes at %p [%8lu] in %-30s [%3lx] (%s: %u) <- \"%s\"\n", + desc->bytes, desc->mem, (ulong)desc->mem - (ulong)pool->heap, + desc->func, desc->fid, desc->file, desc->line, string ); + + D_DEBUG_AT( Fusion_SHM, " -> allocs: %p\n", pool->allocs ); + + /* Add description to list. */ + direct_list_append( &pool->allocs, &desc->link ); + + /* Unlock the pool. */ + fusion_skirmish_dismiss( &pool->lock ); + + /* Copy string content. */ + direct_memcpy( data + sizeof(SHMemDesc), string, length ); + + return data + sizeof(SHMemDesc); +} + +#else + +void +fusion_dbg_print_memleaks( FusionSHMPoolShared *pool ) +{ +} + +#endif + +/**********************************************************************************************************************/ + +/* Allocate SIZE bytes of memory. */ +void * +fusion_shmalloc( FusionSHMPoolShared *pool, size_t __size ) +{ + void *data = NULL; + + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( __size > 0 ); + + if (pool->debug) + D_WARN( "Fusion/SHMMalloc: Pool runs in debug mode, but access from pure-release is attempted!\n" ); + + if (fusion_shm_pool_allocate( pool, __size, false, true, &data )) + return NULL; + + D_ASSERT( data != NULL ); + + return data; +} + +/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ +void * +fusion_shcalloc( FusionSHMPoolShared *pool, size_t __nmemb, size_t __size ) +{ + void *data = NULL; + + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( __nmemb > 0 ); + D_ASSERT( __size > 0 ); + + if (pool->debug) + D_WARN( "Fusion/SHMMalloc: Pool runs in debug mode, but access from pure-release is attempted!\n" ); + + if (fusion_shm_pool_allocate( pool, __nmemb * __size, true, true, &data )) + return NULL; + + D_ASSERT( data != NULL ); + + return data; +} + +/* Re-allocate the previously allocated block + in __ptr, making the new block SIZE bytes long. */ +void * +fusion_shrealloc( FusionSHMPoolShared *pool, void *__ptr, size_t __size ) +{ + void *data = NULL; + + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + + if (pool->debug) + D_WARN( "Fusion/SHMMalloc: Pool runs in debug mode, but access from pure-release is attempted!\n" ); + + if (!__ptr) + return fusion_shmalloc( pool, __size ); + + if (!__size) { + fusion_shfree( pool, __ptr ); + return NULL; + } + + if (fusion_shm_pool_reallocate( pool, __ptr, __size, true, &data )) + return NULL; + + D_ASSERT( data != NULL || __size == 0 ); + + return data; +} + +/* Free a block allocated by `shmalloc', `shrealloc' or `shcalloc'. */ +void +fusion_shfree( FusionSHMPoolShared *pool, void *__ptr ) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( __ptr != NULL ); + + if (pool->debug) + D_WARN( "Fusion/SHMMalloc: Pool runs in debug mode, but access from pure-release is attempted!\n" ); + + fusion_shm_pool_deallocate( pool, __ptr, true ); +} + +/* Duplicate string in shared memory. */ +char * +fusion_shstrdup( FusionSHMPoolShared *pool, const char* string ) +{ + int len; + void *data = NULL; + + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( string != NULL ); + + if (pool->debug) + D_WARN( "Fusion/SHMMalloc: Pool runs in debug mode, but access from pure-release is attempted!\n" ); + + len = strlen( string ) + 1; + + if (fusion_shm_pool_allocate( pool, len, false, true, &data )) + return NULL; + + D_ASSERT( data != NULL ); + + direct_memcpy( data, string, len ); + + return data; +} + +#else + +/************************** SINGLE APPLICATION CORE ***************************/ + +#include + +void +fusion_dbg_print_memleaks( FusionSHMPoolShared *pool ) +{ +} + +#if DIRECT_BUILD_DEBUGS /* Build with debug support? */ + +/* Allocate SIZE bytes of memory. */ +void * +fusion_dbg_shmalloc( FusionSHMPoolShared *pool, + const char *file, int line, + const char *func, size_t __size ) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( __size > 0 ); + + if (pool->debug) + return direct_malloc( file, line, func, __size ); + + return malloc( __size ); +} + +/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ +void * +fusion_dbg_shcalloc( FusionSHMPoolShared *pool, + const char *file, int line, + const char *func, size_t __nmemb, size_t __size) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( __nmemb > 0 ); + D_ASSERT( __size > 0 ); + + if (pool->debug) + return direct_calloc( file, line, func, __nmemb, __size ); + + return calloc( __nmemb, __size ); +} + +/* Re-allocate the previously allocated block + in __ptr, making the new block SIZE bytes long. */ +void * +fusion_dbg_shrealloc( FusionSHMPoolShared *pool, + const char *file, int line, + const char *func, const char *what, void *__ptr, + size_t __size ) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + + if (pool->debug) + return direct_realloc( file, line, func, what, __ptr, __size ); + + return realloc( __ptr, __size ); +} + +/* Free a block allocated by `shmalloc', `shrealloc' or `shcalloc'. */ +void +fusion_dbg_shfree( FusionSHMPoolShared *pool, + const char *file, int line, + const char *func, const char *what, void *__ptr ) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( __ptr != NULL ); + + if (pool->debug) + direct_free( file, line, func, what, __ptr ); + else + free( __ptr ); +} + +/* Duplicate string in shared memory. */ +char * +fusion_dbg_shstrdup( FusionSHMPoolShared *pool, + const char *file, int line, + const char *func, const char *string ) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( string != NULL ); + + if (pool->debug) + return direct_strdup( file, line, func, string ); + + return strdup( string ); +} + +#endif + +/**********************************************************************************************************************/ + +/* Allocate SIZE bytes of memory. */ +void * +fusion_shmalloc (FusionSHMPoolShared *pool, + size_t __size) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( __size > 0 ); + + if (pool->debug) + D_WARN( "Fusion/SHMMalloc: Pool runs in debug mode, but access from pure-release is attempted!\n" ); + + return malloc( __size ); +} + +/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */ +void * +fusion_shcalloc (FusionSHMPoolShared *pool, + size_t __nmemb, size_t __size) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( __nmemb > 0 ); + D_ASSERT( __size > 0 ); + + if (pool->debug) + D_WARN( "Fusion/SHMMalloc: Pool runs in debug mode, but access from pure-release is attempted!\n" ); + + return calloc( __nmemb, __size ); +} + +/* Re-allocate the previously allocated block + in __ptr, making the new block SIZE bytes long. */ +void * +fusion_shrealloc (FusionSHMPoolShared *pool, + void *__ptr, size_t __size) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + + if (pool->debug) + D_WARN( "Fusion/SHMMalloc: Pool runs in debug mode, but access from pure-release is attempted!\n" ); + + return realloc( __ptr, __size ); +} + +/* Free a block allocated by `shmalloc', `shrealloc' or `shcalloc'. */ +void +fusion_shfree (FusionSHMPoolShared *pool, + void *__ptr) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( __ptr != NULL ); + + if (pool->debug) + D_WARN( "Fusion/SHMMalloc: Pool runs in debug mode, but access from pure-release is attempted!\n" ); + + free( __ptr ); +} + +/* Duplicate string in shared memory. */ +char * +fusion_shstrdup (FusionSHMPoolShared *pool, + const char *string) +{ + D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); + D_ASSERT( string != NULL ); + + if (pool->debug) + D_WARN( "Fusion/SHMMalloc: Pool runs in debug mode, but access from pure-release is attempted!\n" ); + + return strdup( string ); +} + +#endif + -- cgit