From 9499484ed2f0377678b2b4d88573327ee0e4ce6d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 14 Mar 2019 03:01:01 +0300 Subject: [PATCH] Implemented a faster way to access predefined TSRM resources - CG(), EG(), etc. --- TSRM/TSRM.c | 147 +++++++++++++++++++++++------ TSRM/TSRM.h | 16 ++++ Zend/zend.c | 10 +- Zend/zend.h | 2 + Zend/zend_alloc.c | 12 ++- Zend/zend_alloc.h | 4 + Zend/zend_gc.c | 12 ++- Zend/zend_gc.h | 4 + Zend/zend_globals.h | 2 + Zend/zend_globals_macros.h | 10 +- Zend/zend_ini_scanner.l | 1 + Zend/zend_language_scanner.l | 1 + Zend/zend_signal.c | 3 +- Zend/zend_signal.h | 3 +- Zend/zend_virtual_cwd.c | 3 +- Zend/zend_virtual_cwd.h | 3 +- main/SAPI.c | 3 +- main/SAPI.h | 3 +- main/main.c | 37 +++++++- main/php_globals.h | 3 +- main/php_main.h | 6 ++ sapi/apache2handler/sapi_apache2.c | 3 +- sapi/cgi/cgi_main.c | 3 +- sapi/cli/php_cli.c | 3 +- sapi/embed/php_embed.c | 3 +- sapi/fpm/fpm/fpm_main.c | 7 +- sapi/litespeed/lsapi_main.c | 4 +- sapi/phpdbg/phpdbg.c | 3 +- 28 files changed, 245 insertions(+), 66 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; icount < id_count) { + int j; + + p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count); + for (j=p->count; jstorage[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; icount < 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; jstorage[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; istorage[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; icount; 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; icount; 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; icount; 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 #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 diff --git a/Zend/zend.c b/Zend/zend.c index 542ac9ff1d..2c2bd09081 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -38,6 +38,8 @@ static size_t global_map_ptr_last = 0; #ifdef ZTS ZEND_API int compiler_globals_id; ZEND_API int executor_globals_id; +ZEND_API size_t compiler_globals_offset; +ZEND_API size_t executor_globals_offset; static HashTable *global_function_table = NULL; static HashTable *global_class_table = NULL; static HashTable *global_constants_table = NULL; @@ -868,10 +870,10 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ zend_init_rsrc_list_dtors(); #ifdef ZTS - ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor); - ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor); - ts_allocate_id(&language_scanner_globals_id, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL); - ts_allocate_id(&ini_scanner_globals_id, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL); + ts_allocate_fast_id(&compiler_globals_id, &compiler_globals_offset, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor); + ts_allocate_fast_id(&executor_globals_id, &executor_globals_offset, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor); + ts_allocate_fast_id(&language_scanner_globals_id, &language_scanner_globals_offset, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL); + ts_allocate_fast_id(&ini_scanner_globals_id, &ini_scanner_globals_offset, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL); compiler_globals = ts_resource(compiler_globals_id); executor_globals = ts_resource(executor_globals_id); diff --git a/Zend/zend.h b/Zend/zend.h index 4839b994b9..73a56a0ccb 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -55,12 +55,14 @@ #ifdef ZEND_ENABLE_STATIC_TSRMLS_CACHE #define ZEND_TSRMG TSRMG_STATIC +#define ZEND_TSRMG_FAST TSRMG_FAST_STATIC #define ZEND_TSRMLS_CACHE_EXTERN() TSRMLS_CACHE_EXTERN() #define ZEND_TSRMLS_CACHE_DEFINE() TSRMLS_CACHE_DEFINE() #define ZEND_TSRMLS_CACHE_UPDATE() TSRMLS_CACHE_UPDATE() #define ZEND_TSRMLS_CACHE TSRMLS_CACHE #else #define ZEND_TSRMG TSRMG +#define ZEND_TSRMG_FAST TSRMG_FAST #define ZEND_TSRMLS_CACHE_EXTERN() #define ZEND_TSRMLS_CACHE_DEFINE() #define ZEND_TSRMLS_CACHE_UPDATE() diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 27879dae03..dabf48150c 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2371,7 +2371,8 @@ typedef struct _zend_alloc_globals { #ifdef ZTS static int alloc_globals_id; -# define AG(v) ZEND_TSRMG(alloc_globals_id, zend_alloc_globals *, v) +static size_t alloc_globals_offset; +# define AG(v) ZEND_TSRMG_FAST(alloc_globals_offset, zend_alloc_globals *, v) #else # define AG(v) (alloc_globals.v) static zend_alloc_globals alloc_globals; @@ -2736,7 +2737,7 @@ static void alloc_globals_dtor(zend_alloc_globals *alloc_globals) ZEND_API void start_memory_manager(void) { #ifdef ZTS - ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); + ts_allocate_fast_id(&alloc_globals_id, &alloc_globals_offset, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor); #else alloc_globals_ctor(&alloc_globals); #endif @@ -2958,3 +2959,10 @@ ZEND_API void * __zend_realloc(void *p, size_t len) } zend_out_of_memory(); } + +#ifdef ZTS +size_t zend_mm_globals_size(void) +{ + return sizeof(zend_alloc_globals); +} +#endif diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index abe6ec8e12..075aac6561 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -398,6 +398,10 @@ static void apc_init_heap(void) */ +#ifdef ZTS +size_t zend_mm_globals_size(void); +#endif + END_EXTERN_C() #endif diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index bc1fa4b82f..edb952c2cd 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -211,7 +211,8 @@ typedef struct _zend_gc_globals { #ifdef ZTS static int gc_globals_id; -#define GC_G(v) ZEND_TSRMG(gc_globals_id, zend_gc_globals *, v) +static size_t gc_globals_offset; +#define GC_G(v) ZEND_TSRMG_FAST(gc_globals_offset, zend_gc_globals *, v) #else #define GC_G(v) (gc_globals.v) static zend_gc_globals gc_globals; @@ -442,7 +443,7 @@ static void gc_globals_ctor_ex(zend_gc_globals *gc_globals) void gc_globals_ctor(void) { #ifdef ZTS - ts_allocate_id(&gc_globals_id, sizeof(zend_gc_globals), (ts_allocate_ctor) gc_globals_ctor_ex, (ts_allocate_dtor) root_buffer_dtor); + ts_allocate_fast_id(&gc_globals_id, &gc_globals_offset, sizeof(zend_gc_globals), (ts_allocate_ctor) gc_globals_ctor_ex, (ts_allocate_dtor) root_buffer_dtor); #else gc_globals_ctor_ex(&gc_globals); #endif @@ -1585,3 +1586,10 @@ ZEND_API void zend_gc_get_status(zend_gc_status *status) status->threshold = GC_G(gc_threshold); status->num_roots = GC_G(num_roots); } + +#ifdef ZTS +size_t zend_gc_globals_size(void) +{ + return sizeof(zend_gc_globals); +} +#endif diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h index 377bd4298a..e83e874e07 100644 --- a/Zend/zend_gc.h +++ b/Zend/zend_gc.h @@ -51,6 +51,10 @@ void gc_globals_ctor(void); void gc_globals_dtor(void); void gc_reset(void); +#ifdef ZTS +size_t zend_gc_globals_size(void); +#endif + END_EXTERN_C() #define GC_REMOVE_FROM_BUFFER(p) do { \ diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 2f46da0c2d..5a76862194 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -45,6 +45,8 @@ BEGIN_EXTERN_C() ZEND_API extern int compiler_globals_id; ZEND_API extern int executor_globals_id; +ZEND_API extern size_t compiler_globals_offset; +ZEND_API extern size_t executor_globals_offset; END_EXTERN_C() #endif diff --git a/Zend/zend_globals_macros.h b/Zend/zend_globals_macros.h index 18181a433e..59b3daca53 100644 --- a/Zend/zend_globals_macros.h +++ b/Zend/zend_globals_macros.h @@ -29,7 +29,7 @@ BEGIN_EXTERN_C() /* Compiler */ #ifdef ZTS -# define CG(v) ZEND_TSRMG(compiler_globals_id, zend_compiler_globals *, v) +# define CG(v) ZEND_TSRMG_FAST(compiler_globals_offset, zend_compiler_globals *, v) #else # define CG(v) (compiler_globals.v) extern ZEND_API struct _zend_compiler_globals compiler_globals; @@ -39,7 +39,7 @@ ZEND_API int zendparse(void); /* Executor */ #ifdef ZTS -# define EG(v) ZEND_TSRMG(executor_globals_id, zend_executor_globals *, v) +# define EG(v) ZEND_TSRMG_FAST(executor_globals_offset, zend_executor_globals *, v) #else # define EG(v) (executor_globals.v) extern ZEND_API zend_executor_globals executor_globals; @@ -47,8 +47,9 @@ extern ZEND_API zend_executor_globals executor_globals; /* Language Scanner */ #ifdef ZTS -# define LANG_SCNG(v) ZEND_TSRMG(language_scanner_globals_id, zend_php_scanner_globals *, v) +# define LANG_SCNG(v) ZEND_TSRMG_FAST(language_scanner_globals_offset, zend_php_scanner_globals *, v) extern ZEND_API ts_rsrc_id language_scanner_globals_id; +extern ZEND_API size_t language_scanner_globals_offset; #else # define LANG_SCNG(v) (language_scanner_globals.v) extern ZEND_API zend_php_scanner_globals language_scanner_globals; @@ -57,8 +58,9 @@ extern ZEND_API zend_php_scanner_globals language_scanner_globals; /* INI Scanner */ #ifdef ZTS -# define INI_SCNG(v) ZEND_TSRMG(ini_scanner_globals_id, zend_ini_scanner_globals *, v) +# define INI_SCNG(v) ZEND_TSRMG_FAST(ini_scanner_globals_offset, zend_ini_scanner_globals *, v) extern ZEND_API ts_rsrc_id ini_scanner_globals_id; +extern ZEND_API size_t ini_scanner_globals_offset; #else # define INI_SCNG(v) (ini_scanner_globals.v) extern ZEND_API zend_ini_scanner_globals ini_scanner_globals; diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l index 23a5a7f14c..f71f0b9193 100644 --- a/Zend/zend_ini_scanner.l +++ b/Zend/zend_ini_scanner.l @@ -104,6 +104,7 @@ #define SCNG INI_SCNG #ifdef ZTS ZEND_API ts_rsrc_id ini_scanner_globals_id; +ZEND_API size_t ini_scanner_globals_offset; #else ZEND_API zend_ini_scanner_globals ini_scanner_globals; #endif diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index e93431de24..b1e25ebae5 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -85,6 +85,7 @@ #define SCNG LANG_SCNG #ifdef ZTS ZEND_API ts_rsrc_id language_scanner_globals_id; +ZEND_API size_t language_scanner_globals_offset; #else ZEND_API zend_php_scanner_globals language_scanner_globals; #endif diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c index a0dccd5819..571d85f848 100644 --- a/Zend/zend_signal.c +++ b/Zend/zend_signal.c @@ -45,6 +45,7 @@ #ifdef ZTS ZEND_API int zend_signal_globals_id; +ZEND_API size_t zend_signal_globals_offset; #else ZEND_API zend_signal_globals_t zend_signal_globals; #endif /* not ZTS */ @@ -403,7 +404,7 @@ ZEND_API void zend_signal_startup(void) { #ifdef ZTS - ts_allocate_id(&zend_signal_globals_id, sizeof(zend_signal_globals_t), (ts_allocate_ctor) zend_signal_globals_ctor, NULL); + ts_allocate_fast_id(&zend_signal_globals_id, &zend_signal_globals_offset, sizeof(zend_signal_globals_t), (ts_allocate_ctor) zend_signal_globals_ctor, NULL); #else zend_signal_globals_ctor(&zend_signal_globals); #endif diff --git a/Zend/zend_signal.h b/Zend/zend_signal.h index 7ecdde3cd6..1c234b0a0c 100644 --- a/Zend/zend_signal.h +++ b/Zend/zend_signal.h @@ -65,9 +65,10 @@ typedef struct _zend_signal_globals_t { } zend_signal_globals_t; # ifdef ZTS -# define SIGG(v) ZEND_TSRMG(zend_signal_globals_id, zend_signal_globals_t *, v) +# define SIGG(v) ZEND_TSRMG_FAST(zend_signal_globals_offset, zend_signal_globals_t *, v) BEGIN_EXTERN_C() ZEND_API extern int zend_signal_globals_id; +ZEND_API extern size_t zend_signal_globals_offset; END_EXTERN_C() # else # define SIGG(v) (zend_signal_globals.v) diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 3998b46aa1..8f8514ba23 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -82,6 +82,7 @@ MUTEX_T cwd_mutex; #ifdef ZTS ts_rsrc_id cwd_globals_id; +size_t cwd_globals_offset; #else virtual_cwd_globals cwd_globals; #endif @@ -185,7 +186,7 @@ CWD_API void virtual_cwd_startup(void) /* {{{ */ { virtual_cwd_main_cwd_init(0); #ifdef ZTS - ts_allocate_id(&cwd_globals_id, sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor); + ts_allocate_fast_id(&cwd_globals_id, &cwd_globals_offset, sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor); #else cwd_globals_ctor(&cwd_globals); #endif diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h index c6c06f6332..dd8567cc51 100644 --- a/Zend/zend_virtual_cwd.h +++ b/Zend/zend_virtual_cwd.h @@ -212,7 +212,8 @@ typedef struct _virtual_cwd_globals { #ifdef ZTS extern ts_rsrc_id cwd_globals_id; -# define CWDG(v) ZEND_TSRMG(cwd_globals_id, virtual_cwd_globals *, v) +extern size_t cwd_globals_offset; +# define CWDG(v) ZEND_TSRMG_FAST(cwd_globals_offset, virtual_cwd_globals *, v) #else extern virtual_cwd_globals cwd_globals; # define CWDG(v) (cwd_globals.v) diff --git a/main/SAPI.c b/main/SAPI.c index 6a272d4c64..05b7bbbbec 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -45,6 +45,7 @@ #ifdef ZTS SAPI_API int sapi_globals_id; +SAPI_API size_t sapi_globals_offset; #else sapi_globals_struct sapi_globals; #endif @@ -76,7 +77,7 @@ SAPI_API void sapi_startup(sapi_module_struct *sf) sapi_module = *sf; #ifdef ZTS - ts_allocate_id(&sapi_globals_id, sizeof(sapi_globals_struct), (ts_allocate_ctor) sapi_globals_ctor, (ts_allocate_dtor) sapi_globals_dtor); + ts_allocate_fast_id(&sapi_globals_id, &sapi_globals_offset, sizeof(sapi_globals_struct), (ts_allocate_ctor) sapi_globals_ctor, (ts_allocate_dtor) sapi_globals_dtor); # ifdef PHP_WIN32 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); # endif diff --git a/main/SAPI.h b/main/SAPI.h index f3479a22e6..fe8bfd6244 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -137,8 +137,9 @@ typedef struct _sapi_globals_struct { BEGIN_EXTERN_C() #ifdef ZTS -# define SG(v) ZEND_TSRMG(sapi_globals_id, sapi_globals_struct *, v) +# define SG(v) ZEND_TSRMG_FAST(sapi_globals_offset, sapi_globals_struct *, v) SAPI_API extern int sapi_globals_id; +SAPI_API extern size_t sapi_globals_offset; #else # define SG(v) (sapi_globals.v) extern SAPI_API sapi_globals_struct sapi_globals; diff --git a/main/main.c b/main/main.c index 5e18630bd9..6286990f62 100644 --- a/main/main.c +++ b/main/main.c @@ -116,6 +116,7 @@ PHPAPI int (*php_register_internal_extensions_func)(void) = php_register_interna php_core_globals core_globals; #else PHPAPI int core_globals_id; +PHPAPI size_t core_globals_offset; #endif #define SAFE_FILENAME(f) ((f)?(f):"-") @@ -2151,7 +2152,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod php_output_startup(); #ifdef ZTS - ts_allocate_id(&core_globals_id, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor); + ts_allocate_fast_id(&core_globals_id, &core_globals_offset, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor); #ifdef PHP_WIN32 ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor, (ts_allocate_dtor) php_win32_core_globals_dtor); #endif @@ -2774,3 +2775,37 @@ PHPAPI int php_lint_script(zend_file_handle *file) return retval; } /* }}} */ + +#ifdef ZTS +/* {{{ php_reserve_tsrm_memory + */ +PHPAPI void php_reserve_tsrm_memory(void) +{ + tsrm_reserve( + TSRM_ALIGNED_SIZE(sizeof(zend_compiler_globals)) + + TSRM_ALIGNED_SIZE(sizeof(zend_executor_globals)) + + TSRM_ALIGNED_SIZE(sizeof(zend_php_scanner_globals)) + + TSRM_ALIGNED_SIZE(sizeof(zend_ini_scanner_globals)) + + TSRM_ALIGNED_SIZE(sizeof(virtual_cwd_globals)) + +#ifdef ZEND_SIGNALS + TSRM_ALIGNED_SIZE(sizeof(zend_signal_globals_t)) + +#endif + TSRM_ALIGNED_SIZE(zend_mm_globals_size()) + + TSRM_ALIGNED_SIZE(zend_gc_globals_size()) + + TSRM_ALIGNED_SIZE(sizeof(php_core_globals)) + + TSRM_ALIGNED_SIZE(sizeof(sapi_globals_struct)) + ); +} +/* }}} */ + +/* {{{ php_tsrm_startup + */ +PHPAPI int php_tsrm_startup(void) +{ + int ret = tsrm_startup(1, 1, 0, NULL); + php_reserve_tsrm_memory(); + (void)ts_resource(0); + return ret; +} +/* }}} */ +#endif diff --git a/main/php_globals.h b/main/php_globals.h index ad24618eae..6b31d9eaa6 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -24,8 +24,9 @@ typedef struct _php_core_globals php_core_globals; #ifdef ZTS -# define PG(v) ZEND_TSRMG(core_globals_id, php_core_globals *, v) +# define PG(v) ZEND_TSRMG_FAST(core_globals_offset, php_core_globals *, v) extern PHPAPI int core_globals_id; +extern PHPAPI size_t core_globals_offset; #else # define PG(v) (core_globals.v) extern ZEND_API struct _php_core_globals core_globals; diff --git a/main/php_main.h b/main/php_main.h index 8f440de820..6f2f9c5856 100644 --- a/main/php_main.h +++ b/main/php_main.h @@ -49,6 +49,12 @@ PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *h /* environment module */ extern int php_init_environ(void); extern int php_shutdown_environ(void); + +#ifdef ZTS +PHPAPI void php_reserve_tsrm_memory(void); +PHPAPI int php_tsrm_startup(void); +#endif + END_EXTERN_C() #endif diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index 81198af562..193420eca4 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -474,8 +474,7 @@ php_apache_server_startup(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp apache2_sapi_module.php_ini_path_override = apache2_php_ini_path_override; } #ifdef ZTS - tsrm_startup(1, 1, 0, NULL); - (void)ts_resource(0); + php_tsrm_startup(); # ifdef PHP_WIN32 ZEND_TSRMLS_CACHE_UPDATE(); # endif diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 84d2213cd6..b22d37f89b 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -1791,8 +1791,7 @@ int main(int argc, char *argv[]) #endif #ifdef ZTS - tsrm_startup(1, 1, 0, NULL); - (void)ts_resource(0); + php_tsrm_startup(); # ifdef PHP_WIN32 ZEND_TSRMLS_CACHE_UPDATE(); # endif diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 2cc83a5d6d..4333487a0b 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -1246,8 +1246,7 @@ int main(int argc, char *argv[]) #ifdef ZTS - tsrm_startup(1, 1, 0, NULL); - (void)ts_resource(0); + php_tsrm_startup(); # ifdef PHP_WIN32 ZEND_TSRMLS_CACHE_UPDATE(); # endif diff --git a/sapi/embed/php_embed.c b/sapi/embed/php_embed.c index 4221e6e0eb..4fcb181cc0 100644 --- a/sapi/embed/php_embed.c +++ b/sapi/embed/php_embed.c @@ -171,8 +171,7 @@ EMBED_SAPI_API int php_embed_init(int argc, char **argv) #endif #ifdef ZTS - tsrm_startup(1, 1, 0, NULL); - (void)ts_resource(0); + php_tsrm_startup(); # ifdef PHP_WIN32 ZEND_TSRMLS_CACHE_UPDATE(); # endif diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 843e5d913f..307c02ed7c 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1550,10 +1550,6 @@ int main(int argc, char *argv[]) int ini_entries_len = 0; /* end of temporary locals */ -#ifdef ZTS - void ***tsrm_ls; -#endif - int max_requests = 0; int requests = 0; int fcgi_fd = 0; @@ -1583,8 +1579,7 @@ int main(int argc, char *argv[]) #endif #ifdef ZTS - tsrm_startup(1, 1, 0, NULL); - tsrm_ls = ts_resource(0); + php_tsrm_startup(); #endif zend_signal_startup(); diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index be97c46ff4..64e95d5ceb 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -86,7 +86,6 @@ zend_compiler_globals *compiler_globals; zend_executor_globals *executor_globals; php_core_globals *core_globals; sapi_globals_struct *sapi_globals; -void ***tsrm_ls; #endif zend_module_entry litespeed_module_entry; @@ -1234,7 +1233,7 @@ int main( int argc, char * argv[] ) #endif #ifdef ZTS - tsrm_startup(1, 1, 0, NULL); + php_tsrm_startup(); #endif #if PHP_MAJOR_VERSION >= 7 @@ -1262,7 +1261,6 @@ int main( int argc, char * argv[] ) executor_globals = ts_resource(executor_globals_id); core_globals = ts_resource(core_globals_id); sapi_globals = ts_resource(sapi_globals_id); - tsrm_ls = ts_resource(0); SG(request_info).path_translated = NULL; #endif diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 11e1fcf574..51c6cde122 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -1416,8 +1416,7 @@ int main(int argc, char **argv) /* {{{ */ phpdbg_main: #ifdef ZTS - tsrm_startup(1, 1, 0, NULL); - (void)ts_resource(0); + php_tsrm_startup(); # ifdef PHP_WIN32 ZEND_TSRMLS_CACHE_UPDATE(); # endif -- 2.40.0