Skip to content

Commit

Permalink
zend_hrtime: Use clock_gettime_nsec_np() for macOS if available (#1…
Browse files Browse the repository at this point in the history
…7089)

As per the Apple developer documentation:

> Prefer to use the equivalent clock_gettime_nsec_np(CLOCK_UPTIME_RAW) in
> nanoseconds.

and also

> This API has the potential of being misused to access device signals to try
> to identify the device or user, also known as fingerprinting. Regardless of
> whether a user gives your app permission to track, fingerprinting is not
> allowed. When you use this API in your app or third-party SDK (an SDK not
> provided by Apple), declare your usage and the reason for using the API in
> your app or third-party SDK’s PrivacyInfo.xcprivacy file.

see https://developer.apple.com/documentation/kernel/1462446-mach_absolute_time
  • Loading branch information
TimWolla authored Dec 10, 2024
1 parent 2541b9f commit 85f69a7
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 7 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -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
========================================
Expand Down
5 changes: 5 additions & 0 deletions Zend/Zend.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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 <time.h>])
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.
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_hrtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <mach/mach_time.h>
# include <string.h>
Expand Down Expand Up @@ -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);

Expand Down
16 changes: 11 additions & 5 deletions Zend/zend_hrtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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()

Expand Down Expand Up @@ -82,7 +86,9 @@ static zend_always_inline zend_hrtime_t zend_hrtime(void)
LARGE_INTEGER lt = {0};
QueryPerformanceCounter(&lt);
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 };
Expand Down

0 comments on commit 85f69a7

Please sign in to comment.