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
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Sat Jun 01 19:01:30 2024 UTC