php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #58556 reserved_offset in APC should be true global (not a thread local)
Submitted: 2009-02-16 17:23 UTC Modified: 2009-02-18 04:01 UTC
From: basant dot kukreja at gmail dot com Assigned:
Status: Closed Package: APC (PECL)
PHP Version: 5.2.5 OS: Solaris 10
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: basant dot kukreja at gmail dot com
New email:
PHP Version: OS:

 

 [2009-02-16 17:23 UTC] basant dot kukreja at gmail dot com
Description:
------------
I found that APC is consuming twice more time in my_compile_file in threaded version than in single threaded
fastcgi version.

Later on debugging, I found out that apc is always copying opcodes in threaded
php.  needcopy variable in my_prepare_op_array_for_execution was always 1.

From my_prepare_op_array_for_execution :
    apc_opflags_t * flags = APCG(reserved_offset) != -1 ? 
                                (apc_opflags_t*) & (src->reserved[APCG(reserved_offset)]) : NULL;
    int needcopy = flags ? flags->deep_copy : 1;

flags variable was mostly NULL in my_prepare_op_array_for_execution.

Further debugging showed that reserved_offset is initialized in apc_zend_init
function. It is initialized once in multithreaded server.
In my opinion, it should have been a true global variable, not a thread local
variable.


Reproduce code:
---------------
Test simple test.php code and put a printf of needcopy. It is always 1.

Expected result:
----------------
APC should not copy opcodes for individual threads unless necessary.

Actual result:
--------------
needcopy should be 0 for most scripts. It is 1.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-02-16 17:26 UTC] basant dot kukreja at gmail dot com
Here is a patch which fixes the performance issue for APC inside multi-threaded php.

--- ../../../unchanged/APC-3.0.19/./apc_compile.c	2008-05-14 23:45:27.000000000 -0700
+++ ./apc_compile.c	2009-02-16 13:48:53.978726000 -0800
@@ -1236,10 +1236,10 @@
     }
 
 #ifdef ZEND_ENGINE_2
-    if(APCG(reserved_offset) != -1) {
+    if(apc_reserved_offset != -1) {
         /* Insanity alert: the void* pointer is cast into an apc_opflags_t 
          * struct. apc_zend_init() checks to ensure that it fits in a void* */
-        flags = (apc_opflags_t*) & (dst->reserved[APCG(reserved_offset)]);
+        flags = (apc_opflags_t*) & (dst->reserved[apc_reserved_offset]);
         memset(flags, 0, sizeof(apc_opflags_t));
         /* assert(sizeof(apc_opflags_t) < sizeof(dst->reserved)); */
     }
@@ -2040,8 +2040,8 @@
     zend_op *zo;
     zend_op *dzo;
 #ifdef ZEND_ENGINE_2
-    apc_opflags_t * flags = APCG(reserved_offset) != -1 ? 
-                                (apc_opflags_t*) & (src->reserved[APCG(reserved_offset)]) : NULL;
+    apc_opflags_t * flags = apc_reserved_offset != -1 ? 
+                                (apc_opflags_t*) & (src->reserved[apc_reserved_offset]) : NULL;
     int needcopy = flags ? flags->deep_copy : 1;
     /* auto_globals_jit was not in php4 */
     int do_prepare_fetch_global = PG(auto_globals_jit) && (flags == NULL || flags->unknown_global);
--- ../../../unchanged/APC-3.0.19/./apc_globals.h	2008-05-14 23:45:27.000000000 -0700
+++ ./apc_globals.h	2009-02-16 13:50:18.718915000 -0800
@@ -79,9 +79,6 @@
     double rfc1867_freq;         /* Update frequency as percentage or bytes */
 #endif
     HashTable *copied_zvals;     /* my_copy recursion detection list */
-#ifdef ZEND_ENGINE_2
-    int reserved_offset;         /* offset for apc info in op_array->reserved[] */
-#endif
     zend_bool force_file_update; /* force files to be updated during apc_compile_file */
     char canon_path[MAXPATHLEN]; /* canonical path for key data */
 #if APC_FILEHITS
@@ -103,6 +100,9 @@
 extern apc_cache_t* apc_cache;       /* the global compiler cache */
 extern apc_cache_t* apc_user_cache;  /* the global user content cache */
 extern void* apc_compiled_filters;   /* compiled filters */
+#ifdef ZEND_ENGINE_2
+extern int apc_reserved_offset;         /* offset for apc info in op_array->reserved[] */
+#endif
 
 #endif
 
--- ../../../unchanged/APC-3.0.19/./apc_zend.c	2008-05-14 23:45:27.000000000 -0700
+++ ./apc_zend.c	2009-02-16 13:48:53.992013000 -0800
@@ -195,9 +195,9 @@
 		zval_dtor(&tmp_inc_filename);
 	}
 
-	if(APCG(reserved_offset) != -1) {
+	if(apc_reserved_offset != -1) {
 		/* Insanity alert: look into apc_compile.c for why a void** is cast to a apc_opflags_t* */
-		flags = (apc_opflags_t*) & (execute_data->op_array->reserved[APCG(reserved_offset)]);
+		flags = (apc_opflags_t*) & (execute_data->op_array->reserved[apc_reserved_offset]);
 	}
 
 #ifdef ZEND_ENGINE_2
@@ -223,9 +223,9 @@
 {
     zend_extension dummy_ext;
 #ifdef ZEND_ENGINE_2
-    APCG(reserved_offset) = zend_get_resource_handle(&dummy_ext); 
-    assert(APCG(reserved_offset) == dummy_ext.resource_number);
-    assert(APCG(reserved_offset) != -1);
+    apc_reserved_offset = zend_get_resource_handle(&dummy_ext); 
+    assert(apc_reserved_offset == dummy_ext.resource_number);
+    assert(apc_reserved_offset != -1);
     assert(sizeof(apc_opflags_t) <= sizeof(void*));
 #endif
 	if (!APCG(include_once)) {
--- ../../../unchanged/APC-3.0.19/./php_apc.c	2008-05-14 23:45:28.000000000 -0700
+++ ./php_apc.c	2009-02-16 13:48:53.993278000 -0800
@@ -72,6 +72,9 @@
 apc_cache_t* apc_cache = NULL;       
 apc_cache_t* apc_user_cache = NULL;
 void* apc_compiled_filters = NULL;
+#ifdef ZEND_ENGINE_2
+int apc_reserved_offset = -1;
+#endif
 
 static void php_apc_init_globals(zend_apc_globals* apc_globals TSRMLS_DC)
 {
@@ -90,9 +93,6 @@
     apc_globals->rfc1867 = 0;
 #endif
     apc_globals->copied_zvals = NULL;
-#ifdef ZEND_ENGINE_2
-    apc_globals->reserved_offset = -1;
-#endif
     apc_globals->force_file_update = 0;
     apc_globals->coredump_unmap = 0;
 }
 [2009-02-18 04:01 UTC] gopalv82 at yahoo dot com
http://news.php.net/php.pecl.cvs/11976

in CVS now.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 12 05:01:33 2025 UTC