diff options
author | Dmitry Stogov <dmitry@zend.com> | 2019-03-14 03:01:01 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2019-03-14 03:01:01 +0300 |
commit | 9499484ed2f0377678b2b4d88573327ee0e4ce6d (patch) | |
tree | 2253189b70e711565902d2c372fe5d93ce111358 /TSRM | |
parent | a1b7bc0c8148eaf728fccdffe147e3bc0c03f18e (diff) | |
download | php-git-9499484ed2f0377678b2b4d88573327ee0e4ce6d.tar.gz |
Implemented a faster way to access predefined TSRM resources - CG(), EG(), etc.
Diffstat (limited to 'TSRM')
-rw-r--r-- | TSRM/TSRM.c | 147 | ||||
-rw-r--r-- | TSRM/TSRM.h | 16 |
2 files changed, 136 insertions, 27 deletions
diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index 67f6722945..670c260678 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -34,6 +34,7 @@ typedef struct { size_t size; ts_allocate_ctor ctor; ts_allocate_dtor dtor; + size_t fast_offset; int done; } tsrm_resource_type; @@ -47,6 +48,9 @@ static ts_rsrc_id id_count; static tsrm_resource_type *resource_types_table=NULL; static int resource_types_table_size; +/* Reserved space for fast globals access */ +static size_t tsrm_reserved_pos = 0; +static size_t tsrm_reserved_size = 0; static MUTEX_T tsmm_mutex; /* thread-safe memory manager mutex */ @@ -160,6 +164,10 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu tsmm_mutex = tsrm_mutex_alloc(); TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Started up TSRM, %d expected threads, %d expected resources", expected_threads, expected_resources)); + + tsrm_reserved_pos = 0; + tsrm_reserved_size = 0; + return 1; }/*}}}*/ @@ -187,7 +195,9 @@ TSRM_API void tsrm_shutdown(void) if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) { resource_types_table[j].dtor(p->storage[j]); } - free(p->storage[j]); + if (!resource_types_table[j].fast_offset) { + free(p->storage[j]); + } } } free(p->storage); @@ -222,14 +232,46 @@ TSRM_API void tsrm_shutdown(void) tsrm_new_thread_begin_handler = NULL; tsrm_new_thread_end_handler = NULL; tsrm_shutdown_handler = NULL; + + tsrm_reserved_pos = 0; + tsrm_reserved_size = 0; }/*}}}*/ -/* 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) +/* enlarge the arrays for the already active threads */ +static void tsrm_update_active_threads(void) {/*{{{*/ int i; + for (i=0; i<tsrm_tls_table_size; i++) { + tsrm_tls_entry *p = tsrm_tls_table[i]; + + while (p) { + if (p->count < id_count) { + int j; + + p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count); + for (j=p->count; j<id_count; j++) { + if (resource_types_table[j].fast_offset) { + p->storage[j] = (void *) (((char*)p) + resource_types_table[j].fast_offset); + } else { + 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->count = id_count; + } + p = p->next; + } + } +}/*}}}*/ + + +/* 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_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size)); tsrm_mutex_lock(tsmm_mutex); @@ -254,28 +296,68 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate 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; + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].fast_offset = 0; resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0; - /* enlarge the arrays for the already active threads */ - for (i=0; i<tsrm_tls_table_size; i++) { - tsrm_tls_entry *p = tsrm_tls_table[i]; + tsrm_update_active_threads(); + tsrm_mutex_unlock(tsmm_mutex); - while (p) { - if (p->count < id_count) { - int j; + TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id)); + return *rsrc_id; +}/*}}}*/ - p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count); - 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->count = id_count; - } - p = p->next; + +/* Reserve space for fast thread-safe-resources */ +TSRM_API void tsrm_reserve(size_t size) +{/*{{{*/ + tsrm_reserved_pos = 0; + tsrm_reserved_size = TSRM_ALIGNED_SIZE(size); +}/*}}}*/ + + +/* allocates a new fast thread-safe-resource id */ +TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor) +{/*{{{*/ + TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new fast resource id, %d bytes", size)); + + tsrm_mutex_lock(tsmm_mutex); + + /* obtain a resource id */ + *rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++); + TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id)); + + size = TSRM_ALIGNED_SIZE(size); + if (tsrm_reserved_size - tsrm_reserved_pos < size) { + tsrm_mutex_unlock(tsmm_mutex); + TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate space for fast resource")); + *rsrc_id = 0; + *offset = 0; + return 0; + } + + *offset = TSRM_ALIGNED_SIZE(sizeof(tsrm_tls_entry)) + tsrm_reserved_pos; + tsrm_reserved_pos += size; + + /* store the new resource type in the resource sizes table */ + if (resource_types_table_size < id_count) { + tsrm_resource_type *_tmp; + _tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count); + if (!_tmp) { + tsrm_mutex_unlock(tsmm_mutex); + TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource")); + *rsrc_id = 0; + return 0; } + resource_types_table = _tmp; + resource_types_table_size = id_count; } + 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; + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].fast_offset = *offset; + resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0; + + tsrm_update_active_threads(); tsrm_mutex_unlock(tsmm_mutex); TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id)); @@ -288,7 +370,7 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_ int i; 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) = (tsrm_tls_entry *) malloc(TSRM_ALIGNED_SIZE(sizeof(tsrm_tls_entry)) + tsrm_reserved_size); (*thread_resources_ptr)->storage = NULL; if (id_count > 0) { (*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count); @@ -307,9 +389,12 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_ 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); + } else { + if (resource_types_table[i].fast_offset) { + (*thread_resources_ptr)->storage[i] = (void *) (((char*)(*thread_resources_ptr)) + resource_types_table[i].fast_offset); + } 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]); } @@ -402,7 +487,9 @@ void tsrm_free_interpreter_context(void *context) } } for (i=0; i<thread_resources->count; i++) { - free(thread_resources->storage[i]); + if (!resource_types_table[i].fast_offset) { + free(thread_resources->storage[i]); + } } free(thread_resources->storage); free(thread_resources); @@ -467,7 +554,9 @@ void ts_free_thread(void) } } for (i=0; i<thread_resources->count; i++) { - free(thread_resources->storage[i]); + if (!resource_types_table[i].fast_offset) { + free(thread_resources->storage[i]); + } } free(thread_resources->storage); if (last) { @@ -509,7 +598,9 @@ void ts_free_worker_threads(void) } } for (i=0; i<thread_resources->count; i++) { - free(thread_resources->storage[i]); + if (!resource_types_table[i].fast_offset) { + free(thread_resources->storage[i]); + } } free(thread_resources->storage); if (last) { @@ -553,7 +644,9 @@ void ts_free_id(ts_rsrc_id id) if (resource_types_table && resource_types_table[j].dtor) { resource_types_table[j].dtor(p->storage[j]); } - free(p->storage[j]); + if (!resource_types_table[j].fast_offset) { + free(p->storage[j]); + } p->storage[j] = NULL; } p = p->next; diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index 061459e77d..a14e31e1f0 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -57,6 +57,14 @@ typedef uintptr_t tsrm_uintptr_t; #include <TLS.h> #endif +#if SIZEOF_SIZE_T == 4 +# define TSRM_ALIGNED_SIZE(size) \ + (((size) + INT32_C(15)) & ~INT32_C(15)) +#else +# define TSRM_ALIGNED_SIZE(size) \ + (((size) + INT64_C(15)) & ~INT64_C(15)) +#endif + typedef int ts_rsrc_id; /* Define THREAD_T and MUTEX_T */ @@ -94,6 +102,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); +/* Fast resource in reserved (pre-allocated) space */ +TSRM_API void tsrm_reserve(size_t size); +TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor); + /* fetches the requested resource for the current thread */ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id); #define ts_resource(id) ts_resource_ex(id, NULL) @@ -162,9 +174,13 @@ TSRM_API const char *tsrm_api_name(void); #define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_get_ls_cache() #define TSRMG(id, type, element) (TSRMG_BULK(id, type)->element) #define TSRMG_BULK(id, type) ((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)]) +#define TSRMG_FAST(offset, type, element) (TSRMG_FAST_BULK(offset, type)->element) +#define TSRMG_FAST_BULK(offset, type) ((type) (((char*) tsrm_get_ls_cache())+(offset))) #define TSRMG_STATIC(id, type, element) (TSRMG_BULK_STATIC(id, type)->element) #define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)]) +#define TSRMG_FAST_STATIC(offset, type, element) (TSRMG_FAST_BULK_STATIC(offset, type)->element) +#define TSRMG_FAST_BULK_STATIC(offset, type) ((type) (((char*) TSRMLS_CACHE)+(offset))) #define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE; #define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL; #if ZEND_DEBUG |