6. New Functions
========================================
+Core:
+ . Added monotonic timer function hrtime([bool get_as_num]). It returns an
+ array of the form [seconds, nanoseconds] with the timestamp starting at
+ an unspecified point in the past. If the optional argument is passed as
+ true, the return value is an integer on 64-bit systems or float on
+ 32-bit systems, representing the nanoseconds. The timestamp is not
+ adjustable and is not related to wall clock or time of day. The timers
+ are available under Linux, FreeBSD, Windows, Mac, SunOS, AIX and their
+ derivatives. If no required timers are provided by a corresponding
+ platform, the function returns false.
+
Date:
. Added the DateTime::createFromImmutable() method, which mirrors
DateTimeImmutable::createFromMutable().
i. RAND_RANGE()
j. cast_object() with _IS_NUMBER
k. zend_fcall_info_cache.initialized
+ l. php_hrtime_current()
2. Build system changes
a. Unix build system changes
k. zend_fcall_info_cache.initialized is removed. zend_fcall_info_cache is
initialized if zend_fcall_info_cache.function_handler is set.
+ l. php_hrtime_current() delivers the number of nanoseconds since an uncertain
+ point in the past.
+
========================
2. Build system changes
========================
ZEND_ARG_INFO(0, response_code)
ZEND_END_ARG_INFO()
/* }}} */
+/* {{{ hrtime.c */
+ZEND_BEGIN_ARG_INFO(arginfo_hrtime, 0)
+ ZEND_ARG_INFO(0, get_as_number)
+ZEND_END_ARG_INFO()
+/* }}} */
/* {{{ html.c */
ZEND_BEGIN_ARG_INFO_EX(arginfo_htmlspecialchars, 0, 0, 1)
ZEND_ARG_INFO(0, string)
PHP_FE(getrusage, arginfo_getrusage)
#endif
+ PHP_FE(hrtime, arginfo_hrtime)
+
#ifdef HAVE_GETTIMEOFDAY
PHP_FE(uniqid, arginfo_uniqid)
#endif
BASIC_MINIT_SUBMODULE(random)
+ BASIC_MINIT_SUBMODULE(hrtime)
+
return SUCCESS;
}
/* }}} */
char *filename = tmpnam(NULL);
char buffer[64];
int result = 0;
-
+
FILE *fp = fopen(filename, "wb");
if (NULL == fp)
return 0;
fputs("line 1\n", fp);
fputs("line 2\n", fp);
fclose(fp);
-
+
fp = fopen(filename, "rb+");
if (NULL == fp)
return 0;
AC_DEFINE(HAVE_CRYPT, 1, [ ])
])
fi
-
+
AC_CACHE_CHECK(for standard DES crypt, ac_cv_crypt_des,[
AC_TRY_RUN([
#if HAVE_UNISTD_H
char salt[15], answer[40];
char *encrypted;
- salt[0]='$'; salt[1]='1'; salt[2]='$';
+ salt[0]='$'; salt[1]='1'; salt[2]='$';
salt[3]='r'; salt[4]='a'; salt[5]='s';
salt[6]='m'; salt[7]='u'; salt[8]='s';
salt[9]='l'; salt[10]='e'; salt[11]='$';
AC_DEFINE_UNQUOTED(PHP_USE_PHP_CRYPT_R, 0, [Whether PHP has to use its own crypt_r for blowfish, des and ext des])
fi
-dnl
+dnl
dnl Check for __attribute__ ((__aligned__)) support in the compiler
dnl
AC_CACHE_CHECK(whether the compiler supports aligned attribute, ac_cv_attribute_aligned,[
dnl log2 could be used to improve the log function, however it requires C99. The check for log2 should be turned on,
dnl as soon as we support C99.
AC_CHECK_FUNCS(getcwd getwd asinh acosh atanh log1p hypot glob strfmon nice fpclass mempcpy strpncpy)
-AC_FUNC_FNMATCH
+AC_FUNC_FNMATCH
dnl
dnl Check if there is a support means of creating a new process
http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
filters.c proc_open.c streamsfuncs.c http.c password.c \
- random.c net.c,,,
+ random.c net.c hrtime.c,,,
-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
PHP_ADD_MAKEFILE_FRAGMENT
url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \
php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \
user_filters.c uuencode.c filters.c proc_open.c password.c \
- streamsfuncs.c http.c flock_compat.c random.c", false /* never shared */,
+ streamsfuncs.c http.c flock_compat.c random.c hrtime.c", false /* never shared */,
'/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1');
PHP_INSTALL_HEADERS("", "ext/standard");
if (PHP_MBREGEX != "no") {
- CHECK_HEADER_ADD_INCLUDE("oniguruma.h", "CFLAGS_STANDARD", PHP_MBREGEX + ";ext\\mbstring\\oniguruma")
+ CHECK_HEADER_ADD_INCLUDE("oniguruma.h", "CFLAGS_STANDARD", PHP_MBREGEX + ";ext\\mbstring\\oniguruma")
}
ADD_MAKEFILE_FRAGMENT();
PHP_INSTALL_HEADERS("", "ext/standard");
-
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2017 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Niklas Keller <kelunik@php.net> |
+ | Author: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#include "php.h"
+#include "hrtime.h"
+
+/* {{{ */
+/* This file reuses code parts from the cross-platform timer library
+ Public Domain - 2011 Mattias Jansson / Rampant Pixels */
+
+#if PHP_HRTIME_PLATFORM_POSIX
+
+# include <unistd.h>
+# include <time.h>
+# include <string.h>
+
+#elif PHP_HRTIME_PLATFORM_WINDOWS
+
+# define WIN32_LEAN_AND_MEAN
+
+static double _timer_scale = .0;
+
+#elif PHP_HRTIME_PLATFORM_APPLE
+
+# include <mach/mach_time.h>
+# include <string.h>
+static mach_timebase_info_data_t _timerlib_info;
+
+#elif PHP_HRTIME_PLATFORM_HPUX
+
+# include <sys/time.h>
+
+#elif PHP_HRTIME_PLATFORM_AIX
+
+# include <sys/time.h>
+# include <sys/systemcfg.h>
+
+#endif
+
+#define NANO_IN_SEC 1000000000
+/* }}} */
+
+static int _timer_init()
+{/*{{{*/
+#if PHP_HRTIME_PLATFORM_WINDOWS
+
+ LARGE_INTEGER tf = {0};
+ if (!QueryPerformanceFrequency(&tf) || 0 == tf.QuadPart) {
+ return -1;
+ }
+ _timer_scale = (double)NANO_IN_SEC / (php_hrtime_t)tf.QuadPart;
+
+#elif PHP_HRTIME_PLATFORM_APPLE
+
+ if (mach_timebase_info(&_timerlib_info)) {
+ return -1;
+ }
+
+#elif PHP_HRTIME_PLATFORM_POSIX
+
+#if !_POSIX_MONOTONIC_CLOCK
+#ifdef _SC_MONOTONIC_CLOCK
+ if (0 >= sysconf(_SC_MONOTONIC_CLOCK)) {
+ return -1;
+ }
+#endif
+#endif
+
+#elif PHP_HRTIME_PLATFORM_HPUX
+
+ /* pass */
+
+#elif PHP_HRTIME_PLATFORM_AIX
+
+ /* pass */
+
+#else
+ /* Timer unavailable. */
+ return -1;
+#endif
+
+ return 0;
+}/*}}}*/
+
+/* {{{ */
+PHP_MINIT_FUNCTION(hrtime)
+{
+ if (0 > _timer_init()) {
+ php_error_docref(NULL, E_WARNING, "Failed to initialize high-resolution timer");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+static zend_always_inline php_hrtime_t _timer_current(void)
+{/*{{{*/
+#if PHP_HRTIME_PLATFORM_WINDOWS
+ LARGE_INTEGER lt = {0};
+ QueryPerformanceCounter(<);
+ return (php_hrtime_t)((php_hrtime_t)lt.QuadPart * _timer_scale);
+#elif PHP_HRTIME_PLATFORM_APPLE
+ return (php_hrtime_t)mach_absolute_time() * _timerlib_info.numer / _timerlib_info.denom;
+#elif PHP_HRTIME_PLATFORM_POSIX
+ struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
+ if (0 == clock_gettime(CLOCK_MONOTONIC, &ts)) {
+ return ((php_hrtime_t) ts.tv_sec * (php_hrtime_t)NANO_IN_SEC) + ts.tv_nsec;
+ }
+ return 0;
+#elif PHP_HRTIME_PLATFORM_HPUX
+ return (php_hrtime_t) gethrtime();
+#elif PHP_HRTIME_PLATFORM_AIX
+ timebasestruct_t t;
+ read_wall_time(&t, TIMEBASE_SZ);
+ time_base_to_time(&t, TIMEBASE_SZ);
+ return (php_hrtime_t) t.tb_high * (php_hrtime_t)NANO_IN_SEC + t.tb_low;
+#else
+ return 0;
+#endif
+}/*}}}*/
+
+#if ZEND_ENABLE_ZVAL_LONG64
+#define PHP_RETURN_HRTIME(t) RETURN_LONG((zend_long)t)
+#else
+#ifdef _WIN32
+# define HRTIME_U64A(i, s, len) _ui64toa_s(i, s, len, 10)
+#else
+# define HRTIME_U64A(i, s, len) \
+ do { \
+ int st = snprintf(s, len, "%llu", i); \
+ s[st] = '\0'; \
+ } while (0)
+#endif
+#define PHP_RETURN_HRTIME(t) do { \
+ char _a[ZEND_LTOA_BUF_LEN]; \
+ double _d; \
+ HRTIME_U64A(t, _a, ZEND_LTOA_BUF_LEN); \
+ _d = zend_strtod(_a, NULL); \
+ RETURN_DOUBLE(_d); \
+ } while (0)
+#endif
+
+/* {{{ proto mixed hrtime([bool get_as_number = false])
+ Returns an array of integers in form [seconds, nanoseconds] counted
+ from an arbitrary point in time. If an optional boolean argument is
+ passed, returns an integer on 64-bit platforms or float on 32-bit
+ containing the current high-resolution time in nanoseconds. The
+ delivered timestamp is monotonic and can not be adjusted. */
+PHP_FUNCTION(hrtime)
+{
+#if HRTIME_AVAILABLE
+ zend_bool get_as_num = 0;
+ php_hrtime_t t = _timer_current();
+
+ ZEND_PARSE_PARAMETERS_START(0, 1)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_BOOL(get_as_num)
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (UNEXPECTED(get_as_num)) {
+ PHP_RETURN_HRTIME(t);
+ } else {
+ array_init_size(return_value, 2);
+ zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
+ add_next_index_long(return_value, (zend_long)(t / (php_hrtime_t)NANO_IN_SEC));
+ add_next_index_long(return_value, (zend_long)(t % (php_hrtime_t)NANO_IN_SEC));
+ }
+#else
+ RETURN_FALSE
+#endif
+}
+/* }}} */
+
+PHPAPI php_hrtime_t php_hrtime_current(void)
+{/*{{{*/
+ return _timer_current();
+}/*}}}*/
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */
+
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2017 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Niklas Keller <kelunik@php.net> |
+ | Author: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef HRTIME_H
+#define HRTIME_H
+
+#define PHP_HRTIME_PLATFORM_POSIX 0
+#define PHP_HRTIME_PLATFORM_WINDOWS 0
+#define PHP_HRTIME_PLATFORM_APPLE 0
+#define PHP_HRTIME_PLATFORM_HPUX 0
+#define PHP_HRTIME_PLATFORM_AIX 0
+
+#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) && defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC)
+# undef PHP_HRTIME_PLATFORM_POSIX
+# define PHP_HRTIME_PLATFORM_POSIX 1
+#elif defined(_WIN32) || defined(_WIN64)
+# undef PHP_HRTIME_PLATFORM_WINDOWS
+# define PHP_HRTIME_PLATFORM_WINDOWS 1
+#elif defined(__APPLE__)
+# undef PHP_HRTIME_PLATFORM_APPLE
+# define PHP_HRTIME_PLATFORM_APPLE 1
+#elif (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__)))
+# undef PHP_HRTIME_PLATFORM_HPUX
+# define PHP_HRTIME_PLATFORM_HPUX 1
+#elif defined(_AIX)
+# undef PHP_HRTIME_PLATFORM_AIX
+# define PHP_HRTIME_PLATFORM_AIX 1
+#endif
+
+#define HRTIME_AVAILABLE (PHP_HRTIME_PLATFORM_POSIX || PHP_HRTIME_PLATFORM_WINDOWS || PHP_HRTIME_PLATFORM_APPLE || PHP_HRTIME_PLATFORM_HPUX || PHP_HRTIME_PLATFORM_AIX)
+
+typedef uint64_t php_hrtime_t;
+
+PHPAPI php_hrtime_t php_hrtime_current(void);
+
+PHP_MINIT_FUNCTION(hrtime);
+
+PHP_FUNCTION(hrtime);
+
+#endif /* HRTIME_H */
#include "php_mail.h"
#include "md5.h"
#include "sha1.h"
+#include "hrtime.h"
#include "html.h"
#include "exec.h"
#include "file.h"
--- /dev/null
+--TEST--
+Test hrtime() aligns with microtime()
+--FILE--
+<?php
+
+$m0 = microtime(true);
+$h0 = hrtime(true);
+for ($i = 0; $i < 1024*1024; $i++);
+$h1 = hrtime(true);
+$m1 = microtime(true);
+
+$d0 = ($m1 - $m0)*1000000000.0;
+$d1 = $h1 - $h0;
+
+/* Relative uncertainty. */
+$d = abs($d0 - $d1)/$d1;
+
+if ($d > 0.05) {
+ print "FAIL, $d";
+} else {
+ print "OK, $d";
+}
+
+?>
+--EXPECTF--
+OK, %f
--- /dev/null
+--TEST--
+Test hrtime() return array
+--FILE--
+<?php
+
+var_dump(hrtime());
+
+?>
+--EXPECTF--
+array(2) {
+ [0]=>
+ int(%d)
+ [1]=>
+ int(%d)
+}