diff options
author | krakjoe <joe.watkins@live.co.uk> | 2014-09-20 20:22:14 +0100 |
---|---|---|
committer | krakjoe <joe.watkins@live.co.uk> | 2014-09-20 20:22:14 +0100 |
commit | b3aebda9eaf55706af2e21178f229a171725a168 (patch) | |
tree | 9aa1794dc4b513d5c0077adcbeb89fa215f181a4 /TSRM/TSRM.c | |
parent | 763bfb4f3b0e66d5a961f9f367aa86e9f9da262e (diff) | |
download | php-git-b3aebda9eaf55706af2e21178f229a171725a168.tar.gz |
native tls initial patch
Diffstat (limited to 'TSRM/TSRM.c')
-rw-r--r-- | TSRM/TSRM.c | 138 |
1 files changed, 88 insertions, 50 deletions
diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index efdea5c880..32c28993f8 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -23,7 +23,7 @@ typedef struct _tsrm_tls_entry tsrm_tls_entry; struct _tsrm_tls_entry { - void **storage; + void *storage; int count; THREAD_T thread_id; tsrm_tls_entry *next; @@ -31,6 +31,7 @@ struct _tsrm_tls_entry { typedef struct { + ts_rsrc_offset offset; size_t size; ts_allocate_ctor ctor; ts_allocate_dtor dtor; @@ -42,7 +43,7 @@ typedef struct { static tsrm_tls_entry **tsrm_tls_table=NULL; static int tsrm_tls_table_size; static ts_rsrc_id id_count; - +static size_t rsrcs_size; /* The resource sizes table */ static tsrm_resource_type *resource_types_table=NULL; static int resource_types_table_size; @@ -61,31 +62,62 @@ int tsrm_error(int level, const char *format, ...); static int tsrm_error_level; static FILE *tsrm_error_file; +#ifdef USE___THREAD +TSRM_API TSRM_TLS void *tsrm_ls_cache = 0; +#endif + +#ifdef PASS_TSRMLS +# define CALL_TSRMG_CTOR(ctor, globale, storage) (ctor)((globale), (storage)) +# define CALL_TSRMG_DTOR(ctor, globale, storage) (ctor)((globale), (storage)) +# define CALL_NEW_THREAD_BEGIN_HANDLER(thread_id, storage) tsrm_new_thread_begin_handler((thread_id), (storage)) +# define CALL_NEW_THREAD_END_HANDLER(thread_id, storage) tsrm_new_thread_end_handler((thread_id), (storage)) +#else +# define CALL_TSRMG_CTOR(ctor, globale, storage) (ctor)((globale)) +# define CALL_TSRMG_DTOR(ctor, globale, storage) (ctor)((globale)) +# define CALL_NEW_THREAD_BEGIN_HANDLER(thread_id, storage) tsrm_new_thread_begin_handler((thread_id)) +# define CALL_NEW_THREAD_END_HANDLER(thread_id, storage) tsrm_new_thread_end_handler((thread_id)) +#endif + +#ifndef TSRM_MM_ALIGNMENT +# define TSRM_MM_ALIGNMENT 8 +#elif TSRM_MM_ALIGNMENT < 4 +# undef TSRM_MM_ALIGNMENT +# define TSRM_MM_ALIGNMENT 8 +#endif + +#define TSRMG_PTR(storage, offset) ((void *)((tsrm_uintptr_t)storage + offset)) + +#ifdef USE___THREAD +# define TSRM_RETURN_TSRM_LS(array) array +#else +# define TSRM_RETURN_TSRM_LS(array) &array +#endif + #if TSRM_DEBUG #define TSRM_ERROR(args) tsrm_error args -#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \ +#define TSRM_SAFE_RETURN_RSRC(array, id, range) \ { \ - int unshuffled_offset = TSRM_UNSHUFFLE_RSRC_ID(offset); \ + int unshuffled_id = TSRM_UNSHUFFLE_RSRC_ID(id); \ \ - if (offset==0) { \ - return &array; \ - } else if ((unshuffled_offset)>=0 && (unshuffled_offset)<(range)) { \ + if (id==0) { \ + return TSRM_RETURN_TSRM_LS(array); \ + } else if ((unshuffled_id)>=0 && (unshuffled_id)<(range)) { \ TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Successfully fetched resource id %d for thread id %ld - 0x%0.8X", \ - unshuffled_offset, (long) thread_resources->thread_id, array[unshuffled_offset])); \ - return array[unshuffled_offset]; \ + unshuffled_id, (long) thread_resources->thread_id, TSRMG_PTR(array, resource_types_table[unshuffled_id].offset))); \ + return TSRMG_PTR(array, resource_types_table[unshuffled_id].offset); \ } else { \ TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Resource id %d is out of range (%d..%d)", \ - unshuffled_offset, TSRM_SHUFFLE_RSRC_ID(0), TSRM_SHUFFLE_RSRC_ID(thread_resources->count-1))); \ + unshuffled_id, TSRM_SHUFFLE_RSRC_ID(0), TSRM_SHUFFLE_RSRC_ID(thread_resources->count-1))); \ return NULL; \ } \ } #else #define TSRM_ERROR(args) -#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \ - if (offset==0) { \ - return &array; \ - } else { \ - return array[TSRM_UNSHUFFLE_RSRC_ID(offset)]; \ +#define TSRM_SAFE_RETURN_RSRC(array, id, range) \ + if (id==0) { \ + return TSRM_RETURN_TSRM_LS(array); \ + } else { \ + return TSRMG_PTR(array, resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(id)].offset); \ } #endif @@ -175,12 +207,9 @@ TSRM_API void tsrm_shutdown(void) next_p = p->next; for (j=0; j<p->count; j++) { - if (p->storage[j]) { - if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) { - resource_types_table[j].dtor(p->storage[j], &p->storage); - } - free(p->storage[j]); - } + if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) { + CALL_TSRMG_CTOR(resource_types_table[j].dtor, TSRMG_PTR(p->storage, resource_types_table[j].offset), &p->storage); + } } free(p->storage); free(p); @@ -212,9 +241,10 @@ TSRM_API void tsrm_shutdown(void) /* allocates a new thread-safe-resource id */ -TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor) +TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, ts_rsrc_offset *rsrc_offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor) { int i; + ts_rsrc_offset offset = 0; TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size)); @@ -235,6 +265,17 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate } resource_types_table_size = id_count; } + + if (TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id) > 0) { + offset = resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id-1)].offset + +resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id-1)].size; + } + offset = ((TSRM_MM_ALIGNMENT + offset - 1) & ~(TSRM_MM_ALIGNMENT - 1)); + if (rsrc_offset) { + *rsrc_offset = offset; + } + + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].offset = offset; resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size; resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor; resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor; @@ -248,11 +289,13 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate if (p->count < id_count) { int j; - p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count); + p->storage = realloc(p->storage, offset + size); +#ifdef USE___THREAD + tsrm_ls_cache = p->storage; +#endif for (j=p->count; j<id_count; j++) { - p->storage[j] = (void *) malloc(resource_types_table[j].size); if (resource_types_table[j].ctor) { - resource_types_table[j].ctor(p->storage[j], &p->storage); + CALL_TSRMG_CTOR(resource_types_table[j].ctor, TSRMG_PTR(p->storage, resource_types_table[j].offset), &p->storage); } } p->count = id_count; @@ -260,9 +303,10 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate p = p->next; } } + rsrcs_size = offset + size; tsrm_mutex_unlock(tsmm_mutex); - TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id)); + TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d, offset %u", *rsrc_id, *rsrc_offset)); return *rsrc_id; } @@ -273,7 +317,7 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_ TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id)); (*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry)); - (*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count); + (*thread_resources_ptr)->storage = malloc(rsrcs_size); (*thread_resources_ptr)->count = id_count; (*thread_resources_ptr)->thread_id = thread_id; (*thread_resources_ptr)->next = NULL; @@ -281,23 +325,23 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_ /* Set thread local storage to this new thread resources structure */ tsrm_tls_set(*thread_resources_ptr); +#ifdef USE___THREAD + tsrm_ls_cache = (*thread_resources_ptr)->storage; +#endif + if (tsrm_new_thread_begin_handler) { - tsrm_new_thread_begin_handler(thread_id, &((*thread_resources_ptr)->storage)); + CALL_NEW_THREAD_BEGIN_HANDLER(thread_id, &(*thread_resources_ptr)->storage); } for (i=0; i<id_count; i++) { if (resource_types_table[i].done) { - (*thread_resources_ptr)->storage[i] = NULL; - } else - { - (*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size); if (resource_types_table[i].ctor) { - resource_types_table[i].ctor((*thread_resources_ptr)->storage[i], &(*thread_resources_ptr)->storage); + CALL_TSRMG_CTOR(resource_types_table[i].ctor, TSRMG_PTR((*thread_resources_ptr)->storage, resource_types_table[i].offset), &(*thread_resources_ptr)->storage); } } } if (tsrm_new_thread_end_handler) { - tsrm_new_thread_end_handler(thread_id, &((*thread_resources_ptr)->storage)); + CALL_NEW_THREAD_END_HANDLER(thread_id, &(*thread_resources_ptr)->storage); } tsrm_mutex_unlock(tsmm_mutex); @@ -390,12 +434,10 @@ void tsrm_free_interpreter_context(void *context) for (i=0; i<thread_resources->count; i++) { if (resource_types_table[i].dtor) { - resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage); + CALL_TSRMG_DTOR(resource_types_table[i].dtor, TSRMG_PTR(thread_resources->storage, resource_types_table[i].offset), &thread_resources->storage); } } - for (i=0; i<thread_resources->count; i++) { - free(thread_resources->storage[i]); - } + free(thread_resources->storage); free(thread_resources); thread_resources = next; @@ -413,6 +455,10 @@ void *tsrm_set_interpreter_context(void *new_ctx) /* Set thread local storage to this new thread resources structure */ tsrm_tls_set(new_ctx); + +#ifdef USE___THREAD + tsrm_ls_cache = ((tsrm_tls_entry*)new_ctx)->storage; +#endif /* return old context, so caller can restore it when they're done */ return current; @@ -455,12 +501,9 @@ void ts_free_thread(void) if (thread_resources->thread_id == thread_id) { for (i=0; i<thread_resources->count; i++) { if (resource_types_table[i].dtor) { - resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage); + CALL_TSRMG_DTOR(resource_types_table[i].dtor, TSRMG_PTR(thread_resources->storage, resource_types_table[i].offset), &thread_resources->storage); } } - for (i=0; i<thread_resources->count; i++) { - free(thread_resources->storage[i]); - } free(thread_resources->storage); if (last) { last->next = thread_resources->next; @@ -497,12 +540,9 @@ void ts_free_worker_threads(void) if (thread_resources->thread_id != thread_id) { for (i=0; i<thread_resources->count; i++) { if (resource_types_table[i].dtor) { - resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage); + CALL_TSRMG_DTOR(resource_types_table[i].dtor, TSRMG_PTR(thread_resources->storage, resource_types_table[i].offset), &thread_resources->storage); } } - for (i=0; i<thread_resources->count; i++) { - free(thread_resources->storage[i]); - } free(thread_resources->storage); if (last) { last->next = thread_resources->next; @@ -541,12 +581,10 @@ void ts_free_id(ts_rsrc_id id) tsrm_tls_entry *p = tsrm_tls_table[i]; while (p) { - if (p->count > j && p->storage[j]) { + if (p->count > j) { if (resource_types_table && resource_types_table[j].dtor) { - resource_types_table[j].dtor(p->storage[j], &p->storage); + CALL_TSRMG_DTOR(resource_types_table[j].dtor, TSRMG_PTR(p->storage, resource_types_table[j].offset), &p->storage); } - free(p->storage[j]); - p->storage[j] = NULL; } p = p->next; } |