Commit:    037ea6f36076f9f213cec2f305b8a395f4f40897
Author:    Dmitry Stogov <dmi...@zend.com>         Thu, 28 Mar 2013 13:34:59 
+0400
Parents:   031553cd011dcc73a062a540f24ff41c310bc4a9
Branches:  PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=037ea6f36076f9f213cec2f305b8a395f4f40897

Log:
Reimplemented OPcache restart trigger. Now, if memory or hash are full the 
restart is scheduled only in case the amount of wasted memory is above 
opcache.max_wasted_percentage. Otherwise OPcahce continue serving the following 
requests using already cached files, but doesn't try to add new files (the 
cache is full anyway).

Changed paths:
  M  ext/opcache/ZendAccelerator.c
  M  ext/opcache/ZendAccelerator.h
  M  ext/opcache/zend_accelerator_module.c
  M  ext/opcache/zend_shared_alloc.c

diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index a5f9923..5d5de44 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -184,6 +184,13 @@ static inline char* accel_getcwd(int *cwd_len TSRMLS_DC)
        }
 }
 
+void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason 
TSRMLS_DC)
+{
+       if ((((double) ZSMMG(wasted_shared_memory)) / 
ZCG(accel_directives).memory_consumption) >= 
ZCG(accel_directives).max_wasted_percentage) {
+               zend_accel_schedule_restart(reason TSRMLS_CC);
+       }
+}
+
 /* O+ tracks changes of "include_path" directive. It stores all the requested
  * values in ZCG(include_paths) shared hash table, current value in
  * ZCG(include_path)/ZCG(include_path_len) and one letter "path key" in
@@ -219,8 +226,10 @@ static ZEND_INI_MH(accel_include_path_on_modify)
                                                        
key[ZCG(include_path_len) + 1] = 'A' + ZCSG(include_paths).num_entries;
                                                        ZCG(include_path_key) = 
key + ZCG(include_path_len) + 1;
                                                        
zend_accel_hash_update(&ZCSG(include_paths), key, ZCG(include_path_len) + 1, 0, 
ZCG(include_path_key));
-                                       }
-                               }
+                                               } else {
+                                                       
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
+                                               }
+                                       }
 
                                        zend_shared_alloc_unlock(TSRMLS_C);
                                        SHM_PROTECT();
@@ -868,14 +877,6 @@ static inline int 
do_validate_timestamps(zend_persistent_script *persistent_scri
        return FAILURE;
 }
 
-static void zend_accel_schedule_restart_if_necessary(TSRMLS_D)
-{
-       if ((((double) ZSMMG(wasted_shared_memory)) / 
ZCG(accel_directives).memory_consumption) >= 
ZCG(accel_directives).max_wasted_percentage) {
-           ZSMMG(memory_exhausted) = 1;
-               zend_accel_schedule_restart(ACCEL_RESTART_WASTED TSRMLS_CC);
-       }
-}
-
 static inline int validate_timestamp_and_record(zend_persistent_script 
*persistent_script, zend_file_handle *file_handle TSRMLS_DC)
 {
        if (ZCG(accel_directives).revalidate_freq &&
@@ -973,7 +974,9 @@ char *accel_make_persistent_key_ex(zend_file_handle 
*file_handle, int path_lengt
                                                
zend_accel_hash_update(&ZCSG(include_paths), key, ZCG(include_path_len) + 1, 0, 
ZCG(include_path_key));
                                                include_path = 
ZCG(include_path_key);
                                                include_path_len = 1;
-                               }
+                                       } else {
+                                               
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
+                                       }
                }
 
                                zend_shared_alloc_unlock(TSRMLS_C);
@@ -1051,12 +1054,14 @@ static void zend_accel_add_key(char *key, unsigned int 
key_length, zend_accel_ha
                if (zend_accel_hash_is_full(&ZCSG(hash))) {
                        zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in 
hash table!");
                        ZSMMG(memory_exhausted) = 1;
-                       zend_accel_schedule_restart(ACCEL_RESTART_HASH 
TSRMLS_CC);
+                       
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH TSRMLS_CC);
                } else {
                        char *new_key = zend_shared_alloc(key_length + 1);
                        if (new_key) {
                                memcpy(new_key, key, key_length + 1);
                                zend_accel_hash_update(&ZCSG(hash), new_key, 
key_length + 1, 1, bucket);
+                       } else {
+                               
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
                        }
                }
        }
@@ -1078,7 +1083,7 @@ static zend_persistent_script 
*cache_script_in_shared_memory(zend_persistent_scr
        if (zend_accel_hash_is_full(&ZCSG(hash))) {
                zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash 
table!");
                ZSMMG(memory_exhausted) = 1;
-               zend_accel_schedule_restart(ACCEL_RESTART_HASH TSRMLS_CC);
+               zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH 
TSRMLS_CC);
                zend_shared_alloc_unlock(TSRMLS_C);
                return new_persistent_script;
        }
@@ -1106,6 +1111,7 @@ static zend_persistent_script 
*cache_script_in_shared_memory(zend_persistent_scr
        /* Allocate shared memory */
        ZCG(mem) = zend_shared_alloc(memory_used);
        if (!ZCG(mem)) {
+               zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM 
TSRMLS_CC);
                zend_shared_alloc_unlock(TSRMLS_C);
                return new_persistent_script;
        }
@@ -1139,7 +1145,7 @@ static zend_persistent_script 
*cache_script_in_shared_memory(zend_persistent_scr
                if (!zend_accel_hash_update(&ZCSG(hash), key, key_length + 1, 
1, bucket)) {
                        zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in 
hash table!");
                        ZSMMG(memory_exhausted) = 1;
-                       zend_accel_schedule_restart(ACCEL_RESTART_HASH 
TSRMLS_CC);
+                       
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH TSRMLS_CC);
                }
        }
 
@@ -1503,7 +1509,11 @@ static zend_op_array 
*persistent_compile_file(zend_file_handle *file_handle, int
                                persistent_script->corrupted = 1;
                                persistent_script->timestamp = 0;
                                ZSMMG(wasted_shared_memory) += 
persistent_script->dynamic_members.memory_consumption;
-                               
zend_accel_schedule_restart_if_necessary(TSRMLS_C);
+                               if (ZSMMG(memory_exhausted)) {
+                                       zend_accel_restart_reason reason =
+                                               
zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM;
+                                       
zend_accel_schedule_restart_if_necessary(reason TSRMLS_CC);
+                               }
                        }
                        zend_shared_alloc_unlock(TSRMLS_C);
                        persistent_script = NULL;
@@ -1524,7 +1534,11 @@ static zend_op_array 
*persistent_compile_file(zend_file_handle *file_handle, int
                                persistent_script->corrupted = 1;
                                persistent_script->timestamp = 0;
                                ZSMMG(wasted_shared_memory) += 
persistent_script->dynamic_members.memory_consumption;
-                               
zend_accel_schedule_restart_if_necessary(TSRMLS_C);
+                               if (ZSMMG(memory_exhausted)) {
+                                       zend_accel_restart_reason reason =
+                                               
zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM;
+                                       
zend_accel_schedule_restart_if_necessary(reason TSRMLS_CC);
+                               }
                        }
                        zend_shared_alloc_unlock(TSRMLS_C);
                        persistent_script = NULL;
@@ -2011,9 +2025,6 @@ static void accel_activate(void)
                                        case ACCEL_RESTART_OOM:
                                                ZCSG(oom_restarts)++;
                                                break;
-                                       case ACCEL_RESTART_WASTED:
-                                               ZCSG(wasted_restarts)++;
-                                               break;
                                        case ACCEL_RESTART_HASH:
                                                ZCSG(hash_restarts)++;
                                                break;
@@ -2380,7 +2391,6 @@ static void zend_accel_init_shm(TSRMLS_D)
        zend_reset_cache_vars(TSRMLS_C);
 
        ZCSG(oom_restarts) = 0;
-       ZCSG(wasted_restarts) = 0;
        ZCSG(hash_restarts) = 0;
        ZCSG(manual_restarts) = 0;
 
@@ -2530,6 +2540,8 @@ static int accel_startup(zend_extension *extension)
                                        key[ZCG(include_path_len) + 1] = 'A' + 
ZCSG(include_paths).num_entries;
                                        ZCG(include_path_key) = key + 
ZCG(include_path_len) + 1;
                                        
zend_accel_hash_update(&ZCSG(include_paths), key, ZCG(include_path_len) + 1, 0, 
ZCG(include_path_key));
+                               } else {
+                                       
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
                                }
                                zend_shared_alloc_unlock(TSRMLS_C);
                        }
diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h
index f9b51b0..f200547 100644
--- a/ext/opcache/ZendAccelerator.h
+++ b/ext/opcache/ZendAccelerator.h
@@ -167,7 +167,6 @@ typedef time_t accel_time_t;
 
 typedef enum _zend_accel_restart_reason {
        ACCEL_RESTART_OOM,    /* restart because of out of memory */
-       ACCEL_RESTART_WASTED, /* restart because of wasted memory */
        ACCEL_RESTART_HASH,   /* restart because of hash overflow */
        ACCEL_RESTART_USER    /* restart sheduled by opcache_reset() */
 } zend_accel_restart_reason;
@@ -268,7 +267,6 @@ typedef struct _zend_accel_shared_globals {
        unsigned long   misses;
        unsigned long   blacklist_misses;
        unsigned long   oom_restarts;     /* number of restarts because of out 
of memory */
-       unsigned long   wasted_restarts;  /* number of restarts because of 
wasted memory */
        unsigned long   hash_restarts;    /* number of restarts because of hash 
overflow */
        unsigned long   manual_restarts;  /* number of restarts sheduled by 
opcache_reset() */
        zend_accel_hash hash;             /* hash table for cached scripts */
@@ -319,6 +317,7 @@ extern zend_accel_globals accel_globals;
 extern char *zps_api_failure_reason;
 
 void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC);
+void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason 
TSRMLS_DC);
 int  accelerator_shm_read_lock(TSRMLS_D);
 void accelerator_shm_read_unlock(TSRMLS_D);
 
diff --git a/ext/opcache/zend_accelerator_module.c 
b/ext/opcache/zend_accelerator_module.c
index 8cfab79..8d6ed4e 100644
--- a/ext/opcache/zend_accelerator_module.c
+++ b/ext/opcache/zend_accelerator_module.c
@@ -406,8 +406,6 @@ void zend_accel_info(ZEND_MODULE_INFO_FUNC_ARGS)
                        php_info_print_table_row(2, "Max keys", buf);
                        snprintf(buf, sizeof(buf), "%ld", ZCSG(oom_restarts));
                        php_info_print_table_row(2, "OOM restarts", buf);
-                       snprintf(buf, sizeof(buf), "%ld", 
ZCSG(wasted_restarts));
-                       php_info_print_table_row(2, "Wasted memory restarts", 
buf);
                        snprintf(buf, sizeof(buf), "%ld", ZCSG(hash_restarts));
                        php_info_print_table_row(2, "Hash keys restarts", buf);
                        snprintf(buf, sizeof(buf), "%ld", 
ZCSG(manual_restarts));
@@ -535,7 +533,6 @@ static ZEND_FUNCTION(opcache_get_status)
        add_assoc_long(statistics, "start_time", ZCSG(start_time));
        add_assoc_long(statistics, "last_restart_time", 
ZCSG(last_restart_time));
        add_assoc_long(statistics, "oom_restarts", ZCSG(oom_restarts));
-       add_assoc_long(statistics, "wasted_restarts", ZCSG(wasted_restarts));
        add_assoc_long(statistics, "hash_restarts", ZCSG(hash_restarts));
        add_assoc_long(statistics, "manual_restarts", ZCSG(manual_restarts));
        add_assoc_long(statistics, "misses", 
ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses));
diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c
index 18e8bdb..ebfdea2 100644
--- a/ext/opcache/zend_shared_alloc.c
+++ b/ext/opcache/zend_shared_alloc.c
@@ -215,8 +215,17 @@ int zend_shared_alloc_startup(int requested_size)
        /* move shared_segments and shared_free to shared memory */
        ZCG(locked) = 1; /* no need to perform a real lock at this point */
        p_tmp_shared_globals = (zend_smm_shared_globals *) 
zend_shared_alloc(sizeof(zend_smm_shared_globals));
+       if (!p_tmp_shared_globals) {
+               zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared 
memory!");
+               return ALLOC_FAILURE;;
+       }
 
        tmp_shared_segments = zend_shared_alloc(shared_segments_array_size + 
ZSMMG(shared_segments_count) * sizeof(void *));
+       if (!tmp_shared_segments) {
+               zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared 
memory!");
+               return ALLOC_FAILURE;;
+       }
+
        copy_shared_segments(tmp_shared_segments, ZSMMG(shared_segments)[0], 
ZSMMG(shared_segments_count), S_H(segment_type_size)());
 
        *p_tmp_shared_globals = tmp_shared_globals;
@@ -226,6 +235,11 @@ int zend_shared_alloc_startup(int requested_size)
        ZSMMG(shared_segments) = tmp_shared_segments;
 
        ZSMMG(shared_memory_state).positions = (int 
*)zend_shared_alloc(sizeof(int) * ZSMMG(shared_segments_count));
+       if (!ZSMMG(shared_memory_state).positions) {
+               zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared 
memory!");
+               return ALLOC_FAILURE;;
+       }
+
        ZCG(locked) = 0;
 
        return res;
@@ -277,7 +291,6 @@ static size_t zend_shared_alloc_get_largest_free_block(void)
                zend_accel_error(ACCEL_LOG_WARNING, "Not enough free shared 
space to allocate %ld bytes (%ld bytes free)", (long)size, 
(long)ZSMMG(shared_free)); \
                if (zend_shared_alloc_get_largest_free_block() < 
MIN_FREE_MEMORY) { \
                        ZSMMG(memory_exhausted) = 1; \
-                       zend_accel_schedule_restart(ACCEL_RESTART_OOM 
TSRMLS_CC); \
                } \
        } while (0)
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to