diff --git a/NEWS b/NEWS index b723e8a11662c..a66c4c7b3a909 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,8 @@ PHP NEWS . Added PHP_BUILD_DATE constant. (cmb) . Added support for Closures in constant expressions. (timwolla, Volker Dusch) + . Use `clock_gettime_nsec_np()` for high resolution timer on macOS + if available. (timwolla) - Curl: . Added curl_multi_get_handles(). (timwolla) diff --git a/UPGRADING b/UPGRADING index 6446beec2d868..b36a59dc164ca 100644 --- a/UPGRADING +++ b/UPGRADING @@ -193,6 +193,11 @@ PHP 8.5 UPGRADE NOTES 13. Other Changes ======================================== +- Core: + The high resolution timer (`hrtime()`) on macOS now uses the recommended + `clock_gettime_nsec_np(CLOCK_UPTIME_RAW)` API instead of + `mach_absolute_time()`. + ======================================== 14. Performance Improvements ======================================== diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 47ea9c831d524..45791a34c5f80 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -151,6 +151,11 @@ AC_CHECK_FUNCS(m4_normalize([ pthread_stackseg_np ])) +AC_CHECK_DECL([clock_gettime_nsec_np], + [AC_DEFINE([HAVE_CLOCK_GETTIME_NSEC_NP], [1], + [Define to 1 if you have the declaration of 'clock_gettime_nsec_np'.])],, + [#include ]) + dnl dnl Check for sigsetjmp. If sigsetjmp is defined as a macro, use AC_CHECK_DECL dnl as a fallback since AC_CHECK_FUNC cannot detect macros. diff --git a/Zend/zend_hrtime.c b/Zend/zend_hrtime.c index bcf11964f1cea..7fa36b1b654f4 100644 --- a/Zend/zend_hrtime.c +++ b/Zend/zend_hrtime.c @@ -33,7 +33,7 @@ ZEND_API double zend_hrtime_timer_scale = .0; -#elif ZEND_HRTIME_PLATFORM_APPLE +#elif ZEND_HRTIME_PLATFORM_APPLE_MACH_ABSOLUTE # include # include @@ -62,7 +62,7 @@ void zend_startup_hrtime(void) zend_hrtime_timer_scale = (double)ZEND_NANO_IN_SEC / (zend_hrtime_t)tf.QuadPart; } -#elif ZEND_HRTIME_PLATFORM_APPLE +#elif ZEND_HRTIME_PLATFORM_APPLE_MACH_ABSOLUTE mach_timebase_info(&zend_hrtime_timerlib_info); diff --git a/Zend/zend_hrtime.h b/Zend/zend_hrtime.h index 1449c4e443cf2..b050caa9ef6cd 100644 --- a/Zend/zend_hrtime.h +++ b/Zend/zend_hrtime.h @@ -33,7 +33,8 @@ #define ZEND_HRTIME_PLATFORM_POSIX 0 #define ZEND_HRTIME_PLATFORM_WINDOWS 0 -#define ZEND_HRTIME_PLATFORM_APPLE 0 +#define ZEND_HRTIME_PLATFORM_APPLE_MACH_ABSOLUTE 0 +#define ZEND_HRTIME_PLATFORM_APPLE_GETTIME_NSEC 0 #define ZEND_HRTIME_PLATFORM_HPUX 0 #define ZEND_HRTIME_PLATFORM_AIX 0 @@ -43,9 +44,12 @@ #elif defined(_WIN32) || defined(_WIN64) # undef ZEND_HRTIME_PLATFORM_WINDOWS # define ZEND_HRTIME_PLATFORM_WINDOWS 1 +#elif HAVE_CLOCK_GETTIME_NSEC_NP +# undef ZEND_HRTIME_PLATFORM_APPLE_GETTIME_NSEC +# define ZEND_HRTIME_PLATFORM_APPLE_GETTIME_NSEC 1 #elif defined(__APPLE__) -# undef ZEND_HRTIME_PLATFORM_APPLE -# define ZEND_HRTIME_PLATFORM_APPLE 1 +# undef ZEND_HRTIME_PLATFORM_APPLE_MACH_ABSOLUTE +# define ZEND_HRTIME_PLATFORM_APPLE_MACH_ABSOLUTE 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 @@ -54,7 +58,7 @@ # 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) +#define ZEND_HRTIME_AVAILABLE (ZEND_HRTIME_PLATFORM_POSIX || ZEND_HRTIME_PLATFORM_WINDOWS || ZEND_HRTIME_PLATFORM_APPLE_MACH_ABSOLUTE || ZEND_HRTIME_PLATFORM_APPLE_GETTIME_NSEC || ZEND_HRTIME_PLATFORM_HPUX || ZEND_HRTIME_PLATFORM_AIX) BEGIN_EXTERN_C() @@ -82,7 +86,9 @@ static zend_always_inline zend_hrtime_t zend_hrtime(void) LARGE_INTEGER lt = {0}; QueryPerformanceCounter(<); return (zend_hrtime_t)((zend_hrtime_t)lt.QuadPart * zend_hrtime_timer_scale); -#elif ZEND_HRTIME_PLATFORM_APPLE +#elif ZEND_HRTIME_PLATFORM_APPLE_GETTIME_NSEC + return clock_gettime_nsec_np(CLOCK_UPTIME_RAW); +#elif ZEND_HRTIME_PLATFORM_APPLE_MACH_ABSOLUTE 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 }; diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 938672ccc0c7d..86275ac34a1f1 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -4017,19 +4017,7 @@ PHP_FUNCTION(imageaffine) if ((zval_affine_elem = zend_hash_index_find(Z_ARRVAL_P(z_affine), i)) != NULL) { switch (Z_TYPE_P(zval_affine_elem)) { case IS_LONG: - affine[i] = Z_LVAL_P(zval_affine_elem); - if (affine[i] < INT_MIN || affine[i] > INT_MAX) { - zend_argument_value_error(2, "element %i must be between %d and %d", i, INT_MIN, INT_MAX); - RETURN_THROWS(); - } - break; case IS_DOUBLE: - affine[i] = Z_DVAL_P(zval_affine_elem); - if (affine[i] < INT_MIN || affine[i] > INT_MAX) { - zend_argument_value_error(2, "element %i must be between %d and %d", i, INT_MIN, INT_MAX); - RETURN_THROWS(); - } - break; case IS_STRING: affine[i] = zval_get_double(zval_affine_elem); if (affine[i] < INT_MIN || affine[i] > INT_MAX) { @@ -4195,11 +4183,7 @@ PHP_FUNCTION(imageaffinematrixconcat) if ((tmp = zend_hash_index_find(Z_ARRVAL_P(z_m1), i)) != NULL) { switch (Z_TYPE_P(tmp)) { case IS_LONG: - m1[i] = Z_LVAL_P(tmp); - break; case IS_DOUBLE: - m1[i] = Z_DVAL_P(tmp); - break; case IS_STRING: m1[i] = zval_get_double(tmp); break; @@ -4212,11 +4196,7 @@ PHP_FUNCTION(imageaffinematrixconcat) if ((tmp = zend_hash_index_find(Z_ARRVAL_P(z_m2), i)) != NULL) { switch (Z_TYPE_P(tmp)) { case IS_LONG: - m2[i] = Z_LVAL_P(tmp); - break; case IS_DOUBLE: - m2[i] = Z_DVAL_P(tmp); - break; case IS_STRING: m2[i] = zval_get_double(tmp); break;