APC's performance improvement patch for single process multithreaded php

From: Date: Wed, 07 Oct 2009 00:49:42 +0000
Subject: APC's performance improvement patch for single process multithreaded php
Groups: php.pecl.dev 
Request: Send a blank email to pecl-dev+get-6673@lists.php.net to get a copy of this message
Hi developers, On Unix platforms, APC can be compiled with mmap or shared memory. This performs good for multiprocess php. However when we run inside single process multi-threaded Web Servers e.g Sun Web Server or Apache worker mpm with single process, mmap is simply overkill. Reading APC's compiled cache from in-process memory is much efficient than from mmap. To achieve the above, I introduced a configurable variable apc.single_proc which is set to 0 by default. When apc.single_proc is set to 1, cache is created inside process memory. Also mutex which is used to synchronize the cache can also be created as PTHREAD_PROCESS_PRIVATE. apc.single_proc can only be set to 1 when ZTS is enabled. Attached is the patch from APC trunk which achieve this. Regards, Basant.

Index: php_apc.c =================================================================== --- php_apc.c (revision 289260) +++ php_apc.c (working copy) @@ -95,6 +95,7 @@ apc_globals->report_autofilter = 0; apc_globals->include_once = 0; apc_globals->apc_optimize_function = NULL; + apc_globals->single_proc = 0; #ifdef MULTIPART_EVENT_FORMDATA apc_globals->rfc1867 = 0; memset(&(apc_globals->rfc1867_data), 0, sizeof(apc_rfc1867_data)); @@ -257,6 +258,9 @@ STD_PHP_INI_BOOLEAN("apc.write_lock", "1", PHP_INI_SYSTEM, OnUpdateBool, write_lock, zend_apc_globals, apc_globals) STD_PHP_INI_BOOLEAN("apc.slam_defense", "1", PHP_INI_SYSTEM, OnUpdateBool, slam_defense, zend_apc_globals, apc_globals) STD_PHP_INI_BOOLEAN("apc.report_autofilter", "0", PHP_INI_SYSTEM, OnUpdateBool, report_autofilter,zend_apc_globals, apc_globals) +#ifdef ZTS +STD_PHP_INI_BOOLEAN("apc.single_proc", "0", PHP_INI_ALL, OnUpdateBool, single_proc, zend_apc_globals, apc_globals) +#endif #ifdef MULTIPART_EVENT_FORMDATA STD_PHP_INI_BOOLEAN("apc.rfc1867", "0", PHP_INI_SYSTEM, OnUpdateBool, rfc1867, zend_apc_globals, apc_globals) STD_PHP_INI_ENTRY("apc.rfc1867_prefix", "upload_", PHP_INI_SYSTEM, OnUpdateStringUnempty, rfc1867_prefix, zend_apc_globals, apc_globals) Index: apc_pthreadmutex.c =================================================================== --- apc_pthreadmutex.c (revision 289260) +++ apc_pthreadmutex.c (working copy) @@ -20,6 +20,7 @@ /* $Id$ */ #include "apc_pthreadmutex.h" +#include "apc_globals.h" #ifdef APC_PTHREADMUTEX_LOCKS @@ -27,6 +28,8 @@ { int result; pthread_mutexattr_t* attr; + int shared; + TSRMLS_FETCH(); attr = malloc(sizeof(pthread_mutexattr_t)); result = pthread_mutexattr_init(attr); @@ -46,7 +49,13 @@ #endif /* pthread_mutexattr_settype(attr, PTHREAD_MUTEX_ERRORCHECK); */ - result = pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED); + + if (APCG(single_proc)) + shared = PTHREAD_PROCESS_PRIVATE; + else + shared = PTHREAD_PROCESS_SHARED; + + result = pthread_mutexattr_setpshared(attr, shared); if(result == EINVAL) { apc_eprint("pthread mutex error: attr is not an initialized mutex attribute object, or pshared is not a valid process-shared state setting."); } else if(result == EFAULT) { Index: apc_sma.c =================================================================== --- apc_sma.c (revision 289260) +++ apc_sma.c (working copy) @@ -336,6 +336,7 @@ void apc_sma_init(int numseg, size_t segsize, char *mmap_file_mask) { uint i; + TSRMLS_FETCH(); if (sma_initialized) { return; @@ -367,12 +368,17 @@ block_t* block; void* shmaddr; + if (APCG(single_proc)) { + sma_segments[i].shmaddr = calloc(1, sma_segsize); + sma_segments[i].size = sma_segsize; + } else { #if APC_MMAP - sma_segments[i] = apc_mmap(mmap_file_mask, sma_segsize); - if(sma_numseg != 1) memcpy(&mmap_file_mask[strlen(mmap_file_mask)-6], "XXXXXX", 6); + sma_segments[i] = apc_mmap(mmap_file_mask, sma_segsize); + if(sma_numseg != 1) memcpy(&mmap_file_mask[strlen(mmap_file_mask)-6], "XXXXXX", 6); #else - sma_segments[i] = apc_shm_attach(apc_shm_create(NULL, i, sma_segsize)); + sma_segments[i] = apc_shm_attach(apc_shm_create(NULL, i, sma_segsize)); #endif + } sma_segments[i].size = sma_segsize; @@ -423,16 +429,21 @@ void apc_sma_cleanup() { uint i; + TSRMLS_FETCH(); assert(sma_initialized); for (i = 0; i < sma_numseg; i++) { apc_lck_destroy(SMA_LCK(i)); + if (APCG(single_proc)) { + free(sma_segments[i].shmaddr); + } else { #if APC_MMAP - apc_unmap(&sma_segments[i]); + apc_unmap(&sma_segments[i]); #else - apc_shm_detach(&sma_segments[i]); + apc_shm_detach(&sma_segments[i]); #endif + } } sma_initialized = 0; apc_efree(sma_segments); Index: apc_globals.h =================================================================== --- apc_globals.h (revision 289260) +++ apc_globals.h (working copy) @@ -76,6 +76,8 @@ /* module variables */ zend_bool initialized; /* true if module was initialized */ + zend_bool single_proc; /* true if single process shared the APC cache. + useful for performance */ apc_stack_t* cache_stack; /* the stack of cached executable code */ zend_bool cache_by_default; /* true if files should be cached unless filtered out */ /* false if files should only be cached if filtered in */
« previous php.pecl.dev (#6673) next »