mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
- Prepare for optimization - use a single fetch for multiple resources
- Clean a bit
This commit is contained in:
parent
e280c3e555
commit
736b4ae43d
4 changed files with 71 additions and 60 deletions
95
TSRM/TSRM.c
95
TSRM/TSRM.c
|
@ -38,9 +38,6 @@ 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=NULL;
|
||||
static int tsrm_tls_table_size;
|
||||
|
@ -61,15 +58,30 @@ static void (*tsrm_new_thread_end_handler)();
|
|||
int tsrm_error(int level, const char *format, ...);
|
||||
|
||||
/* Read a resource from a thread's resource storage */
|
||||
void *ts_resource_read( tsrm_tls_entry *thread_resources, ts_rsrc_id id );
|
||||
static int tsrm_error_level;
|
||||
static FILE *tsrm_error_file;
|
||||
|
||||
#if TSRM_DEBUG
|
||||
#define TSRM_ERROR(a) tsrm_error a
|
||||
#define TSRM_SAFE_ARRAY_OFFSET(array, offset, range) (((offset)>=0 && (offset)<(range)) ? array[offset] : NULL)
|
||||
#define TSRM_ERROR(args) tsrm_error args
|
||||
#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \
|
||||
{ \
|
||||
int unshuffled_offset = TSRM_UNSHUFFLE_RSRC_ID(offset); \
|
||||
\
|
||||
if (offset==0) { \
|
||||
return &array; \
|
||||
} else if ((unshuffled_offset)>=0 && (unshuffled_offset)<(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]; \
|
||||
} 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))); \
|
||||
return NULL; \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define TSRM_ERROR(a)
|
||||
#define TSRM_SAFE_ARRAY_OFFSET(array, offset, range) array[offset]
|
||||
#define TSRM_ERROR
|
||||
#define RETURN_TSRM_SAFE_ARRAY_OFFSET(array, offset, range) return array[offset]
|
||||
#endif
|
||||
|
||||
#if defined(PTHREADS)
|
||||
|
@ -164,9 +176,8 @@ TSRM_API void tsrm_shutdown(void)
|
|||
|
||||
|
||||
/* allocates a new thread-safe-resource id */
|
||||
TSRM_API ts_rsrc_id ts_allocate_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, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
|
||||
{
|
||||
ts_rsrc_id new_id;
|
||||
int i;
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size));
|
||||
|
@ -174,8 +185,8 @@ TSRM_API ts_rsrc_id ts_allocate_id(size_t size, ts_allocate_ctor ctor, ts_alloca
|
|||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
/* obtain a resource id */
|
||||
new_id = id_count++;
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", TSRM_SHUFFLE_RSRC_ID(new_id)));
|
||||
*rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++);
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id));
|
||||
|
||||
/* store the new resource type in the resource sizes table */
|
||||
if (resource_types_table_size < id_count) {
|
||||
|
@ -183,13 +194,14 @@ TSRM_API ts_rsrc_id ts_allocate_id(size_t size, ts_allocate_ctor ctor, ts_alloca
|
|||
if (!resource_types_table) {
|
||||
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_size = id_count;
|
||||
}
|
||||
resource_types_table[new_id].size = size;
|
||||
resource_types_table[new_id].ctor = ctor;
|
||||
resource_types_table[new_id].dtor = dtor;
|
||||
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;
|
||||
|
||||
/* enlarge the arrays for the already active threads */
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
|
@ -203,7 +215,7 @@ TSRM_API ts_rsrc_id ts_allocate_id(size_t size, ts_allocate_ctor ctor, ts_alloca
|
|||
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]);
|
||||
resource_types_table[j].ctor(p->storage[j], &p->storage);
|
||||
}
|
||||
}
|
||||
p->count = id_count;
|
||||
|
@ -213,8 +225,8 @@ TSRM_API ts_rsrc_id ts_allocate_id(size_t size, ts_allocate_ctor ctor, ts_alloca
|
|||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", TSRM_SHUFFLE_RSRC_ID(new_id)));
|
||||
return TSRM_SHUFFLE_RSRC_ID(new_id);
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
|
||||
return *rsrc_id;
|
||||
}
|
||||
|
||||
|
||||
|
@ -242,7 +254,7 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
|
|||
for (i=0; i<id_count; i++) {
|
||||
(*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]);
|
||||
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i], &(*thread_resources_ptr)->storage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,19 +276,23 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
|
|||
if (!th_id) {
|
||||
#if defined(PTHREADS)
|
||||
/* Fast path for looking up the resources for the current
|
||||
* thread. Its used by just about every call to
|
||||
* ts_resource_ex(). This avoids the need for a mutex lock
|
||||
* and our hashtable lookup.
|
||||
*/
|
||||
thread_resources = pthread_getspecific( tls_key );
|
||||
* thread. Its used by just about every call to
|
||||
* ts_resource_ex(). This avoids the need for a mutex lock
|
||||
* and our hashtable lookup.
|
||||
*/
|
||||
thread_resources = pthread_getspecific(tls_key);
|
||||
#elif defined(TSRM_ST)
|
||||
thread_resources = st_thread_getspecific(tls_key);
|
||||
#else
|
||||
thread_resources = NULL;
|
||||
#endif
|
||||
if (thread_resources) {
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id ));
|
||||
return ts_resource_read( thread_resources, id );
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id));
|
||||
/* Read a specific resource from the thread's resources.
|
||||
* This is called outside of a mutex, so have to be aware about external
|
||||
* changes to the structure as we read it.
|
||||
*/
|
||||
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
|
||||
}
|
||||
thread_id = tsrm_thread_id();
|
||||
} else {
|
||||
|
@ -310,26 +326,11 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
|
|||
} while (thread_resources);
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
return ts_resource_read( thread_resources, id );
|
||||
}
|
||||
|
||||
|
||||
/* Read a specific resource from the thread's resources.
|
||||
* This is called outside of a mutex, so have to be aware about external
|
||||
* changes to the structure as we read it.
|
||||
*/
|
||||
void *ts_resource_read( tsrm_tls_entry *thread_resources, ts_rsrc_id id )
|
||||
{
|
||||
void *resource;
|
||||
|
||||
resource = TSRM_SAFE_ARRAY_OFFSET(thread_resources->storage, TSRM_UNSHUFFLE_RSRC_ID(id), thread_resources->count);
|
||||
if (resource) {
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Successfully fetched resource id %d for thread id %ld - %x", id, (long) thread_resources->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)));
|
||||
abort();
|
||||
}
|
||||
return resource;
|
||||
/* Read a specific resource from the thread's resources.
|
||||
* This is called outside of a mutex, so have to be aware about external
|
||||
* changes to the structure as we read it.
|
||||
*/
|
||||
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
|
||||
}
|
||||
|
||||
|
||||
|
@ -350,7 +351,7 @@ 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]);
|
||||
resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage);
|
||||
}
|
||||
}
|
||||
for (i=0; i<thread_resources->count; i++) {
|
||||
|
|
16
TSRM/TSRM.h
16
TSRM/TSRM.h
|
@ -68,8 +68,8 @@ typedef int ts_rsrc_id;
|
|||
# define MUTEX_T st_mutex_t
|
||||
#endif
|
||||
|
||||
typedef void (*ts_allocate_ctor)(void *);
|
||||
typedef void (*ts_allocate_dtor)(void *);
|
||||
typedef void (*ts_allocate_ctor)(void *, void ***);
|
||||
typedef void (*ts_allocate_dtor)(void *, void ***);
|
||||
|
||||
#define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
|
||||
|
||||
|
@ -82,7 +82,7 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
|
|||
TSRM_API void tsrm_shutdown(void);
|
||||
|
||||
/* allocates a new thread-safe-resource id */
|
||||
TSRM_API ts_rsrc_id ts_allocate_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, 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);
|
||||
|
@ -112,6 +112,16 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
|
|||
TSRM_API void *tsrm_set_new_thread_begin_handler(void (*new_thread_begin_handler)(THREAD_T thread_id));
|
||||
TSRM_API void *tsrm_set_new_thread_end_handler(void (*new_thread_end_handler)(THREAD_T thread_id));
|
||||
|
||||
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
|
||||
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
|
||||
|
||||
#define TSRMLS_FETCH() void ***tsrm_ls = ts_resource_ex(0, NULL)
|
||||
#define TSRMG(id, type, element) (((type) (*tsrm_ls)[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
|
||||
#define TSRMLS_D void ***tsrm_ls
|
||||
#define TSRMLS_DC , TSRMLS_D
|
||||
#define TSRMLS_C tsrm_ls
|
||||
#define TSRMLS_CC , TSRMLS_C
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -140,12 +140,12 @@ static int php_is_file_ok(const cwd_state *state)
|
|||
return (1);
|
||||
}
|
||||
|
||||
static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals)
|
||||
static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
|
||||
{
|
||||
CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state);
|
||||
}
|
||||
|
||||
static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals)
|
||||
static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
|
||||
{
|
||||
CWD_STATE_FREE(&cwd_globals->cwd);
|
||||
}
|
||||
|
@ -178,9 +178,9 @@ CWD_API void virtual_cwd_startup(void)
|
|||
main_cwd_state.cwd_length = strlen(cwd);
|
||||
|
||||
#ifdef ZTS
|
||||
cwd_globals_id = ts_allocate_id(sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor);
|
||||
ts_allocate_id(&cwd_globals_id, sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor);
|
||||
#else
|
||||
cwd_globals_ctor(&cwd_globals);
|
||||
cwd_globals_ctor(&cwd_globals TSRMLS_CC);
|
||||
#endif
|
||||
|
||||
#if defined(TSRM_WIN32) && defined(ZTS)
|
||||
|
@ -191,7 +191,7 @@ CWD_API void virtual_cwd_startup(void)
|
|||
CWD_API void virtual_cwd_shutdown(void)
|
||||
{
|
||||
#ifndef ZTS
|
||||
cwd_globals_dtor(&cwd_globals);
|
||||
cwd_globals_dtor(&cwd_globals TSRMLS_CC);
|
||||
#endif
|
||||
#if defined(TSRM_WIN32) && defined(ZTS)
|
||||
tsrm_mutex_free(cwd_mutex);
|
||||
|
|
|
@ -36,14 +36,14 @@ static ts_rsrc_id win32_globals_id;
|
|||
static tsrm_win32_globals win32_globals;
|
||||
#endif
|
||||
|
||||
static void tsrm_win32_ctor(tsrm_win32_globals *globals)
|
||||
static void tsrm_win32_ctor(tsrm_win32_globals *globals TSRMLS_DC)
|
||||
{
|
||||
globals->process = NULL;
|
||||
globals->process_size = 0;
|
||||
globals->comspec = _strdup((GetVersion()<0x80000000)?"cmd.exe":"command.com");
|
||||
}
|
||||
|
||||
static void tsrm_win32_dtor(tsrm_win32_globals *globals)
|
||||
static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC)
|
||||
{
|
||||
if (globals->process != NULL) {
|
||||
free(globals->process);
|
||||
|
@ -54,16 +54,16 @@ static void tsrm_win32_dtor(tsrm_win32_globals *globals)
|
|||
TSRM_API void tsrm_win32_startup(void)
|
||||
{
|
||||
#ifdef ZTS
|
||||
win32_globals_id = ts_allocate_id(sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
|
||||
ts_allocate_id(&win32_globals_id, sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
|
||||
#else
|
||||
tsrm_win32_ctor(&win32_globals);
|
||||
tsrm_win32_ctor(&win32_globals TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
TSRM_API void tsrm_win32_shutdown(void)
|
||||
{
|
||||
#ifndef ZTS
|
||||
tsrm_win32_dtor(&win32_globals);
|
||||
tsrm_win32_dtor(&win32_globals TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue