} 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;
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();
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;
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;
}
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;
}
}
}
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
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;
}
}
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);
}
} 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);
} 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;
}
/* Allocate a mutex */
-TSRM_API MUTEX_T tsrm_mutex_alloc( void )
+TSRM_API MUTEX_T tsrm_mutex_alloc(void)
{
MUTEX_T mutexp;
/* 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
/* 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;
/* 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;
* 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;
}
-void tsrm_debug_set(int status)
+void tsrm_error_set(int level)
{
- tsrm_debug_status = status;
+ tsrm_error_level = level;
}
#endif /* ZTS */