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