xref: /php-src/ext/standard/hrtime.c (revision d0731934)
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: Niklas Keller <kelunik@php.net>                              |
14    | Author: Anatol Belski <ab@php.net>                                   |
15    +----------------------------------------------------------------------+
16  */
17 
18 #include "php.h"
19 #include "zend_hrtime.h"
20 
21 #ifdef ZEND_ENABLE_ZVAL_LONG64
22 #define PHP_RETURN_HRTIME(t) RETURN_LONG((zend_long)t)
23 #else
24 #ifdef _WIN32
25 # define HRTIME_U64A(i, s, len) _ui64toa_s(i, s, len, 10)
26 #else
27 # define HRTIME_U64A(i, s, len) \
28 	do { \
29 		int st = snprintf(s, len, "%llu", i); \
30 		s[st] = '\0'; \
31 	} while (0)
32 #endif
33 #define PHP_RETURN_HRTIME(t) do { \
34 	char _a[ZEND_LTOA_BUF_LEN]; \
35 	double _d; \
36 	HRTIME_U64A(t, _a, ZEND_LTOA_BUF_LEN); \
37 	_d = zend_strtod(_a, NULL); \
38 	RETURN_DOUBLE(_d); \
39 	} while (0)
40 #endif
41 
42 /* {{{ Returns an array of integers in form [seconds, nanoseconds] counted
43 	from an arbitrary point in time. If an optional boolean argument is
44 	passed, returns an integer on 64-bit platforms or float on 32-bit
45 	containing the current high-resolution time in nanoseconds. The
46 	delivered timestamp is monotonic and cannot be adjusted. */
PHP_FUNCTION(hrtime)47 PHP_FUNCTION(hrtime)
48 {
49 #if ZEND_HRTIME_AVAILABLE
50 	bool get_as_num = 0;
51 	zend_hrtime_t t = zend_hrtime();
52 
53 	ZEND_PARSE_PARAMETERS_START(0, 1)
54 		Z_PARAM_OPTIONAL
55 		Z_PARAM_BOOL(get_as_num)
56 	ZEND_PARSE_PARAMETERS_END();
57 
58 	if (UNEXPECTED(get_as_num)) {
59 		PHP_RETURN_HRTIME(t);
60 	} else {
61 		array_init_size(return_value, 2);
62 		zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
63 		add_next_index_long(return_value, (zend_long)(t / (zend_hrtime_t)ZEND_NANO_IN_SEC));
64 		add_next_index_long(return_value, (zend_long)(t % (zend_hrtime_t)ZEND_NANO_IN_SEC));
65 	}
66 #else
67 	RETURN_FALSE;
68 #endif
69 }
70 /* }}} */
71