Skip to content

Commit 24b0383

Browse files
committed
Refactor basic time
1 parent cb49281 commit 24b0383

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+510
-736
lines changed

Zend/Optimizer/zend_func_infos.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -559,10 +559,8 @@ static const func_info_t func_infos[] = {
559559
F1("dechex", MAY_BE_STRING),
560560
F1("base_convert", MAY_BE_STRING),
561561
F1("number_format", MAY_BE_STRING),
562-
#if defined(HAVE_GETTIMEOFDAY)
563562
F1("microtime", MAY_BE_STRING|MAY_BE_DOUBLE),
564563
F1("gettimeofday", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_DOUBLE),
565-
#endif
566564
#if defined(HAVE_GETRUSAGE)
567565
F1("getrusage", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_FALSE),
568566
#endif
@@ -597,9 +595,7 @@ static const func_info_t func_infos[] = {
597595
F1("stream_resolve_include_path", MAY_BE_STRING|MAY_BE_FALSE),
598596
F1("stream_get_wrappers", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
599597
F1("stream_get_transports", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
600-
#if defined(HAVE_GETTIMEOFDAY)
601598
F1("uniqid", MAY_BE_STRING),
602-
#endif
603599
F1("parse_url", MAY_BE_LONG|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_NULL|MAY_BE_FALSE),
604600
F1("urlencode", MAY_BE_STRING),
605601
F1("urldecode", MAY_BE_STRING),

Zend/zend_time.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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+
ZEND_API time_t zend_realtime_get(time_t *sec, long *nsec) {
20+
if (!nsec) {
21+
return time(sec);
22+
}
23+
24+
#if defined(HAVE_CLOCK_GETTIME)
25+
26+
struct timespec ts;
27+
clock_gettime(CLOCK_REALTIME, &ts);
28+
if (sec) *sec = ts.tv_sec;
29+
*nsec = ts.tv_nsec;
30+
return ts.tv_sec;
31+
32+
#elif defined(HAVE_TIMESPEC_GET)
33+
34+
struct timespec ts;
35+
timespec_get(&ts, TIME_UTC);
36+
if (sec) *sec = ts.tv_sec;
37+
*nsec = ts.tv_nsec;
38+
return ts.tv_sec;
39+
40+
#elif defined(HAVE_GETTIMEOFDAY)
41+
42+
struct timeval tv;
43+
gettimeofday(&tv, NULL);
44+
45+
if (sec) *sec = tv.tv_sec;
46+
*nsec = tv.tv_usec * 1000;
47+
return tv.tv_sec;
48+
49+
#else
50+
51+
*nsec = 0;
52+
return time(sec);
53+
54+
#endif
55+
}
56+
57+
ZEND_API void zend_realtime_spec(struct timespec *ts) {
58+
#if defined(HAVE_CLOCK_GETTIME)
59+
60+
clock_gettime(CLOCK_REALTIME, ts);
61+
62+
#elif defined(HAVE_TIMESPEC_GET)
63+
64+
timespec_get(ts, TIME_UTC);
65+
66+
#elif defined(HAVE_GETTIMEOFDAY)
67+
68+
struct timeval tv;
69+
gettimeofday(&tv, NULL);
70+
zend_time_val2spec(tv, ts);
71+
72+
#else
73+
74+
ts->tv_sec = time(NULL);
75+
ts->tv_nsec = 0;
76+
77+
#endif
78+
}

Zend/zend_time.h

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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+
/* Helper macro to assign seconds to timeval */
44+
#define zend_time_sec2val(s, tv) \
45+
(tv).tv_sec = (tv_sec_t) (s); \
46+
(tv).tv_usec = 0;
47+
48+
/* Helper macro to assign microseconds to timeval */
49+
#define zend_time_usec2val(usec, tv) \
50+
(tv).tv_sec = (tv_sec_t) ((usec) / ZEND_MICRO_IN_SEC); \
51+
(tv).tv_usec = (tv_usec_t) ((usec) % ZEND_MICRO_IN_SEC);
52+
53+
/* Helper macro to assign double (seconds) to timeval */
54+
#define zend_time_dbl2val(d, tv) \
55+
(tv).tv_sec = (tv_sec_t) (d); \
56+
(tv).tv_usec = (tv_usec_t) (((d) - (tv).tv_sec) * ZEND_MICRO_IN_SEC);
57+
58+
/* Helper macro to copy timeval to timespec */
59+
#define zend_time_val2spec(tv, ts) \
60+
(ts).tv_sec = (time_t) (tv).tv_sec; \
61+
(ts).tv_nsec = (long) ((tv).tv_usec * 1000);
62+
63+
BEGIN_EXTERN_C()
64+
65+
/* Like time() but with up to nanosecond */
66+
ZEND_API time_t zend_realtime_get(time_t *sec, long *nsec);
67+
68+
/* wrapper around clock_gettime/timestamp_get/gettimeofday/time */
69+
ZEND_API void zend_realtime_spec(struct timespec *ts);
70+
71+
/* Monotonic time in nanoseconds with a fallback to real/wall-time
72+
if no monotonic timer is available */
73+
#if ZEND_HRTIME_AVAILABLE
74+
# define zend_monotime_fallback() (uint64_t)zend_hrtime()
75+
#else
76+
ZEND_API zend_always_inline uint64_t zend_monotime_fallback(void) {
77+
struct timespec ts;
78+
zend_realtime_spec(&ts);
79+
return ((uint64_t) ts.tv_sec * ZEND_NANO_IN_SEC) + ts.tv_nsec;
80+
}
81+
#endif
82+
83+
END_EXTERN_C()
84+
85+
#endif // ZEND_TIME_H

configure.ac

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ AC_CHECK_FUNCS(m4_normalize([
545545
asctime_r
546546
asprintf
547547
chroot
548+
clock_gettime
548549
ctime_r
549550
explicit_memset
550551
fdatasync
@@ -596,6 +597,7 @@ AC_CHECK_FUNCS(m4_normalize([
596597
strptime
597598
strtok_r
598599
symlink
600+
timespec_get
599601
tzset
600602
unsetenv
601603
usleep
@@ -1764,6 +1766,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([
17641766
zend_generators.c
17651767
zend_hash.c
17661768
zend_highlight.c
1769+
zend_time.c
17671770
zend_hrtime.c
17681771
zend_inheritance.c
17691772
zend_ini_parser.c

docs-old/streams.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent);
9090
/* Convert a socket into a stream. */
9191
9292
PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short port,
93-
int socktype, int timeout, int persistent);
93+
int socktype, struct timeval *timeout, const char *persistent_id);
9494
/* Open a connection to a host and return a stream. */
9595
9696
PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,

ext/date/php_date.c

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,9 @@
2323
#include "zend_attributes.h"
2424
#include "zend_interfaces.h"
2525
#include "zend_exceptions.h"
26+
#include "zend_time.h"
2627
#include "lib/timelib.h"
2728
#include "lib/timelib_private.h"
28-
#ifndef PHP_WIN32
29-
#include <time.h>
30-
#else
31-
#include "win32/time.h"
32-
#endif
3329

3430
#ifdef PHP_WIN32
3531
static __inline __int64 php_date_llabs( __int64 i ) { return i >= 0? i: -i; }
@@ -55,18 +51,7 @@ static inline long long php_date_llabs( long long i ) { return i >= 0 ? i : -i;
5551

5652
PHPAPI time_t php_time(void)
5753
{
58-
#ifdef HAVE_GETTIMEOFDAY
59-
struct timeval tm;
60-
61-
if (UNEXPECTED(gettimeofday(&tm, NULL) != SUCCESS)) {
62-
/* fallback, can't reasonably happen */
63-
return time(NULL);
64-
}
65-
66-
return tm.tv_sec;
67-
#else
6854
return time(NULL);
69-
#endif
7055
}
7156

7257
/*
@@ -2353,16 +2338,9 @@ static void php_date_set_time_fraction(timelib_time *time, int microsecond)
23532338

23542339
static void php_date_get_current_time_with_fraction(time_t *sec, suseconds_t *usec)
23552340
{
2356-
#ifdef HAVE_GETTIMEOFDAY
2357-
struct timeval tp = {0}; /* For setting microsecond */
2358-
2359-
gettimeofday(&tp, NULL);
2360-
*sec = tp.tv_sec;
2361-
*usec = tp.tv_usec;
2362-
#else
2363-
*sec = time(NULL);
2364-
*usec = 0;
2365-
#endif
2341+
long nsec;
2342+
zend_realtime_get(sec, &nsec);
2343+
*usec = nsec / 1000;
23662344
}
23672345

23682346
PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags) /* {{{ */

ext/ftp/ftp.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#endif
2121

2222
#include "php.h"
23+
#include "zend_time.h"
2324

2425
#include <stdio.h>
2526
#include <ctype.h>
@@ -29,7 +30,6 @@
2930
#endif
3031
#include <fcntl.h>
3132
#include <string.h>
32-
#include <time.h>
3333
#ifdef PHP_WIN32
3434
#include <winsock2.h>
3535
#else
@@ -43,10 +43,6 @@
4343
#endif
4444
#include <errno.h>
4545

46-
#ifdef HAVE_SYS_TIME_H
47-
#include <sys/time.h>
48-
#endif
49-
5046
#ifdef HAVE_SYS_SELECT_H
5147
#include <sys/select.h>
5248
#endif
@@ -1609,8 +1605,7 @@ static databuf_t* ftp_getdata(ftpbuf_t *ftp)
16091605
/* connect */
16101606
/* Win 95/98 seems not to like size > sizeof(sockaddr_in) */
16111607
size = php_sockaddr_size(&ftp->pasvaddr);
1612-
tv.tv_sec = ftp->timeout_sec;
1613-
tv.tv_usec = 0;
1608+
zend_time_sec2val(ftp->timeout_sec, tv);
16141609
if (php_connect_nonb(fd, (struct sockaddr*) &ftp->pasvaddr, size, &tv) == -1) {
16151610
php_error_docref(NULL, E_WARNING, "php_connect_nonb() failed: %s (%d)", strerror(errno), errno);
16161611
goto bail;

ext/mysqlnd/mysqlnd_debug.c

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
#include "php.h"
19+
#include "zend_time.h"
1920
#include "mysqlnd.h"
2021
#include "mysqlnd_priv.h"
2122
#include "mysqlnd_debug.h"
@@ -76,21 +77,19 @@ MYSQLND_METHOD(mysqlnd_debug, log)(MYSQLND_DEBUG * self,
7677
}
7778
if (flags & MYSQLND_DEBUG_DUMP_TIME) {
7879
/* The following from FF's DBUG library, which is in the public domain */
79-
struct timeval tv;
80+
struct timespec ts;
8081
struct tm *tm_p;
81-
if (gettimeofday(&tv, NULL) != -1) {
82-
const time_t sec = tv.tv_sec;
83-
if ((tm_p = localtime((const time_t *)&sec))) {
84-
snprintf(time_buffer, sizeof(time_buffer) - 1,
85-
/* "%04d-%02d-%02d " */
86-
"%02d:%02d:%02d.%06d ",
87-
/*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/
88-
tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec,
89-
(int) (tv.tv_usec));
90-
time_buffer[sizeof(time_buffer) - 1 ] = '\0';
91-
} else {
92-
time_buffer[0] = '\0';
93-
}
82+
zend_realtime_spec(&ts);
83+
if ((tm_p = localtime((const time_t *)&ts.tv_sec))) {
84+
snprintf(time_buffer, sizeof(time_buffer) - 1,
85+
/* "%04d-%02d-%02d " */
86+
"%02d:%02d:%02d.%06d ",
87+
/*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/
88+
tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec,
89+
(int) (ts.tv_nsec / 1000));
90+
time_buffer[sizeof(time_buffer) - 1 ] = '\0';
91+
} else {
92+
time_buffer[0] = '\0';
9493
}
9594
}
9695
if (flags & MYSQLND_DEBUG_DUMP_FILE) {
@@ -163,21 +162,19 @@ MYSQLND_METHOD(mysqlnd_debug, log_va)(MYSQLND_DEBUG *self,
163162
}
164163
if (flags & MYSQLND_DEBUG_DUMP_TIME) {
165164
/* The following from FF's DBUG library, which is in the public domain */
166-
struct timeval tv;
165+
struct timespec ts;
167166
struct tm *tm_p;
168-
if (gettimeofday(&tv, NULL) != -1) {
169-
const time_t sec = tv.tv_sec;
170-
if ((tm_p = localtime((const time_t *)&sec))) {
171-
snprintf(time_buffer, sizeof(time_buffer) - 1,
172-
/* "%04d-%02d-%02d " */
173-
"%02d:%02d:%02d.%06d ",
174-
/*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/
175-
tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec,
176-
(int) (tv.tv_usec));
177-
time_buffer[sizeof(time_buffer) - 1 ] = '\0';
178-
} else {
179-
time_buffer[0] = '\0';
180-
}
167+
zend_realtime_spec(&ts);
168+
if ((tm_p = localtime((const time_t *)&ts.tv_sec))) {
169+
snprintf(time_buffer, sizeof(time_buffer) - 1,
170+
/* "%04d-%02d-%02d " */
171+
"%02d:%02d:%02d.%06d ",
172+
/*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/
173+
tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec,
174+
(int)(ts.tv_nsec / 1000));
175+
time_buffer[sizeof(time_buffer) - 1 ] = '\0';
176+
} else {
177+
time_buffer[0] = '\0';
181178
}
182179
}
183180
if (flags & MYSQLND_DEBUG_DUMP_FILE) {
@@ -329,8 +326,8 @@ MYSQLND_METHOD(mysqlnd_debug, func_leave)(MYSQLND_DEBUG * self, unsigned int lin
329326
uint64_t own_time = call_time - mine_non_own_time;
330327
uint32_t func_name_len = strlen(*func_name);
331328

332-
self->m->log_va(self, line, file, zend_stack_count(&self->call_stack) - 1, NULL, "<%s (total=%u own=%u in_calls=%u)",
333-
*func_name, (unsigned int) call_time, (unsigned int) own_time, (unsigned int) mine_non_own_time
329+
self->m->log_va(self, line, file, zend_stack_count(&self->call_stack) - 1, NULL, "<%s (total=%"PRIu64" own=%"PRIu64" in_calls=%"PRIu64")",
330+
*func_name, call_time, own_time, mine_non_own_time
334331
);
335332

336333
if ((f_profile = zend_hash_str_find_ptr(&self->function_profiles, *func_name, func_name_len)) != NULL) {

0 commit comments

Comments
 (0)