Skip to content

Commit bd5fb4c

Browse files
committed
Introduce new time retrieval Zend-API
1 parent f99ca63 commit bd5fb4c

File tree

6 files changed

+156
-1
lines changed

6 files changed

+156
-1
lines changed

UPGRADING.INTERNALS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ PHP 8.6 INTERNALS UPGRADE NOTES
7474
longer is a pointer, but a directly embedded HashTable struct.
7575
. Added a C23_ENUM() helper macro to define forward-compatible fixed-size
7676
enums.
77+
. Introduced a new time-retrieval API zend_time_*.
7778

7879
========================
7980
2. Build system changes

Zend/zend_time.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright (c) The PHP Group |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to version 3.01 of the PHP license, |
6+
| that is bundled with this package in the file LICENSE, and is |
7+
| available through the world-wide-web at the following url: |
8+
| https://www.php.net/license/3_01.txt |
9+
| If you did not receive a copy of the PHP license and are unable to |
10+
| obtain it through the world-wide-web, please send a note to |
11+
| license@php.net so we can mail you a copy immediately. |
12+
+----------------------------------------------------------------------+
13+
| Author: Marc Bennewitz <marc@mabe.berlin> |
14+
+----------------------------------------------------------------------+
15+
*/
16+
17+
#include "zend_time.h"
18+
19+
/* Current real/wall-time in seconds */
20+
ZEND_API time_t zend_time_real_sec(void) {
21+
return time(NULL);
22+
}
23+
24+
ZEND_API void zend_time_real_spec(struct timespec *ts) {
25+
#if defined(HAVE_CLOCK_GETTIME)
26+
27+
(void) clock_gettime(CLOCK_REALTIME, ts);
28+
29+
#elif defined(HAVE_TIMESPEC_GET)
30+
31+
(void) timespec_get(ts, TIME_UTC);
32+
33+
#elif defined(HAVE_GETTIMEOFDAY)
34+
35+
struct timeval tv;
36+
(void) gettimeofday(&tv, NULL);
37+
zend_time_val2spec(tv, ts);
38+
39+
#else
40+
41+
ts->tv_sec = zend_time_real_get();
42+
ts->tv_nsec = 0;
43+
44+
#endif
45+
}
46+
47+
ZEND_API uint64_t zend_time_mono_fallback_nsec(void) {
48+
#if ZEND_HRTIME_AVAILABLE
49+
return (uint64_t)zend_hrtime();
50+
#else
51+
struct timespec ts;
52+
zend_time_real_spec(&ts);
53+
return ((uint64_t) ts.tv_sec * ZEND_NANO_IN_SEC) + ts.tv_nsec;
54+
#endif
55+
}

Zend/zend_time.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright (c) The PHP Group |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to version 3.01 of the PHP license, |
6+
| that is bundled with this package in the file LICENSE, and is |
7+
| available through the world-wide-web at the following url: |
8+
| https://www.php.net/license/3_01.txt |
9+
| If you did not receive a copy of the PHP license and are unable to |
10+
| obtain it through the world-wide-web, please send a note to |
11+
| license@php.net so we can mail you a copy immediately. |
12+
+----------------------------------------------------------------------+
13+
| Author: Marc Bennewitz <marc@mabe.berlin> |
14+
+----------------------------------------------------------------------+
15+
*/
16+
17+
#ifndef ZEND_TIME_H
18+
#define ZEND_TIME_H
19+
20+
#include "zend_portability.h"
21+
22+
#ifdef PHP_WIN32
23+
# include "win32/time.h"
24+
#endif
25+
#ifdef HAVE_SYS_TIME_H
26+
# include <sys/time.h>
27+
#endif
28+
#include <time.h>
29+
30+
#include "zend_hrtime.h"
31+
32+
#ifndef PHP_WIN32
33+
# define tv_sec_t time_t
34+
# define tv_usec_t suseconds_t
35+
#else
36+
# define tv_sec_t long
37+
# define tv_usec_t long
38+
#endif
39+
40+
#define ZEND_MILLI_IN_SEC 1000U
41+
#define ZEND_MICRO_IN_SEC 1000000U
42+
43+
BEGIN_EXTERN_C()
44+
45+
/* Assign seconds to timeval */
46+
static zend_always_inline void zend_time_sec2val(time_t s, struct timeval *tv) {
47+
tv->tv_sec = (tv_sec_t) s;
48+
tv->tv_usec = 0;
49+
}
50+
51+
/* Assign microseconds to timeval */
52+
static zend_always_inline void zend_time_usec2val(int64_t usec, struct timeval *tv) {
53+
tv->tv_sec = (tv_sec_t) (usec / ZEND_MICRO_IN_SEC);
54+
tv->tv_usec = (tv_usec_t) (usec % ZEND_MICRO_IN_SEC);
55+
56+
if (UNEXPECTED(tv->tv_usec < 0)) {
57+
tv->tv_usec += ZEND_MICRO_IN_SEC;
58+
tv->tv_sec -= 1;
59+
}
60+
}
61+
62+
/* Assign double (seconds) to timeval */
63+
static zend_always_inline void zend_time_dbl2val(double s, struct timeval *tv) {
64+
tv->tv_sec = (tv_sec_t) s;
65+
tv->tv_usec = (tv_usec_t) ((s - tv->tv_sec) * ZEND_MICRO_IN_SEC);
66+
67+
if (UNEXPECTED(tv->tv_usec < 0)) {
68+
tv->tv_usec += ZEND_MICRO_IN_SEC;
69+
tv->tv_sec -= 1;
70+
} else if (UNEXPECTED(tv->tv_usec >= ZEND_MICRO_IN_SEC)) {
71+
// rare, but protects against rounding up to exactly 1 second
72+
tv->tv_usec -= ZEND_MICRO_IN_SEC;
73+
tv->tv_sec += 1;
74+
}
75+
}
76+
77+
/* Assign timeval to timespec */
78+
static zend_always_inline void zend_time_val2spec(struct timeval tv, struct timespec *ts) {
79+
ts->tv_sec = (time_t) tv.tv_sec;
80+
ts->tv_nsec = (long) (tv.tv_usec * 1000);
81+
}
82+
83+
/* Current real/wall-time in seconds */
84+
ZEND_API time_t zend_time_real_sec(void);
85+
86+
/* Current real/wall-time in up-to nano seconds */
87+
ZEND_API void zend_time_real_spec(struct timespec *ts);
88+
89+
/* Monotonic time in nanoseconds with a fallback to real/wall-time
90+
if no monotonic timer is available */
91+
ZEND_API uint64_t zend_time_mono_fallback_nsec(void);
92+
93+
END_EXTERN_C()
94+
95+
#endif // ZEND_TIME_H

configure.ac

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ AC_CHECK_FUNCS(m4_normalize([
540540
asctime_r
541541
asprintf
542542
chroot
543+
clock_gettime
543544
ctime_r
544545
explicit_memset
545546
fdatasync
@@ -591,6 +592,7 @@ AC_CHECK_FUNCS(m4_normalize([
591592
strptime
592593
strtok_r
593594
symlink
595+
timespec_get
594596
tzset
595597
unsetenv
596598
usleep
@@ -1760,6 +1762,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([
17601762
zend_generators.c
17611763
zend_hash.c
17621764
zend_highlight.c
1765+
zend_time.c
17631766
zend_hrtime.c
17641767
zend_inheritance.c
17651768
zend_ini_parser.c

win32/build/config.w32

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
240240
zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \
241241
zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \
242242
zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_observer.c zend_system_id.c \
243-
zend_enum.c zend_fibers.c zend_atomic.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c \
243+
zend_enum.c zend_fibers.c zend_atomic.c zend_time.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c \
244244
zend_lazy_objects.c zend_autoload.c");
245245
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");
246246

win32/build/config.w32.h.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#undef HAVE_SETITIMER
4949
#undef HAVE_IODBC
5050
#define HAVE_LIBDL 1
51+
#define HAVE_TIMESPEC_GET 1
5152
#define HAVE_GETTIMEOFDAY 1
5253
#define HAVE_PUTENV 1
5354
#define HAVE_TZSET 1

0 commit comments

Comments
 (0)