diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index b8b03cf7ae2..163da42d0e5 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -38,13 +38,16 @@ typedef struct { } tsrm_resource_type; +#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1) +#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1) + /* The memory manager table */ -static tsrm_tls_entry **tsrm_tls_table; +static tsrm_tls_entry **tsrm_tls_table=NULL; static int tsrm_tls_table_size; static ts_rsrc_id id_count; /* The resource sizes table */ -static tsrm_resource_type *resource_types_table; +static tsrm_resource_type *resource_types_table=NULL; static int resource_types_table_size; @@ -55,12 +58,18 @@ static void (*tsrm_new_thread_begin_handler)(); static void (*tsrm_new_thread_end_handler)(); /* Debug support */ -static int tsrm_debug(const char *format, ...); -static int tsrm_debug_status; - +static int tsrm_error(int level, const char *format, ...); +static int tsrm_error_level; +#if TSRM_ERROR +#define TSRM_ERROR tsrm_error +#define TSRM_SAFE_ARRAY_OFFSET(array, offset, range) (((offset)>=0 && (offset)<(range)) ? array[offset] : NULL) +#else +#define TSRM_ERROR +#define TSRM_SAFE_ARRAY_OFFSET(array, offset, range) array[offset] +#endif /* Startup TSRM (call once for the entire process) */ -TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_status) +TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level) { #if defined(GNUPTH) pth_init(); @@ -69,6 +78,7 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu tsrm_tls_table_size = expected_threads; tsrm_tls_table = (tsrm_tls_entry **) calloc(tsrm_tls_table_size, sizeof(tsrm_tls_entry *)); if (!tsrm_tls_table) { + TSRM_ERROR(TSRM_ERROR_LEVEL_ERROR, "Unable to allocate TLS table"); return 0; } id_count=0; @@ -76,7 +86,9 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu resource_types_table_size = expected_resources; resource_types_table = (tsrm_resource_type *) calloc(resource_types_table_size, sizeof(tsrm_resource_type)); if (!resource_types_table) { + TSRM_ERROR(TSRM_ERROR_LEVEL_ERROR, "Unable to allocate resource types table"); free(tsrm_tls_table); + tsrm_tls_table = NULL; return 0; } @@ -84,9 +96,9 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu tsrm_new_thread_begin_handler = tsrm_new_thread_end_handler = NULL; - tsrm_debug_status = debug_status; + tsrm_error_level = debug_level; - tsrm_debug("Started up TSRM, %d expected threads, %d expected resources\n", expected_threads, expected_resources); + TSRM_ERROR(TSRM_ERROR_LEVEL_INFO, "Started up TSRM, %d expected threads, %d expected resources\n", expected_threads, expected_resources); return 1; } @@ -113,12 +125,15 @@ TSRM_API void tsrm_shutdown(void) } } free(tsrm_tls_table); + tsrm_tls_table = NULL; } if (resource_types_table) { free(resource_types_table); + resource_types_table=NULL; } tsrm_mutex_free(tsmm_mutex); - tsrm_debug("Shutdown TSRM\n"); + tsmm_mutex = NULL; + TSRM_ERROR(TSRM_ERROR_LEVEL_INFO, "Shutdown TSRM\n"); #if defined(GNUPTH) pth_kill(); #endif @@ -131,19 +146,21 @@ TSRM_API ts_rsrc_id ts_allocate_id(size_t size, ts_allocate_ctor ctor, ts_alloca ts_rsrc_id new_id; int i; - tsrm_debug("Obtaining a new resource id, %d bytes\n", size); + TSRM_ERROR(TSRM_ERROR_LEVEL_INFO, "Obtaining a new resource id, %d bytes\n", size); tsrm_mutex_lock(tsmm_mutex); /* obtain a resource id */ new_id = id_count++; - tsrm_debug("Obtained resource id %d\n", new_id); + TSRM_ERROR(TSRM_ERROR_LEVEL_INFO, "Obtained resource id %d\n", new_id); /* store the new resource type in the resource sizes table */ if (resource_types_table_size < id_count) { resource_types_table = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count); if (!resource_types_table) { - return -1; + tsrm_mutex_unlock(tsmm_mutex); + TSRM_ERROR(TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"); + return 0; } resource_types_table_size = id_count; } @@ -173,8 +190,8 @@ TSRM_API ts_rsrc_id ts_allocate_id(size_t size, ts_allocate_ctor ctor, ts_alloca } tsrm_mutex_unlock(tsmm_mutex); - tsrm_debug("Successfully allocated new resource id %d\n", new_id); - return new_id; + TSRM_ERROR(TSRM_ERROR_LEVEL_INFO, "Successfully allocated new resource id %d\n", new_id); + return TSRM_SHUFFLE_RSRC_ID(new_id); } @@ -218,7 +235,7 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id) } else { thread_id = tsrm_thread_id(); } - tsrm_debug("Fetching resource id %d for thread %ld\n", id, (long) thread_id); + TSRM_ERROR(TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for thread %ld\n", id, (long) thread_id); tsrm_mutex_lock(tsmm_mutex); hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size); @@ -246,11 +263,15 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id) } while (thread_resources); } - resource = thread_resources->storage[id]; + resource = TSRM_SAFE_ARRAY_OFFSET(thread_resources->storage, TSRM_UNSHUFFLE_RSRC_ID(id), thread_resources->count); tsrm_mutex_unlock(tsmm_mutex); - tsrm_debug("Successfully fetched resource id %d for thread id %ld - %x\n", id, (long) thread_id, (long) resource); + if (resource) { + TSRM_ERROR(TSRM_ERROR_LEVEL_INFO, "Successfully fetched resource id %d for thread id %ld - %x\n", id, (long) thread_id, (long) resource); + } else { + TSRM_ERROR(TSRM_ERROR_LEVEL_ERROR, "Resource id %d is out of range (%d..%d)", id, TSRM_SHUFFLE_RSRC_ID(0), TSRM_SHUFFLE_RSRC_ID(thread_resources->count-1)); + } return resource; } @@ -325,7 +346,7 @@ TSRM_API THREAD_T tsrm_thread_id(void) /* Allocate a mutex */ -TSRM_API MUTEX_T tsrm_mutex_alloc( void ) +TSRM_API MUTEX_T tsrm_mutex_alloc(void) { MUTEX_T mutexp; @@ -351,7 +372,7 @@ TSRM_API MUTEX_T tsrm_mutex_alloc( void ) /* Free a mutex */ -TSRM_API void tsrm_mutex_free( MUTEX_T mutexp ) +TSRM_API void tsrm_mutex_free(MUTEX_T mutexp) { if (mutexp) { #ifdef TSRM_WIN32 @@ -374,11 +395,9 @@ TSRM_API void tsrm_mutex_free( MUTEX_T mutexp ) /* Lock a mutex */ -TSRM_API int tsrm_mutex_lock( MUTEX_T mutexp ) +TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp) { -#if 0 - tsrm_debug("Mutex locked thread: %ld\n",tsrm_thread_id()); -#endif + TSRM_ERROR(TSRM_ERROR_LEVEL_INFO, "Mutex locked thread: %ld\n",tsrm_thread_id()); #ifdef TSRM_WIN32 EnterCriticalSection(mutexp); return 1; @@ -395,11 +414,9 @@ TSRM_API int tsrm_mutex_lock( MUTEX_T mutexp ) /* Unlock a mutex */ -TSRM_API int tsrm_mutex_unlock( MUTEX_T mutexp ) +TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp) { -#if 0 - tsrm_debug("Mutex unlocked thread: %ld\n",tsrm_thread_id()); -#endif + TSRM_ERROR(TSRM_ERROR_LEVEL_INFO, "Mutex unlocked thread: %ld\n",tsrm_thread_id()); #ifdef TSRM_WIN32 LeaveCriticalSection(mutexp); return 1; @@ -438,9 +455,9 @@ TSRM_API void *tsrm_set_new_thread_end_handler(void (*new_thread_end_handler)(TH * Debug support */ -static int tsrm_debug(const char *format, ...) +static int tsrm_error(int level, const char *format, ...) { - if (tsrm_debug_status) { + if (level<=tsrm_error_level) { va_list args; int size; @@ -454,9 +471,9 @@ static int tsrm_debug(const char *format, ...) } -void tsrm_debug_set(int status) +void tsrm_error_set(int level) { - tsrm_debug_status = status; + tsrm_error_level = level; } #endif /* ZTS */ diff --git a/TSRM/TSRM.dsp b/TSRM/TSRM.dsp index 0633887cf4a..c61f9b12864 100644 --- a/TSRM/TSRM.dsp +++ b/TSRM/TSRM.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Intermediate_Dir "Debug_TS" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "C:\Projects\TSRM" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=1 /YX /FD /GZ /c # ADD BASE RSC /l 0x40d /d "_DEBUG" # ADD RSC /l 0x40d /d "_DEBUG" BSC32=bscmake.exe @@ -65,7 +65,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Release_TS" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c # ADD BASE RSC /l 0x40d /d "NDEBUG" # ADD RSC /l 0x40d /d "NDEBUG" BSC32=bscmake.exe @@ -88,7 +88,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Release_TS_inline" # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "TSRM_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c # ADD BASE RSC /l 0x40d /d "NDEBUG" # ADD RSC /l 0x40d /d "NDEBUG" BSC32=bscmake.exe diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index b68f07b1338..a9494c40b1c 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -77,7 +77,7 @@ extern "C" { #endif /* startup/shutdown */ -TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_status); +TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level); TSRM_API void tsrm_shutdown(void); /* allocates a new thread-safe-resource id */ @@ -95,7 +95,9 @@ TSRM_API void ts_free_id(ts_rsrc_id id); /* Debug support */ -TSRM_API void tsrm_debug_set(int status); +#define TSRM_ERROR_LEVEL_ERROR 1 +#define TSRM_ERROR_LEVEL_INFO 2 +TSRM_API void tsrm_debug_set(int level); /* utility functions */ TSRM_API THREAD_T tsrm_thread_id(void);