mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Expose time spent collecting cycles in gc_status() (#11523)
This commit is contained in:
12
UPGRADING
12
UPGRADING
@@ -146,12 +146,20 @@ PHP 8.3 UPGRADE NOTES
|
||||
========================================
|
||||
|
||||
- Core:
|
||||
. gc_status() has added the following 4 fields:
|
||||
. gc_status() has added the following 8 fields:
|
||||
"running" => bool
|
||||
"protected" => bool
|
||||
"full" => bool
|
||||
"buffer_size" => int
|
||||
See GH-9336
|
||||
"application_time" => float: Total application time, in seconds (including
|
||||
collector_time)
|
||||
"collector_time" => float: Time spent collecting cycles, in seconds
|
||||
(including destructor_time and free_time)
|
||||
"destructor_time" => float: Time spent executing destructors during
|
||||
cycle collection, in seconds
|
||||
"free_time" => float: Time spent freeing values during cycle collection, in
|
||||
seconds
|
||||
See GH-9336, GH-11523
|
||||
. class_alias() now supports creating an alias of an internal class.
|
||||
. Setting `open_basedir` at runtime using `ini_set('open_basedir', ...);` no
|
||||
longer accepts paths containing the parent directory (`..`). Previously,
|
||||
|
||||
@@ -67,6 +67,10 @@ PHP 8.3 INTERNALS UPGRADE NOTES
|
||||
- zend_set_user_opcode_handler
|
||||
- zend_ssa_inference
|
||||
* Removed unused macros PHP_FNV1_32A_INIT and PHP_FNV1A_64_INIT. See GH-11114.
|
||||
* ext/standard/hrtime.h was moved to Zend/zend_hrtime.h
|
||||
* The prefix of the PHP_HRTIME_ macros was changed to ZEND_HRTIME_
|
||||
* The HRTIME_AVAILABLE macro was renamed to ZEND_HRTIME_AVAILABLE
|
||||
* The php_hrtime_current() function was renamed to zend_hrtime()
|
||||
* _php_stream_dirent now has an extra d_type field that is used to store the
|
||||
directory entry type. This can be used to avoid additional stat calls for
|
||||
types when the type is already known.
|
||||
|
||||
@@ -12,8 +12,8 @@ gc_collect_cycles();
|
||||
gc_collect_cycles();
|
||||
var_dump(gc_status());
|
||||
?>
|
||||
--EXPECT--
|
||||
array(8) {
|
||||
--EXPECTF--
|
||||
array(12) {
|
||||
["running"]=>
|
||||
bool(false)
|
||||
["protected"]=>
|
||||
@@ -30,8 +30,16 @@ array(8) {
|
||||
int(16384)
|
||||
["roots"]=>
|
||||
int(1)
|
||||
["application_time"]=>
|
||||
float(%f)
|
||||
["collector_time"]=>
|
||||
float(%f)
|
||||
["destructor_time"]=>
|
||||
float(%f)
|
||||
["free_time"]=>
|
||||
float(%f)
|
||||
}
|
||||
array(8) {
|
||||
array(12) {
|
||||
["running"]=>
|
||||
bool(false)
|
||||
["protected"]=>
|
||||
@@ -48,4 +56,12 @@ array(8) {
|
||||
int(16384)
|
||||
["roots"]=>
|
||||
int(0)
|
||||
["application_time"]=>
|
||||
float(%f)
|
||||
["collector_time"]=>
|
||||
float(%f)
|
||||
["destructor_time"]=>
|
||||
float(%f)
|
||||
["free_time"]=>
|
||||
float(%f)
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ for ($j = 0; $j < 10; $j++) {
|
||||
|
||||
var_dump(gc_status());
|
||||
?>
|
||||
--EXPECT--
|
||||
array(8) {
|
||||
--EXPECTF--
|
||||
array(12) {
|
||||
["running"]=>
|
||||
bool(false)
|
||||
["protected"]=>
|
||||
@@ -63,4 +63,12 @@ array(8) {
|
||||
int(16384)
|
||||
["roots"]=>
|
||||
int(10000)
|
||||
["application_time"]=>
|
||||
float(%f)
|
||||
["collector_time"]=>
|
||||
float(%f)
|
||||
["destructor_time"]=>
|
||||
float(%f)
|
||||
["free_time"]=>
|
||||
float(%f)
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "zend_fibers.h"
|
||||
#include "zend_call_stack.h"
|
||||
#include "zend_max_execution_timer.h"
|
||||
#include "zend_hrtime.h"
|
||||
#include "Optimizer/zend_optimizer.h"
|
||||
|
||||
static size_t global_map_ptr_last = 0;
|
||||
@@ -899,6 +900,7 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */
|
||||
fpsetmask(0);
|
||||
#endif
|
||||
|
||||
zend_startup_hrtime();
|
||||
zend_startup_strtod();
|
||||
zend_startup_extensions_mechanism();
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ ZEND_FUNCTION(gc_status)
|
||||
|
||||
zend_gc_get_status(&status);
|
||||
|
||||
array_init_size(return_value, 8);
|
||||
array_init_size(return_value, 16);
|
||||
|
||||
add_assoc_bool_ex(return_value, "running", sizeof("running")-1, status.active);
|
||||
add_assoc_bool_ex(return_value, "protected", sizeof("protected")-1, status.gc_protected);
|
||||
@@ -148,6 +148,12 @@ ZEND_FUNCTION(gc_status)
|
||||
add_assoc_long_ex(return_value, "threshold", sizeof("threshold")-1, (long)status.threshold);
|
||||
add_assoc_long_ex(return_value, "buffer_size", sizeof("buffer_size")-1, (long)status.buf_size);
|
||||
add_assoc_long_ex(return_value, "roots", sizeof("roots")-1, (long)status.num_roots);
|
||||
|
||||
/* Using double because zend_long may be too small on some platforms */
|
||||
add_assoc_double_ex(return_value, "application_time", sizeof("application_time")-1, (double) status.application_time / ZEND_NANO_IN_SEC);
|
||||
add_assoc_double_ex(return_value, "collector_time", sizeof("collector_time")-1, (double) status.collector_time / ZEND_NANO_IN_SEC);
|
||||
add_assoc_double_ex(return_value, "destructor_time", sizeof("destructor_time")-1, (double) status.dtor_time / ZEND_NANO_IN_SEC);
|
||||
add_assoc_double_ex(return_value, "free_time", sizeof("free_time")-1, (double) status.free_time / ZEND_NANO_IN_SEC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#include "zend.h"
|
||||
#include "zend_API.h"
|
||||
#include "zend_fibers.h"
|
||||
#include "zend_hrtime.h"
|
||||
|
||||
#ifndef ZEND_GC_DEBUG
|
||||
# define ZEND_GC_DEBUG 0
|
||||
@@ -220,6 +221,11 @@ typedef struct _zend_gc_globals {
|
||||
uint32_t gc_runs;
|
||||
uint32_t collected;
|
||||
|
||||
zend_hrtime_t activated_at;
|
||||
zend_hrtime_t collector_time;
|
||||
zend_hrtime_t dtor_time;
|
||||
zend_hrtime_t free_time;
|
||||
|
||||
#if GC_BENCH
|
||||
uint32_t root_buf_length;
|
||||
uint32_t root_buf_peak;
|
||||
@@ -439,6 +445,10 @@ static void gc_globals_ctor_ex(zend_gc_globals *gc_globals)
|
||||
|
||||
gc_globals->gc_runs = 0;
|
||||
gc_globals->collected = 0;
|
||||
gc_globals->collector_time = 0;
|
||||
gc_globals->dtor_time = 0;
|
||||
gc_globals->free_time = 0;
|
||||
gc_globals->activated_at = 0;
|
||||
|
||||
#if GC_BENCH
|
||||
gc_globals->root_buf_length = 0;
|
||||
@@ -479,6 +489,10 @@ void gc_reset(void)
|
||||
GC_G(gc_runs) = 0;
|
||||
GC_G(collected) = 0;
|
||||
|
||||
GC_G(collector_time) = 0;
|
||||
GC_G(dtor_time) = 0;
|
||||
GC_G(free_time) = 0;
|
||||
|
||||
#if GC_BENCH
|
||||
GC_G(root_buf_length) = 0;
|
||||
GC_G(root_buf_peak) = 0;
|
||||
@@ -488,6 +502,8 @@ void gc_reset(void)
|
||||
GC_G(zval_marked_grey) = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
GC_G(activated_at) = zend_hrtime();
|
||||
}
|
||||
|
||||
ZEND_API bool gc_enable(bool enable)
|
||||
@@ -1469,6 +1485,8 @@ ZEND_API int zend_gc_collect_cycles(void)
|
||||
bool should_rerun_gc = 0;
|
||||
bool did_rerun_gc = 0;
|
||||
|
||||
zend_hrtime_t start_time = zend_hrtime();
|
||||
|
||||
rerun_gc:
|
||||
if (GC_G(num_roots)) {
|
||||
int count;
|
||||
@@ -1482,6 +1500,7 @@ rerun_gc:
|
||||
stack.next = NULL;
|
||||
|
||||
if (GC_G(gc_active)) {
|
||||
GC_G(collector_time) += zend_hrtime() - start_time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1561,6 +1580,7 @@ rerun_gc:
|
||||
*
|
||||
* The root buffer might be reallocated during destructors calls,
|
||||
* make sure to reload pointers as necessary. */
|
||||
zend_hrtime_t dtor_start_time = zend_hrtime();
|
||||
idx = GC_FIRST_ROOT;
|
||||
while (idx != end) {
|
||||
current = GC_IDX2PTR(idx);
|
||||
@@ -1582,11 +1602,13 @@ rerun_gc:
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
GC_G(dtor_time) += zend_hrtime() - dtor_start_time;
|
||||
|
||||
if (GC_G(gc_protected)) {
|
||||
/* something went wrong */
|
||||
zend_get_gc_buffer_release();
|
||||
zend_fiber_switch_unblock();
|
||||
GC_G(collector_time) += zend_hrtime() - start_time;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1595,6 +1617,7 @@ rerun_gc:
|
||||
|
||||
/* Destroy zvals. The root buffer may be reallocated. */
|
||||
GC_TRACE("Destroying zvals");
|
||||
zend_hrtime_t free_start_time = zend_hrtime();
|
||||
idx = GC_FIRST_ROOT;
|
||||
while (idx != end) {
|
||||
current = GC_IDX2PTR(idx);
|
||||
@@ -1645,6 +1668,8 @@ rerun_gc:
|
||||
current++;
|
||||
}
|
||||
|
||||
GC_G(free_time) += zend_hrtime() - free_start_time;
|
||||
|
||||
zend_fiber_switch_unblock();
|
||||
|
||||
GC_TRACE("Collection finished");
|
||||
@@ -1666,6 +1691,7 @@ rerun_gc:
|
||||
finish:
|
||||
zend_get_gc_buffer_release();
|
||||
zend_gc_root_tmpvars();
|
||||
GC_G(collector_time) += zend_hrtime() - start_time;
|
||||
return total_count;
|
||||
}
|
||||
|
||||
@@ -1679,6 +1705,10 @@ ZEND_API void zend_gc_get_status(zend_gc_status *status)
|
||||
status->threshold = GC_G(gc_threshold);
|
||||
status->buf_size = GC_G(buf_size);
|
||||
status->num_roots = GC_G(num_roots);
|
||||
status->application_time = zend_hrtime() - GC_G(activated_at);
|
||||
status->collector_time = GC_G(collector_time);
|
||||
status->dtor_time = GC_G(dtor_time);
|
||||
status->free_time = GC_G(free_time);
|
||||
}
|
||||
|
||||
ZEND_API zend_get_gc_buffer *zend_get_gc_buffer_create(void) {
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef ZEND_GC_H
|
||||
#define ZEND_GC_H
|
||||
|
||||
#include "zend_hrtime.h"
|
||||
|
||||
#ifndef GC_BENCH
|
||||
# define GC_BENCH 0
|
||||
#endif
|
||||
@@ -35,6 +37,10 @@ typedef struct _zend_gc_status {
|
||||
uint32_t threshold;
|
||||
uint32_t buf_size;
|
||||
uint32_t num_roots;
|
||||
zend_hrtime_t application_time;
|
||||
zend_hrtime_t collector_time;
|
||||
zend_hrtime_t dtor_time;
|
||||
zend_hrtime_t free_time;
|
||||
} zend_gc_status;
|
||||
|
||||
ZEND_API extern int (*gc_collect_cycles)(void);
|
||||
|
||||
70
Zend/zend_hrtime.c
Normal file
70
Zend/zend_hrtime.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| https://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Niklas Keller <kelunik@php.net> |
|
||||
| Author: Anatol Belski <ab@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_hrtime.h"
|
||||
|
||||
/* This file reuses code parts from the cross-platform timer library
|
||||
Public Domain - 2011 Mattias Jansson / Rampant Pixels */
|
||||
|
||||
#if ZEND_HRTIME_PLATFORM_POSIX
|
||||
|
||||
# include <unistd.h>
|
||||
# include <time.h>
|
||||
# include <string.h>
|
||||
|
||||
#elif ZEND_HRTIME_PLATFORM_WINDOWS
|
||||
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
|
||||
double zend_hrtime_timer_scale = .0;
|
||||
|
||||
#elif ZEND_HRTIME_PLATFORM_APPLE
|
||||
|
||||
# include <mach/mach_time.h>
|
||||
# include <string.h>
|
||||
mach_timebase_info_data_t zend_hrtime_timerlib_info = {
|
||||
.numer = 0,
|
||||
.denom = 1,
|
||||
};
|
||||
|
||||
#elif ZEND_HRTIME_PLATFORM_HPUX
|
||||
|
||||
# include <sys/time.h>
|
||||
|
||||
#elif ZEND_HRTIME_PLATFORM_AIX
|
||||
|
||||
# include <sys/time.h>
|
||||
# include <sys/systemcfg.h>
|
||||
|
||||
#endif
|
||||
|
||||
void zend_startup_hrtime(void)
|
||||
{
|
||||
#if ZEND_HRTIME_PLATFORM_WINDOWS
|
||||
|
||||
LARGE_INTEGER tf = {0};
|
||||
if (QueryPerformanceFrequency(&tf) || 0 != tf.QuadPart) {
|
||||
zend_hrtime_timer_scale = (double)ZEND_NANO_IN_SEC / (zend_hrtime_t)tf.QuadPart;
|
||||
}
|
||||
|
||||
#elif ZEND_HRTIME_PLATFORM_APPLE
|
||||
|
||||
mach_timebase_info(&zend_hrtime_timerlib_info);
|
||||
|
||||
#endif
|
||||
}
|
||||
107
Zend/zend_hrtime.h
Normal file
107
Zend/zend_hrtime.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| https://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Niklas Keller <kelunik@php.net> |
|
||||
| Author: Anatol Belski <ab@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef ZEND_HRTIME_H
|
||||
#define ZEND_HRTIME_H
|
||||
|
||||
#include "zend_portability.h"
|
||||
#include "zend_types.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_TIME_H
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
/* This file reuses code parts from the cross-platform timer library
|
||||
Public Domain - 2011 Mattias Jansson / Rampant Pixels */
|
||||
|
||||
#define ZEND_HRTIME_PLATFORM_POSIX 0
|
||||
#define ZEND_HRTIME_PLATFORM_WINDOWS 0
|
||||
#define ZEND_HRTIME_PLATFORM_APPLE 0
|
||||
#define ZEND_HRTIME_PLATFORM_HPUX 0
|
||||
#define ZEND_HRTIME_PLATFORM_AIX 0
|
||||
|
||||
#if defined(_POSIX_TIMERS) && ((_POSIX_TIMERS > 0) || defined(__OpenBSD__)) && defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC)
|
||||
# undef ZEND_HRTIME_PLATFORM_POSIX
|
||||
# define ZEND_HRTIME_PLATFORM_POSIX 1
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
# undef ZEND_HRTIME_PLATFORM_WINDOWS
|
||||
# define ZEND_HRTIME_PLATFORM_WINDOWS 1
|
||||
#elif defined(__APPLE__)
|
||||
# undef ZEND_HRTIME_PLATFORM_APPLE
|
||||
# define ZEND_HRTIME_PLATFORM_APPLE 1
|
||||
#elif (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__)))
|
||||
# undef ZEND_HRTIME_PLATFORM_HPUX
|
||||
# define ZEND_HRTIME_PLATFORM_HPUX 1
|
||||
#elif defined(_AIX)
|
||||
# undef ZEND_HRTIME_PLATFORM_AIX
|
||||
# define ZEND_HRTIME_PLATFORM_AIX 1
|
||||
#endif
|
||||
|
||||
#define ZEND_HRTIME_AVAILABLE (ZEND_HRTIME_PLATFORM_POSIX || ZEND_HRTIME_PLATFORM_WINDOWS || ZEND_HRTIME_PLATFORM_APPLE || ZEND_HRTIME_PLATFORM_HPUX || ZEND_HRTIME_PLATFORM_AIX)
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
#if ZEND_HRTIME_PLATFORM_WINDOWS
|
||||
|
||||
extern double zend_hrtime_timer_scale;
|
||||
|
||||
#elif ZEND_HRTIME_PLATFORM_APPLE
|
||||
|
||||
# include <mach/mach_time.h>
|
||||
# include <string.h>
|
||||
extern mach_timebase_info_data_t zend_hrtime_timerlib_info;
|
||||
|
||||
#endif
|
||||
|
||||
#define ZEND_NANO_IN_SEC UINT64_C(1000000000)
|
||||
|
||||
typedef uint64_t zend_hrtime_t;
|
||||
|
||||
void zend_startup_hrtime(void);
|
||||
|
||||
static zend_always_inline zend_hrtime_t zend_hrtime(void)
|
||||
{
|
||||
#if ZEND_HRTIME_PLATFORM_WINDOWS
|
||||
LARGE_INTEGER lt = {0};
|
||||
QueryPerformanceCounter(<);
|
||||
return (zend_hrtime_t)((zend_hrtime_t)lt.QuadPart * zend_hrtime_timer_scale);
|
||||
#elif ZEND_HRTIME_PLATFORM_APPLE
|
||||
return (zend_hrtime_t)mach_absolute_time() * zend_hrtime_timerlib_info.numer / zend_hrtime_timerlib_info.denom;
|
||||
#elif ZEND_HRTIME_PLATFORM_POSIX
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
|
||||
if (EXPECTED(0 == clock_gettime(CLOCK_MONOTONIC, &ts))) {
|
||||
return ((zend_hrtime_t) ts.tv_sec * (zend_hrtime_t)ZEND_NANO_IN_SEC) + ts.tv_nsec;
|
||||
}
|
||||
return 0;
|
||||
#elif ZEND_HRTIME_PLATFORM_HPUX
|
||||
return (zend_hrtime_t) gethrtime();
|
||||
#elif ZEND_HRTIME_PLATFORM_AIX
|
||||
timebasestruct_t t;
|
||||
read_wall_time(&t, TIMEBASE_SZ);
|
||||
time_base_to_time(&t, TIMEBASE_SZ);
|
||||
return (zend_hrtime_t) t.tb_high * (zend_hrtime_t)NANO_IN_SEC + t.tb_low;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif /* ZEND_HRTIME_H */
|
||||
@@ -396,6 +396,7 @@ dirent.h \
|
||||
sys/param.h \
|
||||
sys/types.h \
|
||||
sys/time.h \
|
||||
time.h \
|
||||
netinet/in.h \
|
||||
alloca.h \
|
||||
arpa/inet.h \
|
||||
@@ -1734,6 +1735,7 @@ PHP_ADD_SOURCES(Zend, \
|
||||
zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c \
|
||||
zend_observer.c zend_system_id.c zend_enum.c zend_fibers.c zend_atomic.c \
|
||||
zend_max_execution_timer.c \
|
||||
zend_hrtime.c \
|
||||
Optimizer/zend_optimizer.c \
|
||||
Optimizer/pass1.c \
|
||||
Optimizer/pass3.c \
|
||||
|
||||
@@ -352,8 +352,6 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
|
||||
php_register_url_stream_wrapper("http", &php_stream_http_wrapper);
|
||||
php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper);
|
||||
|
||||
BASIC_MINIT_SUBMODULE(hrtime)
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -16,123 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "php.h"
|
||||
#include "hrtime.h"
|
||||
|
||||
/* {{{ */
|
||||
/* This file reuses code parts from the cross-platform timer library
|
||||
Public Domain - 2011 Mattias Jansson / Rampant Pixels */
|
||||
|
||||
#if PHP_HRTIME_PLATFORM_POSIX
|
||||
|
||||
# include <unistd.h>
|
||||
# include <time.h>
|
||||
# include <string.h>
|
||||
|
||||
#elif PHP_HRTIME_PLATFORM_WINDOWS
|
||||
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
|
||||
static double _timer_scale = .0;
|
||||
|
||||
#elif PHP_HRTIME_PLATFORM_APPLE
|
||||
|
||||
# include <mach/mach_time.h>
|
||||
# include <string.h>
|
||||
static mach_timebase_info_data_t _timerlib_info;
|
||||
|
||||
#elif PHP_HRTIME_PLATFORM_HPUX
|
||||
|
||||
# include <sys/time.h>
|
||||
|
||||
#elif PHP_HRTIME_PLATFORM_AIX
|
||||
|
||||
# include <sys/time.h>
|
||||
# include <sys/systemcfg.h>
|
||||
|
||||
#endif
|
||||
|
||||
#define NANO_IN_SEC 1000000000
|
||||
/* }}} */
|
||||
|
||||
static int _timer_init(void)
|
||||
{/*{{{*/
|
||||
#if PHP_HRTIME_PLATFORM_WINDOWS
|
||||
|
||||
LARGE_INTEGER tf = {0};
|
||||
if (!QueryPerformanceFrequency(&tf) || 0 == tf.QuadPart) {
|
||||
return -1;
|
||||
}
|
||||
_timer_scale = (double)NANO_IN_SEC / (php_hrtime_t)tf.QuadPart;
|
||||
|
||||
#elif PHP_HRTIME_PLATFORM_APPLE
|
||||
|
||||
if (mach_timebase_info(&_timerlib_info)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#elif PHP_HRTIME_PLATFORM_POSIX
|
||||
|
||||
#if !_POSIX_MONOTONIC_CLOCK
|
||||
#ifdef _SC_MONOTONIC_CLOCK
|
||||
if (0 >= sysconf(_SC_MONOTONIC_CLOCK)) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif PHP_HRTIME_PLATFORM_HPUX
|
||||
|
||||
/* pass */
|
||||
|
||||
#elif PHP_HRTIME_PLATFORM_AIX
|
||||
|
||||
/* pass */
|
||||
|
||||
#else
|
||||
/* Timer unavailable. */
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}/*}}}*/
|
||||
|
||||
/* {{{ */
|
||||
PHP_MINIT_FUNCTION(hrtime)
|
||||
{
|
||||
if (0 > _timer_init()) {
|
||||
php_error_docref(NULL, E_WARNING, "Failed to initialize high-resolution timer");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_always_inline php_hrtime_t _timer_current(void)
|
||||
{/*{{{*/
|
||||
#if PHP_HRTIME_PLATFORM_WINDOWS
|
||||
LARGE_INTEGER lt = {0};
|
||||
QueryPerformanceCounter(<);
|
||||
return (php_hrtime_t)((php_hrtime_t)lt.QuadPart * _timer_scale);
|
||||
#elif PHP_HRTIME_PLATFORM_APPLE
|
||||
return (php_hrtime_t)mach_absolute_time() * _timerlib_info.numer / _timerlib_info.denom;
|
||||
#elif PHP_HRTIME_PLATFORM_POSIX
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
|
||||
if (0 == clock_gettime(CLOCK_MONOTONIC, &ts)) {
|
||||
return ((php_hrtime_t) ts.tv_sec * (php_hrtime_t)NANO_IN_SEC) + ts.tv_nsec;
|
||||
}
|
||||
return 0;
|
||||
#elif PHP_HRTIME_PLATFORM_HPUX
|
||||
return (php_hrtime_t) gethrtime();
|
||||
#elif PHP_HRTIME_PLATFORM_AIX
|
||||
timebasestruct_t t;
|
||||
read_wall_time(&t, TIMEBASE_SZ);
|
||||
time_base_to_time(&t, TIMEBASE_SZ);
|
||||
return (php_hrtime_t) t.tb_high * (php_hrtime_t)NANO_IN_SEC + t.tb_low;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}/*}}}*/
|
||||
#include "zend_hrtime.h"
|
||||
|
||||
#ifdef ZEND_ENABLE_ZVAL_LONG64
|
||||
#define PHP_RETURN_HRTIME(t) RETURN_LONG((zend_long)t)
|
||||
@@ -162,9 +46,9 @@ static zend_always_inline php_hrtime_t _timer_current(void)
|
||||
delivered timestamp is monotonic and cannot be adjusted. */
|
||||
PHP_FUNCTION(hrtime)
|
||||
{
|
||||
#if HRTIME_AVAILABLE
|
||||
#if ZEND_HRTIME_AVAILABLE
|
||||
bool get_as_num = 0;
|
||||
php_hrtime_t t = _timer_current();
|
||||
zend_hrtime_t t = zend_hrtime();
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(0, 1)
|
||||
Z_PARAM_OPTIONAL
|
||||
@@ -176,16 +60,11 @@ PHP_FUNCTION(hrtime)
|
||||
} else {
|
||||
array_init_size(return_value, 2);
|
||||
zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
|
||||
add_next_index_long(return_value, (zend_long)(t / (php_hrtime_t)NANO_IN_SEC));
|
||||
add_next_index_long(return_value, (zend_long)(t % (php_hrtime_t)NANO_IN_SEC));
|
||||
add_next_index_long(return_value, (zend_long)(t / (zend_hrtime_t)ZEND_NANO_IN_SEC));
|
||||
add_next_index_long(return_value, (zend_long)(t % (zend_hrtime_t)ZEND_NANO_IN_SEC));
|
||||
}
|
||||
#else
|
||||
RETURN_FALSE;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHPAPI php_hrtime_t php_hrtime_current(void)
|
||||
{/*{{{*/
|
||||
return _timer_current();
|
||||
}/*}}}*/
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| https://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Niklas Keller <kelunik@php.net> |
|
||||
| Author: Anatol Belski <ab@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef HRTIME_H
|
||||
#define HRTIME_H
|
||||
|
||||
#define PHP_HRTIME_PLATFORM_POSIX 0
|
||||
#define PHP_HRTIME_PLATFORM_WINDOWS 0
|
||||
#define PHP_HRTIME_PLATFORM_APPLE 0
|
||||
#define PHP_HRTIME_PLATFORM_HPUX 0
|
||||
#define PHP_HRTIME_PLATFORM_AIX 0
|
||||
|
||||
#if defined(_POSIX_TIMERS) && ((_POSIX_TIMERS > 0) || defined(__OpenBSD__)) && defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC)
|
||||
# undef PHP_HRTIME_PLATFORM_POSIX
|
||||
# define PHP_HRTIME_PLATFORM_POSIX 1
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
# undef PHP_HRTIME_PLATFORM_WINDOWS
|
||||
# define PHP_HRTIME_PLATFORM_WINDOWS 1
|
||||
#elif defined(__APPLE__)
|
||||
# undef PHP_HRTIME_PLATFORM_APPLE
|
||||
# define PHP_HRTIME_PLATFORM_APPLE 1
|
||||
#elif (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__)))
|
||||
# undef PHP_HRTIME_PLATFORM_HPUX
|
||||
# define PHP_HRTIME_PLATFORM_HPUX 1
|
||||
#elif defined(_AIX)
|
||||
# undef PHP_HRTIME_PLATFORM_AIX
|
||||
# define PHP_HRTIME_PLATFORM_AIX 1
|
||||
#endif
|
||||
|
||||
#define HRTIME_AVAILABLE (PHP_HRTIME_PLATFORM_POSIX || PHP_HRTIME_PLATFORM_WINDOWS || PHP_HRTIME_PLATFORM_APPLE || PHP_HRTIME_PLATFORM_HPUX || PHP_HRTIME_PLATFORM_AIX)
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
typedef uint64_t php_hrtime_t;
|
||||
|
||||
PHPAPI php_hrtime_t php_hrtime_current(void);
|
||||
|
||||
PHP_MINIT_FUNCTION(hrtime);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif /* HRTIME_H */
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "php_mail.h"
|
||||
#include "md5.h"
|
||||
#include "sha1.h"
|
||||
#include "hrtime.h"
|
||||
#include "html.h"
|
||||
#include "exec.h"
|
||||
#include "file.h"
|
||||
|
||||
@@ -240,7 +240,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
|
||||
zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \
|
||||
zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \
|
||||
zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_observer.c zend_system_id.c \
|
||||
zend_enum.c zend_fibers.c zend_atomic.c");
|
||||
zend_enum.c zend_fibers.c zend_atomic.c zend_hrtime.c");
|
||||
ADD_SOURCES("Zend\\Optimizer", "zend_optimizer.c pass1.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dfg.c dfa_pass.c zend_ssa.c zend_inference.c zend_func_info.c zend_call_graph.c zend_dump.c escape_analysis.c compact_vars.c dce.c sccp.c scdf.c");
|
||||
|
||||
var PHP_ASSEMBLER = PATH_PROG({
|
||||
|
||||
Reference in New Issue
Block a user