void zend_accel_info(ZEND_MODULE_INFO_FUNC_ARGS) { php_info_print_table_start(); if (ZCG(enabled) && accel_startup_ok && #ifdef HAVE_OPCACHE_FILE_CACHE ((ZCG(counted) || ZCSG(accelerator_enabled)) || ZCG(accel_directives).file_cache_only) #else (ZCG(counted) || ZCSG(accelerator_enabled)) #endif ) { php_info_print_table_row(2, "Opcode Caching", "Up and Running"); } else { php_info_print_table_row(2, "Opcode Caching", "Disabled"); } if (ZCG(enabled) && accel_startup_ok && ZCG(accel_directives).optimization_level) { php_info_print_table_row(2, "Optimization", "Enabled"); } else { php_info_print_table_row(2, "Optimization", "Disabled"); } #ifdef HAVE_OPCACHE_FILE_CACHE if (!ZCG(accel_directives).file_cache_only) { php_info_print_table_row(2, "SHM Cache", "Enabled"); } else { php_info_print_table_row(2, "SHM Cache", "Disabled"); } if (ZCG(accel_directives).file_cache) { php_info_print_table_row(2, "File Cache", "Enabled"); } else { php_info_print_table_row(2, "File Cache", "Disabled"); } if (ZCG(accel_directives).file_cache_only) { if (!accel_startup_ok || zps_api_failure_reason) { php_info_print_table_row(2, "Startup Failed", zps_api_failure_reason); } else { php_info_print_table_row(2, "Startup", "OK"); } } else #endif if (ZCG(enabled)) { if (!accel_startup_ok || zps_api_failure_reason) { php_info_print_table_row(2, "Startup Failed", zps_api_failure_reason); } else { char buf[32]; php_info_print_table_row(2, "Startup", "OK"); php_info_print_table_row(2, "Shared memory model", zend_accel_get_shared_model()); snprintf(buf, sizeof(buf), "%pd", (zend_ulong)ZCSG(hits)); php_info_print_table_row(2, "Cache hits", buf); snprintf(buf, sizeof(buf), "%pd", ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses)); php_info_print_table_row(2, "Cache misses", buf); snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ZCG(accel_directives).memory_consumption-zend_shared_alloc_get_free_memory()-ZSMMG(wasted_shared_memory)); php_info_print_table_row(2, "Used memory", buf); snprintf(buf, sizeof(buf), "%pd", zend_shared_alloc_get_free_memory()); php_info_print_table_row(2, "Free memory", buf); snprintf(buf, sizeof(buf), "%pd", ZSMMG(wasted_shared_memory)); php_info_print_table_row(2, "Wasted memory", buf); if (ZCSG(interned_strings_start) && ZCSG(interned_strings_end) && ZCSG(interned_strings_top)) { snprintf(buf, sizeof(buf), "%pd", ZCSG(interned_strings_top) - ZCSG(interned_strings_start)); php_info_print_table_row(2, "Interned Strings Used memory", buf); snprintf(buf, sizeof(buf), "%pd", ZCSG(interned_strings_end) - ZCSG(interned_strings_top)); php_info_print_table_row(2, "Interned Strings Free memory", buf); } snprintf(buf, sizeof(buf), "%ld", ZCSG(hash).num_direct_entries); php_info_print_table_row(2, "Cached scripts", buf); snprintf(buf, sizeof(buf), "%ld", ZCSG(hash).num_entries); php_info_print_table_row(2, "Cached keys", buf); snprintf(buf, sizeof(buf), "%pd", ZCSG(hash).max_num_entries); php_info_print_table_row(2, "Max keys", buf); snprintf(buf, sizeof(buf), "%pd", ZCSG(oom_restarts)); php_info_print_table_row(2, "OOM restarts", buf); snprintf(buf, sizeof(buf), "%pd", ZCSG(hash_restarts)); php_info_print_table_row(2, "Hash keys restarts", buf); snprintf(buf, sizeof(buf), "%pd", ZCSG(manual_restarts)); php_info_print_table_row(2, "Manual restarts", buf); } } php_info_print_table_end(); DISPLAY_INI_ENTRIES(); }
/* {{{ proto array accelerator_get_status([bool fetch_scripts]) Obtain statistics information regarding code acceleration */ static ZEND_FUNCTION(opcache_get_status) { zend_long reqs; zval memory_usage, statistics, scripts; zend_bool fetch_scripts = 1; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &fetch_scripts) == FAILURE) { return; } if (!validate_api_restriction()) { RETURN_FALSE; } if (!accel_startup_ok) { RETURN_FALSE; } array_init(return_value); /* Trivia */ add_assoc_bool(return_value, "opcache_enabled", ZCG(enabled) && (ZCG(counted) || ZCSG(accelerator_enabled))); #ifdef HAVE_OPCACHE_FILE_CACHE if (ZCG(accel_directives).file_cache) { add_assoc_string(return_value, "file_cache", ZCG(accel_directives).file_cache); } if (ZCG(accel_directives).file_cache_only) { add_assoc_bool(return_value, "file_cache_only", 1); return; } #endif add_assoc_bool(return_value, "cache_full", ZSMMG(memory_exhausted)); add_assoc_bool(return_value, "restart_pending", ZCSG(restart_pending)); add_assoc_bool(return_value, "restart_in_progress", ZCSG(restart_in_progress)); /* Memory usage statistics */ array_init(&memory_usage); add_assoc_long(&memory_usage, "used_memory", ZCG(accel_directives).memory_consumption-zend_shared_alloc_get_free_memory()-ZSMMG(wasted_shared_memory)); add_assoc_long(&memory_usage, "free_memory", zend_shared_alloc_get_free_memory()); add_assoc_long(&memory_usage, "wasted_memory", ZSMMG(wasted_shared_memory)); add_assoc_double(&memory_usage, "current_wasted_percentage", (((double) ZSMMG(wasted_shared_memory))/ZCG(accel_directives).memory_consumption)*100.0); add_assoc_zval(return_value, "memory_usage", &memory_usage); if (ZCSG(interned_strings_start) && ZCSG(interned_strings_end) && ZCSG(interned_strings_top)) { zval interned_strings_usage; array_init(&interned_strings_usage); add_assoc_long(&interned_strings_usage, "buffer_size", ZCSG(interned_strings_end) - ZCSG(interned_strings_start)); add_assoc_long(&interned_strings_usage, "used_memory", ZCSG(interned_strings_top) - ZCSG(interned_strings_start)); add_assoc_long(&interned_strings_usage, "free_memory", ZCSG(interned_strings_end) - ZCSG(interned_strings_top)); add_assoc_long(&interned_strings_usage, "number_of_strings", ZCSG(interned_strings).nNumOfElements); add_assoc_zval(return_value, "interned_strings_usage", &interned_strings_usage); } /* Accelerator statistics */ array_init(&statistics); add_assoc_long(&statistics, "num_cached_scripts", ZCSG(hash).num_direct_entries); add_assoc_long(&statistics, "num_cached_keys", ZCSG(hash).num_entries); add_assoc_long(&statistics, "max_cached_keys", ZCSG(hash).max_num_entries); add_assoc_long(&statistics, "hits", (zend_long)ZCSG(hits)); 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, "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)); add_assoc_long(&statistics, "blacklist_misses", ZCSG(blacklist_misses)); reqs = ZCSG(hits)+ZCSG(misses); add_assoc_double(&statistics, "blacklist_miss_ratio", reqs?(((double) ZCSG(blacklist_misses))/reqs)*100.0:0); add_assoc_double(&statistics, "opcache_hit_rate", reqs?(((double) ZCSG(hits))/reqs)*100.0:0); add_assoc_zval(return_value, "opcache_statistics", &statistics); if (fetch_scripts) { /* accelerated scripts */ if (accelerator_get_scripts(&scripts)) { add_assoc_zval(return_value, "scripts", &scripts); } } }
zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle) { zend_string *full_path = file_handle->opened_path; int fd; char *filename; zend_persistent_script *script; zend_file_cache_metainfo info; zend_accel_hash_entry *bucket; void *mem, *checkpoint, *buf; int cache_it = 1; if (!full_path) { return NULL; } filename = zend_file_cache_get_bin_file_path(full_path); fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) { efree(filename); return NULL; } if (zend_file_cache_flock(fd, LOCK_SH) != 0) { close(fd); efree(filename); return NULL; } if (read(fd, &info, sizeof(info)) != sizeof(info)) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s'\n", filename); zend_file_cache_flock(fd, LOCK_UN); close(fd); unlink(filename); efree(filename); return NULL; } /* verify header */ if (memcmp(info.magic, "OPCACHE", 8) != 0 || memcmp(info.system_id, ZCG(system_id), 32) != 0) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s'\n", filename); zend_file_cache_flock(fd, LOCK_UN); close(fd); unlink(filename); efree(filename); return NULL; } /* verify timestamp */ if (ZCG(accel_directives).validate_timestamps && zend_get_file_handle_timestamp(file_handle, NULL) != info.timestamp) { if (zend_file_cache_flock(fd, LOCK_UN) != 0) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot unlock file '%s'\n", filename); } close(fd); unlink(filename); efree(filename); return NULL; } checkpoint = zend_arena_checkpoint(CG(arena)); #ifdef __SSE2__ /* Align to 64-byte boundary */ mem = zend_arena_alloc(&CG(arena), info.mem_size + info.str_size + 64); mem = (void*)(((zend_uintptr_t)mem + 63L) & ~63L); #else mem = zend_arena_alloc(&CG(arena), info.mem_size + info.str_size); #endif if (read(fd, mem, info.mem_size + info.str_size) != (ssize_t)(info.mem_size + info.str_size)) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s'\n", filename); zend_file_cache_flock(fd, LOCK_UN); close(fd); unlink(filename); zend_arena_release(&CG(arena), checkpoint); efree(filename); return NULL; } if (zend_file_cache_flock(fd, LOCK_UN) != 0) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot unlock file '%s'\n", filename); } close(fd); /* verify checksum */ if (ZCG(accel_directives).file_cache_consistency_checks && zend_adler32(ADLER32_INIT, mem, info.mem_size + info.str_size) != info.checksum) { zend_accel_error(ACCEL_LOG_WARNING, "corrupted file '%s'\n", filename); unlink(filename); zend_arena_release(&CG(arena), checkpoint); efree(filename); return NULL; } if (!ZCG(accel_directives).file_cache_only) { /* exclusive lock */ zend_shared_alloc_lock(); /* Check if we still need to put the file into the cache (may be it was * already stored by another process. This final check is done under * exclusive lock) */ bucket = zend_accel_hash_find_entry(&ZCSG(hash), full_path); if (bucket) { script = (zend_persistent_script *)bucket->data; if (!script->corrupted) { zend_shared_alloc_unlock(); zend_arena_release(&CG(arena), checkpoint); efree(filename); return script; } } 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_if_necessary(ACCEL_RESTART_HASH); zend_shared_alloc_unlock(); goto use_process_mem; } #ifdef __SSE2__ /* Align to 64-byte boundary */ buf = zend_shared_alloc(info.mem_size + 64); buf = (void*)(((zend_uintptr_t)buf + 63L) & ~63L); #else buf = zend_shared_alloc(info.mem_size); #endif if (!buf) { zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM); zend_shared_alloc_unlock(); goto use_process_mem; } memcpy(buf, mem, info.mem_size); } else { use_process_mem: buf = mem; cache_it = 0; } ZCG(mem) = ((char*)mem + info.mem_size); script = (zend_persistent_script*)((char*)buf + info.script_offset); script->corrupted = !cache_it; /* used to check if script restored to SHM or process memory */ zend_file_cache_unserialize(script, buf); script->corrupted = 0; if (cache_it) { script->dynamic_members.checksum = zend_accel_script_checksum(script); zend_accel_hash_update(&ZCSG(hash), ZSTR_VAL(script->script.filename), ZSTR_LEN(script->script.filename), 0, script); zend_shared_alloc_unlock(); zend_arena_release(&CG(arena), checkpoint); } efree(filename); return script; }