mirror of
https://github.com/php/pecl-datetime-hrtime.git
synced 2026-03-23 23:32:10 +01:00
initial add of the hrtime ext
git-svn-id: http://svn.php.net/repository/pecl/hrtime/trunk@333366 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
24
README.md
Normal file
24
README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# High resolution timer for PHP #
|
||||
|
||||
This PHP extension brings the possibility to use a high resolution timer from the user land PHP scripts. The best available APIs are used on differend platforms to achieve this goal.
|
||||
|
||||
## Synopsis ##
|
||||
|
||||
```php
|
||||
|
||||
$c = new HRTime\StopWatch;
|
||||
|
||||
$c->start();
|
||||
/* do some interesting stuff*/
|
||||
$c->stop();
|
||||
$elapsed0 = $c->getLastElapsedTime(HRTime\Unit::NANOSECOND);
|
||||
|
||||
/* do something else */
|
||||
|
||||
$c->start();
|
||||
/* do some interesting stuff again */
|
||||
$c->stop();
|
||||
$elapsed1 = $c->getLastElapsedTime(HRTime\Unit::NANOSECOND);
|
||||
|
||||
$elapsed_total = $c->getElapsedTime(HRTime\Unit::NANOSECOND);
|
||||
```
|
||||
12
config.m4
Normal file
12
config.m4
Normal file
@@ -0,0 +1,12 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for extension hrtime
|
||||
|
||||
dnl Otherwise use enable:
|
||||
|
||||
PHP_ARG_ENABLE(hrtime, whether to enable hrtime support,
|
||||
[ --enable-hrtime Enable hrtime support])
|
||||
|
||||
if test "$PHP_HRTIME" != "no"; then
|
||||
PHP_ADD_LIBRARY(rt)
|
||||
PHP_NEW_EXTENSION(hrtime, hrtime.c timer.c, $ext_shared)
|
||||
fi
|
||||
9
config.w32
Normal file
9
config.w32
Normal file
@@ -0,0 +1,9 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_ENABLE("hrtime", "enable hrtime support", "no");
|
||||
|
||||
if (PHP_HRTIME != "no") {
|
||||
EXTENSION("hrtime", "hrtime.c timer.c");
|
||||
}
|
||||
|
||||
415
hrtime.c
Normal file
415
hrtime.c
Normal file
@@ -0,0 +1,415 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Anatol Belski
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Anatol Belski <ab@php.net>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "php_hrtime.h"
|
||||
|
||||
/*ZEND_DECLARE_MODULE_GLOBALS(hrtime);*/
|
||||
|
||||
/* True global resources - no need for thread safety here */
|
||||
static int le_hrtime;
|
||||
|
||||
zend_class_entry *PerformanceCounter_ce;
|
||||
zend_class_entry *StopWatch_ce;
|
||||
zend_class_entry *Unit_ce;
|
||||
|
||||
/* {{{ hrtime_functions[]
|
||||
*
|
||||
* Every user visible function must have an entry in hrtime_functions[].
|
||||
*/
|
||||
const zend_function_entry hrtime_functions[] = {
|
||||
PHP_FE_END
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
const zend_function_entry PerformanceCounter_methods[] = {/*{{{*/
|
||||
PHP_ME(PerformanceCounter, start, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PerformanceCounter, stop, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PerformanceCounter, getElapsedTicks, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PerformanceCounter, getLastElapsedTicks, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PerformanceCounter, getFrequency, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(PerformanceCounter, isRunning, NULL, ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};/*}}}*/
|
||||
|
||||
const zend_function_entry StopWatch_methods[] = {/*{{{*/
|
||||
PHP_ME(StopWatch, getElapsedTime, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(StopWatch, getLastElapsedTime, NULL, ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};/*}}}*/
|
||||
|
||||
/* {{{ hrtime_module_entry
|
||||
*/
|
||||
zend_module_entry hrtime_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
"hrtime",
|
||||
hrtime_functions,
|
||||
PHP_MINIT(hrtime),
|
||||
PHP_MSHUTDOWN(hrtime),
|
||||
PHP_RINIT(hrtime),
|
||||
PHP_RSHUTDOWN(hrtime),
|
||||
PHP_MINFO(hrtime),
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
PHP_HRTIME_VERSION,
|
||||
#endif
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_HRTIME
|
||||
ZEND_GET_MODULE(hrtime)
|
||||
#endif
|
||||
|
||||
void
|
||||
php_performance_counter_obj_destroy(void *obj TSRMLS_DC)
|
||||
{/*{{{*/
|
||||
struct ze_performance_counter_obj *zvco = (struct ze_performance_counter_obj *)obj;
|
||||
|
||||
zend_object_std_dtor(&zvco->zo TSRMLS_CC);
|
||||
|
||||
/*hrtime_counter_destroy(&zvco->htc);*/
|
||||
|
||||
efree(zvco);
|
||||
}/*}}}*/
|
||||
|
||||
zend_object_value
|
||||
php_performance_counter_obj_init(zend_class_entry *ze TSRMLS_DC)
|
||||
{/*{{{*/
|
||||
zend_object_value ret;
|
||||
struct ze_performance_counter_obj *zvco;
|
||||
#if PHP_VERSION_ID < 50399
|
||||
zval *tmp;
|
||||
#endif
|
||||
|
||||
zvco = (struct ze_performance_counter_obj *)emalloc(sizeof(struct ze_performance_counter_obj));
|
||||
memset(&zvco->zo, 0, sizeof(zend_object));
|
||||
|
||||
zend_object_std_init(&zvco->zo, ze TSRMLS_CC);
|
||||
#if PHP_VERSION_ID < 50399
|
||||
zend_hash_copy(zvco->zo.properties, &ze->default_properties, (copy_ctor_func_t) zval_add_ref,
|
||||
(void *) &tmp, sizeof(zval *));
|
||||
#else
|
||||
object_properties_init(&zvco->zo, ze);
|
||||
#endif
|
||||
|
||||
zvco->is_running = 0;
|
||||
zvco->start = 0;
|
||||
zvco->elapsed = 0;
|
||||
zvco->elapsed_ref = 0;
|
||||
|
||||
ret.handle = zend_objects_store_put(zvco, NULL,
|
||||
(zend_objects_free_object_storage_t) php_performance_counter_obj_destroy,
|
||||
NULL TSRMLS_CC);
|
||||
#if PHP_VERSION_ID < 50399
|
||||
ret.handlers = zend_get_std_object_handlers();
|
||||
ret.handlers->clone_obj = NULL;
|
||||
#else
|
||||
ret.handlers = &default_hrtime_handlers;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}/*}}}*/
|
||||
|
||||
/* {{{ PHP_INI
|
||||
*/
|
||||
/* Remove comments and fill if you need to have entries in php.ini
|
||||
PHP_INI_BEGIN()
|
||||
STD_PHP_INI_ENTRY("hrtime.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_hrtime_globals, hrtime_globals)
|
||||
STD_PHP_INI_ENTRY("hrtime.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_hrtime_globals, hrtime_globals)
|
||||
PHP_INI_END()
|
||||
*/
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_hrtime_counter_init_globals
|
||||
*/
|
||||
/* Uncomment this function if you have INI entries
|
||||
static void php_hrtime_init_globals(zend_hrtime_globals *hrtime_globals)
|
||||
{
|
||||
hrtime_globals->global_value = 0;
|
||||
hrtime_globals->global_string = NULL;
|
||||
}
|
||||
*/
|
||||
/* }}} */
|
||||
|
||||
#define HRTIME_SECOND 0
|
||||
#define HRTIME_MILLISECOND 1
|
||||
#define HRTIME_MICROSECOND 2
|
||||
#define HRTIME_NANOSECOND 3
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(hrtime)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
if (timer_lib_initialize()) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to initialize internal timer");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID >= 50399
|
||||
memcpy(&default_hrtime_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
default_hrtime_handlers.clone_obj = NULL;
|
||||
#endif
|
||||
|
||||
/* Init internal classes */
|
||||
INIT_CLASS_ENTRY(ce, "HRTime\\PerformanceCounter", PerformanceCounter_methods);
|
||||
ce.create_object = php_performance_counter_obj_init;
|
||||
PerformanceCounter_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "HRTime\\StopWatch", StopWatch_methods);
|
||||
ce.create_object = php_performance_counter_obj_init;
|
||||
StopWatch_ce = zend_register_internal_class_ex(&ce, PerformanceCounter_ce, "HRTime\\PerformanceCounter" TSRMLS_CC);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "HRTime\\Unit", NULL);
|
||||
Unit_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
zend_declare_class_constant_long(Unit_ce, "SECOND", sizeof("SECOND")-1, HRTIME_SECOND TSRMLS_CC);
|
||||
zend_declare_class_constant_long(Unit_ce, "MILLISECOND", sizeof("MILLISECOND")-1, HRTIME_MILLISECOND TSRMLS_CC);
|
||||
zend_declare_class_constant_long(Unit_ce, "MICROSECOND", sizeof("MICROSECOND")-1, HRTIME_MICROSECOND TSRMLS_CC);
|
||||
zend_declare_class_constant_long(Unit_ce, "NANOSECOND", sizeof("NANOSECOND")-1, HRTIME_NANOSECOND TSRMLS_CC);
|
||||
|
||||
/*
|
||||
REGISTER_INI_ENTRIES();
|
||||
*/
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(hrtime)
|
||||
{
|
||||
timer_lib_shutdown();
|
||||
|
||||
/*
|
||||
UNREGISTER_INI_ENTRIES();
|
||||
*/
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Remove if there's nothing to do at request start */
|
||||
/* {{{ PHP_RINIT_FUNCTION
|
||||
*/
|
||||
PHP_RINIT_FUNCTION(hrtime)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Remove if there's nothing to do at request end */
|
||||
/* {{{ PHP_RSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_RSHUTDOWN_FUNCTION(hrtime)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(hrtime)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "hrtime support", "enabled");
|
||||
php_info_print_table_header(2, "Version", PHP_HRTIME_VERSION);
|
||||
php_info_print_table_end();
|
||||
|
||||
/* Remove comments if you have entries in php.ini
|
||||
DISPLAY_INI_ENTRIES();
|
||||
*/
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHP_METHOD(PerformanceCounter, start)
|
||||
{/*{{{*/
|
||||
struct ze_performance_counter_obj *zvco;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
zvco = (struct ze_performance_counter_obj *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (zvco->is_running) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The counter is already running");
|
||||
return;
|
||||
}
|
||||
|
||||
zvco->start = timer_current();
|
||||
zvco->is_running = 1;
|
||||
}/*}}}*/
|
||||
|
||||
PHP_METHOD(PerformanceCounter, stop)
|
||||
{/*{{{*/
|
||||
struct ze_performance_counter_obj *zvco;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
zvco = (struct ze_performance_counter_obj *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (!zvco->is_running) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The counter is not running");
|
||||
return;
|
||||
}
|
||||
|
||||
zvco->elapsed_ref = timer_elapsed_ticks(zvco->start);
|
||||
zvco->elapsed += zvco->elapsed_ref;
|
||||
zvco->is_running = 0;
|
||||
}/*}}}*/
|
||||
|
||||
PHP_METHOD(PerformanceCounter, getElapsedTicks)
|
||||
{/*{{{*/
|
||||
struct ze_performance_counter_obj *zvco;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
zvco = (struct ze_performance_counter_obj *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (zvco->is_running) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Counter is still running");
|
||||
}
|
||||
|
||||
RETURN_LONG(zvco->elapsed);
|
||||
}/*}}}*/
|
||||
|
||||
PHP_METHOD(PerformanceCounter, getLastElapsedTicks)
|
||||
{/*{{{*/
|
||||
struct ze_performance_counter_obj *zvco;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
zvco = (struct ze_performance_counter_obj *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (zvco->is_running) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Counter is still running");
|
||||
RETURN_LONG(0);
|
||||
}
|
||||
|
||||
RETURN_LONG(zvco->elapsed_ref);
|
||||
}/*}}}*/
|
||||
|
||||
PHP_METHOD(PerformanceCounter, getFrequency)
|
||||
{/*{{{*/
|
||||
struct ze_performance_counter_obj *zvco;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
zvco = (struct ze_performance_counter_obj *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
RETURN_LONG(timer_ticks_per_second());
|
||||
}/*}}}*/
|
||||
|
||||
PHP_METHOD(PerformanceCounter, isRunning)
|
||||
{/*{{{*/
|
||||
struct ze_performance_counter_obj *zvco;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
zvco = (struct ze_performance_counter_obj *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
RETURN_BOOL(zvco->is_running);
|
||||
}/*}}}*/
|
||||
|
||||
#define RET_TIME_BY_UNIT(t, unit) do { \
|
||||
double factor; \
|
||||
switch (unit) { \
|
||||
default: \
|
||||
case HRTIME_SECOND: \
|
||||
factor = 1.0; \
|
||||
break; \
|
||||
case HRTIME_MILLISECOND: \
|
||||
factor = 1000.0; \
|
||||
break; \
|
||||
case HRTIME_MICROSECOND: \
|
||||
factor = 1000000.0; \
|
||||
break; \
|
||||
case HRTIME_NANOSECOND: \
|
||||
factor = 1000000000.0; \
|
||||
break; \
|
||||
} \
|
||||
RETURN_DOUBLE(((double)t/(double)timer_ticks_per_second())*factor); \
|
||||
/*RETURN_DOUBLE((double)timer_elapsed(t)/factor);*/ \
|
||||
} while (0);
|
||||
|
||||
PHP_METHOD(StopWatch, getElapsedTime)
|
||||
{/*{{{*/
|
||||
struct ze_performance_counter_obj *zvco;
|
||||
long unit;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &unit) == FAILURE) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
zvco = (struct ze_performance_counter_obj *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
RET_TIME_BY_UNIT(zvco->elapsed, unit);
|
||||
}/*}}}*/
|
||||
|
||||
PHP_METHOD(StopWatch, getLastElapsedTime)
|
||||
{/*{{{*/
|
||||
struct ze_performance_counter_obj *zvco;
|
||||
long unit;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &unit) == FAILURE) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
zvco = (struct ze_performance_counter_obj *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
RET_TIME_BY_UNIT(zvco->elapsed_ref, unit);
|
||||
}/*}}}*/
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
21
hrtime.php
Normal file
21
hrtime.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
$br = (php_sapi_name() == "cli")? "":"<br>";
|
||||
|
||||
if(!extension_loaded('hrtime')) {
|
||||
dl('hrtime.' . PHP_SHLIB_SUFFIX);
|
||||
}
|
||||
$module = 'hrtime';
|
||||
$functions = get_extension_funcs($module);
|
||||
echo "Functions available in the test extension:$br\n";
|
||||
foreach($functions as $func) {
|
||||
echo $func."$br\n";
|
||||
}
|
||||
echo "$br\n";
|
||||
$function = 'confirm_' . $module . '_compiled';
|
||||
if (extension_loaded($module)) {
|
||||
$str = $function($module);
|
||||
} else {
|
||||
$str = "Module $module is not compiled into PHP";
|
||||
}
|
||||
echo "$str\n";
|
||||
?>
|
||||
100
php_hrtime.h
Normal file
100
php_hrtime.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Anatol Belski
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Anatol Belski <ab@php.net>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef PHP_HRTIME_H
|
||||
#define PHP_HRTIME_H
|
||||
|
||||
#define PHP_HRTIME_VERSION "0.4.3"
|
||||
|
||||
extern zend_module_entry hrtime_module_entry;
|
||||
#define phpext_hrtime_ptr &hrtime_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# define PHP_HRTIME_API __declspec(dllexport)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define PHP_HRTIME_API __attribute__ ((visibility("default")))
|
||||
#else
|
||||
# define PHP_HRTIME_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
PHP_MINIT_FUNCTION(hrtime);
|
||||
PHP_MSHUTDOWN_FUNCTION(hrtime);
|
||||
PHP_RINIT_FUNCTION(hrtime);
|
||||
PHP_RSHUTDOWN_FUNCTION(hrtime);
|
||||
PHP_MINFO_FUNCTION(hrtime);
|
||||
|
||||
PHP_METHOD(PerformanceCounter, start);
|
||||
PHP_METHOD(PerformanceCounter, stop);
|
||||
PHP_METHOD(PerformanceCounter, getElapsedTicks);
|
||||
PHP_METHOD(PerformanceCounter, getLastElapsedTicks);
|
||||
PHP_METHOD(PerformanceCounter, getFrequency);
|
||||
PHP_METHOD(PerformanceCounter, isRunning);
|
||||
|
||||
PHP_METHOD(StopWatch, getElapsedTime);
|
||||
PHP_METHOD(StopWatch, getLastElapsedTime);
|
||||
|
||||
|
||||
/*ZEND_BEGIN_MODULE_GLOBALS(hrtime)
|
||||
ZEND_END_MODULE_GLOBALS(hrtime)*/
|
||||
|
||||
#ifdef ZTS
|
||||
#define HRTIME_G(v) TSRMG(hrtime_globals_id, zend_hrtime_globals *, v)
|
||||
#else
|
||||
#define HRTIME_G(v) (hrtime_globals.v)
|
||||
#endif
|
||||
|
||||
struct ze_performance_counter_obj {
|
||||
zend_object zo;
|
||||
tick_t start;
|
||||
tick_t elapsed;
|
||||
tick_t elapsed_ref;
|
||||
zend_bool is_running;
|
||||
};
|
||||
|
||||
#if PHP_VERSION_ID >= 50399
|
||||
zend_object_handlers default_hrtime_handlers;
|
||||
#endif
|
||||
|
||||
#endif /* PHP_HRTIME_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
100
tests/001.phpt
Normal file
100
tests/001.phpt
Normal file
@@ -0,0 +1,100 @@
|
||||
--TEST--
|
||||
HRTime\StopWatch lasts not more that microtime()
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("hrtime")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include 'helper.inc';
|
||||
|
||||
for ($j = 0; $j < 4; $j++) {
|
||||
$c = new HRTime\StopWatch;
|
||||
|
||||
$t0 = microtime(true);
|
||||
for ($i = 0; $i < 1024; $i++);
|
||||
$t1 = microtime(true);
|
||||
$elapsed0 = $t1 - $t0;
|
||||
|
||||
$c->start();
|
||||
for ($i = 0; $i < 1024; $i++);
|
||||
$c->stop();
|
||||
|
||||
$e0 = $elapsed0;
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::SECOND);
|
||||
echo "Microtime s: ", $e0, "s", "\n";
|
||||
echo "Stopwatch s: ", $e1, "s", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::SECOND));
|
||||
|
||||
$e0 = s_to($elapsed0, HRTime\Unit::MILLISECOND);
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::MILLISECOND);
|
||||
echo "Microtime ms: ", $e0, "ms", "\n";
|
||||
echo "Stopwatch ms: ", $e1, "ms", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::MILLISECOND));
|
||||
|
||||
$e0 = s_to($elapsed0, HRTime\Unit::MICROSECOND);
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::MICROSECOND);
|
||||
echo "Microtime us: ", $e0, "us", "\n";
|
||||
echo "Stopwatch us: ", $e1, "us", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::MICROSECOND));
|
||||
|
||||
$e0 = s_to($elapsed0, HRTime\Unit::NANOSECOND);
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::NANOSECOND);
|
||||
echo "Microtime ns: ", $e0, "ns", "\n";
|
||||
echo "Stopwatch ns: ", $e1, "ns", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::NANOSECOND));
|
||||
|
||||
echo "\n";
|
||||
}
|
||||
--EXPECTF--
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
64
tests/002.phpt
Normal file
64
tests/002.phpt
Normal file
@@ -0,0 +1,64 @@
|
||||
--TEST--
|
||||
HRTime\StopWatch partial elapsed ticks sum == total elapsed ticks
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("hrtime")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
for ($j = 0; $j < 4; $j++) {
|
||||
$c = new HRTime\StopWatch;
|
||||
|
||||
$c->start();
|
||||
for ($i = 0; $i < 1024; $i++);
|
||||
$c->stop();
|
||||
$elapsed0 = $c->getLastElapsedTicks();
|
||||
|
||||
usleep(1000);
|
||||
|
||||
$c->start();
|
||||
for ($i = 0; $i < 1024; $i++);
|
||||
$c->stop();
|
||||
$elapsed1 = $c->getLastElapsedTicks();
|
||||
|
||||
usleep(1000);
|
||||
|
||||
$c->start();
|
||||
for ($i = 0; $i < 1024; $i++);
|
||||
$c->stop();
|
||||
$elapsed2 = $c->getLastElapsedTicks();
|
||||
|
||||
$elapsed_total = $c->getElapsedTicks();
|
||||
|
||||
echo "elapsed0=$elapsed0\n";
|
||||
echo "elapsed1=$elapsed1\n";
|
||||
echo "calculated elapsed total=" . ($elapsed0 + $elapsed1 + $elapsed2) . "\n";
|
||||
echo "elapsed total=$elapsed_total\n";
|
||||
var_dump(($elapsed0 + $elapsed1 + $elapsed2) == $elapsed_total);
|
||||
|
||||
echo "\n";
|
||||
}
|
||||
--EXPECTF--
|
||||
elapsed0=%d
|
||||
elapsed1=%d
|
||||
calculated elapsed total=%d
|
||||
elapsed total=%d
|
||||
bool(true)
|
||||
|
||||
elapsed0=%d
|
||||
elapsed1=%d
|
||||
calculated elapsed total=%d
|
||||
elapsed total=%d
|
||||
bool(true)
|
||||
|
||||
elapsed0=%d
|
||||
elapsed1=%d
|
||||
calculated elapsed total=%d
|
||||
elapsed total=%d
|
||||
bool(true)
|
||||
|
||||
elapsed0=%d
|
||||
elapsed1=%d
|
||||
calculated elapsed total=%d
|
||||
elapsed total=%d
|
||||
bool(true)
|
||||
|
||||
101
tests/003.phpt
Normal file
101
tests/003.phpt
Normal file
@@ -0,0 +1,101 @@
|
||||
--TEST--
|
||||
HRTime\StopWatch is fine with sleep
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("hrtime")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include 'helper.inc';
|
||||
|
||||
for ($j = 0; $j < 4; $j++) {
|
||||
$c = new HRTime\StopWatch;
|
||||
|
||||
$t0 = microtime(true);
|
||||
sleep(1);
|
||||
$t1 = microtime(true);
|
||||
$elapsed0 = $t1 - $t0;
|
||||
|
||||
$c->start();
|
||||
sleep(1);
|
||||
$c->stop();
|
||||
|
||||
$e0 = $elapsed0;
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::SECOND);
|
||||
echo "Microtime s: ", $e0, "s", "\n";
|
||||
echo "Stopwatch s: ", $e1, "s", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::SECOND));
|
||||
|
||||
$e0 = s_to($elapsed0, HRTime\Unit::MILLISECOND);
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::MILLISECOND);
|
||||
echo "Microtime ms: ", $e0, "ms", "\n";
|
||||
echo "Stopwatch ms: ", $e1, "ms", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::MILLISECOND));
|
||||
|
||||
$e0 = s_to($elapsed0, HRTime\Unit::MICROSECOND);
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::MICROSECOND);
|
||||
echo "Microtime us: ", $e0, "us", "\n";
|
||||
echo "Stopwatch us: ", $e1, "us", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::MICROSECOND));
|
||||
|
||||
$e0 = s_to($elapsed0, HRTime\Unit::NANOSECOND);
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::NANOSECOND);
|
||||
echo "Microtime ns: ", $e0, "ns", "\n";
|
||||
echo "Stopwatch ns: ", $e1, "ns", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::NANOSECOND));
|
||||
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
--EXPECTF--
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
100
tests/004.phpt
Normal file
100
tests/004.phpt
Normal file
@@ -0,0 +1,100 @@
|
||||
--TEST--
|
||||
HRTime\StopWatch is fine with usleep
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("hrtime")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include 'helper.inc';
|
||||
|
||||
for ($j = 0; $j < 4; $j++) {
|
||||
$c = new HRTime\StopWatch;
|
||||
|
||||
$t0 = microtime(true);
|
||||
usleep(1);
|
||||
$t1 = microtime(true);
|
||||
$elapsed0 = $t1 - $t0;
|
||||
|
||||
$c->start();
|
||||
usleep(1);
|
||||
$c->stop();
|
||||
|
||||
$e0 = $elapsed0;
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::SECOND);
|
||||
echo "Microtime s: ", $e0, "s", "\n";
|
||||
echo "Stopwatch s: ", $e1, "s", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::SECOND));
|
||||
|
||||
$e0 = s_to($elapsed0, HRTime\Unit::MILLISECOND);
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::MILLISECOND);
|
||||
echo "Microtime ms: ", $e0, "ms", "\n";
|
||||
echo "Stopwatch ms: ", $e1, "ms", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::MILLISECOND));
|
||||
|
||||
$e0 = s_to($elapsed0, HRTime\Unit::MICROSECOND);
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::MICROSECOND);
|
||||
echo "Microtime us: ", $e0, "us", "\n";
|
||||
echo "Stopwatch us: ", $e1, "us", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::MICROSECOND));
|
||||
|
||||
$e0 = s_to($elapsed0, HRTime\Unit::NANOSECOND);
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::NANOSECOND);
|
||||
echo "Microtime ns: ", $e0, "ns", "\n";
|
||||
echo "Stopwatch ns: ", $e1, "ns", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::NANOSECOND));
|
||||
|
||||
echo "\n";
|
||||
}
|
||||
--EXPECTF--
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
Microtime s: %fs
|
||||
Stopwatch s: %fs
|
||||
bool(true)
|
||||
Microtime ms: %fms
|
||||
Stopwatch ms: %fms
|
||||
bool(true)
|
||||
Microtime us: %fus
|
||||
Stopwatch us: %fus
|
||||
bool(true)
|
||||
Microtime ns: %fns
|
||||
Stopwatch ns: %fns
|
||||
bool(true)
|
||||
|
||||
98
tests/005.phpt
Normal file
98
tests/005.phpt
Normal file
@@ -0,0 +1,98 @@
|
||||
--TEST--
|
||||
HRTime\StopWatch elapsed tick count vs. elapsed time
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("hrtime")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include 'helper.inc';
|
||||
|
||||
$c = new HRTime\StopWatch;
|
||||
$freq = $c->getFrequency();
|
||||
|
||||
for ($j = 0; $j < 4; $j++) {
|
||||
|
||||
$c->start();
|
||||
for ($i = 0; $i < 1024; $i++);
|
||||
$c->stop();
|
||||
$elapsed0 = $c->getLastElapsedTicks();
|
||||
|
||||
$e0 = $elapsed0/$freq;
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::SECOND);
|
||||
echo "calc from ticks s: ", $e0, "s", "\n";
|
||||
echo "time method s: ", $e1, "s", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::SECOND));
|
||||
|
||||
$e0 = ($elapsed0/$freq)*1000.0;
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::MILLISECOND);
|
||||
echo "calc from ticks ms: ", $e0, "ms", "\n";
|
||||
echo "time method ms: ", $e1, "ms", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::MILLISECOND));
|
||||
|
||||
$e0 = ($elapsed0/$freq)*1000000.0;
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::MICROSECOND);
|
||||
echo "calc from ticks us: ", $e0, "us", "\n";
|
||||
echo "time method us: ", $e1, "us", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::MICROSECOND));
|
||||
|
||||
$e0 = ($elapsed0/$freq)*1000000000.0;
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::NANOSECOND);
|
||||
echo "calc from ticks ns: ", $e0, "ns", "\n";
|
||||
echo "time method ns: ", $e1, "ns", "\n";
|
||||
var_dump(is_uncertainty_acceptable($e0, $e1, HRTime\Unit::NANOSECOND));
|
||||
|
||||
echo "\n";
|
||||
}
|
||||
--EXPECTF--
|
||||
calc from ticks s: %fs
|
||||
time method s: %fs
|
||||
bool(true)
|
||||
calc from ticks ms: %fms
|
||||
time method ms: %fms
|
||||
bool(true)
|
||||
calc from ticks us: %fus
|
||||
time method us: %fus
|
||||
bool(true)
|
||||
calc from ticks ns: %fns
|
||||
time method ns: %fns
|
||||
bool(true)
|
||||
|
||||
calc from ticks s: %fs
|
||||
time method s: %fs
|
||||
bool(true)
|
||||
calc from ticks ms: %fms
|
||||
time method ms: %fms
|
||||
bool(true)
|
||||
calc from ticks us: %fus
|
||||
time method us: %fus
|
||||
bool(true)
|
||||
calc from ticks ns: %fns
|
||||
time method ns: %fns
|
||||
bool(true)
|
||||
|
||||
calc from ticks s: %fs
|
||||
time method s: %fs
|
||||
bool(true)
|
||||
calc from ticks ms: %fms
|
||||
time method ms: %fms
|
||||
bool(true)
|
||||
calc from ticks us: %fus
|
||||
time method us: %fus
|
||||
bool(true)
|
||||
calc from ticks ns: %fns
|
||||
time method ns: %fns
|
||||
bool(true)
|
||||
|
||||
calc from ticks s: %fs
|
||||
time method s: %fs
|
||||
bool(true)
|
||||
calc from ticks ms: %fms
|
||||
time method ms: %fms
|
||||
bool(true)
|
||||
calc from ticks us: %fus
|
||||
time method us: %fus
|
||||
bool(true)
|
||||
calc from ticks ns: %fns
|
||||
time method ns: %fns
|
||||
bool(true)
|
||||
|
||||
37
tests/006.phpt
Normal file
37
tests/006.phpt
Normal file
@@ -0,0 +1,37 @@
|
||||
--TEST--
|
||||
HRTime\StopWatch start right after stop with nanosecond resolution > 0
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("hrtime")) print "skip"; ?>
|
||||
--INI--
|
||||
presicion=48
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
for ($j = 0; $j < 4; $j++) {
|
||||
$c = new HRTime\StopWatch;
|
||||
|
||||
$c->start();
|
||||
$c->stop();
|
||||
|
||||
$e1 = $c->getLastElapsedTime(HRTime\Unit::NANOSECOND);
|
||||
var_dump($e1, $e1 >= .0);
|
||||
|
||||
echo "\n";
|
||||
|
||||
/* Need this because the accuracy won't be as good as 1ns even on the best machines.
|
||||
Well, at least now it's sience fiction.*/
|
||||
usleep(1);
|
||||
}
|
||||
--EXPECTF--
|
||||
float(%f)
|
||||
bool(true)
|
||||
|
||||
float(%f)
|
||||
bool(true)
|
||||
|
||||
float(%f)
|
||||
bool(true)
|
||||
|
||||
float(%f)
|
||||
bool(true)
|
||||
|
||||
62
tests/helper.inc
Normal file
62
tests/helper.inc
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
function s_to($secs, $unit)
|
||||
{
|
||||
$ret = .0;
|
||||
|
||||
switch ($unit) {
|
||||
case HRTime\Unit::SECOND:
|
||||
$ret = $secs;
|
||||
break;
|
||||
case HRTime\Unit::MILLISECOND:
|
||||
$ret = $secs*1000.0;
|
||||
break;
|
||||
case HRTime\Unit::MICROSECOND:
|
||||
$ret = $secs*1000000.0;
|
||||
break;
|
||||
case HRTime\Unit::NANOSECOND:
|
||||
$ret = $secs*1000000000.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function uncertainty_abs($a, $b)
|
||||
{
|
||||
return $a - $b;
|
||||
}
|
||||
|
||||
function uncertainty_rel($a, $b)
|
||||
{
|
||||
return uncertainty_abs($a, $b)/$b;
|
||||
}
|
||||
|
||||
function is_uncertainty_acceptable($a, $b, $unit)
|
||||
{
|
||||
$ret = false;
|
||||
|
||||
$rel = uncertainty_rel($a, $b);
|
||||
$treshold = .05;
|
||||
|
||||
switch ($unit) {
|
||||
case HRTime\Unit::SECOND:
|
||||
$ret = abs($rel) < $treshold;
|
||||
break;
|
||||
case HRTime\Unit::MILLISECOND:
|
||||
$ret = abs($rel) < $treshold;
|
||||
break;
|
||||
case HRTime\Unit::MICROSECOND:
|
||||
$ret = abs($rel) < $treshold;
|
||||
break;
|
||||
case HRTime\Unit::NANOSECOND:
|
||||
$ret = abs($rel) < $treshold;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$ret) {
|
||||
printf("a=$a b=$b relative uncertainty %d%%\n", (int)($rel*100.0));
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
174
timer.c
Normal file
174
timer.c
Normal file
@@ -0,0 +1,174 @@
|
||||
/* timer.h - Cross-platform timer library - Public Domain - 2011 Mattias Jansson / Rampant Pixels
|
||||
*
|
||||
* This library provides a cross-platform interface to measure
|
||||
* elapsed time with (at least) millisecond accuracy.
|
||||
*
|
||||
* This library is put in the public domain; you can redistribute
|
||||
* it and/or modify it without any restrictions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
#define TIMER_PLATFORM_WINDOWS 0
|
||||
#define TIMER_PLATFORM_APPLE 0
|
||||
#define TIMER_PLATFORM_POSIX 0
|
||||
|
||||
#if defined( _WIN32 ) || defined( _WIN64 )
|
||||
# undef TIMER_PLATFORM_WINDOWS
|
||||
# define TIMER_PLATFORM_WINDOWS 1
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
#elif defined( __APPLE__ )
|
||||
# undef TIMER_PLATFORM_APPLE
|
||||
# define TIMER_PLATFORM_APPLE 1
|
||||
# include <mach/mach_time.h>
|
||||
# include <string.h>
|
||||
static mach_timebase_info_data_t _timerlib_info;
|
||||
static void absolutetime_to_nanoseconds (uint64_t mach_time, uint64_t* clock ) { *clock = mach_time * _timerlib_info.numer / _timerlib_info.denom; }
|
||||
#else
|
||||
# undef TIMER_PLATFORM_POSIX
|
||||
# define TIMER_PLATFORM_POSIX 1
|
||||
# include <unistd.h>
|
||||
# include <time.h>
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
static tick_t _timerlib_freq = 0;
|
||||
static double _timerlib_oofreq = 0;
|
||||
|
||||
|
||||
int timer_lib_initialize( void )
|
||||
{
|
||||
#if TIMER_PLATFORM_WINDOWS
|
||||
tick_t unused;
|
||||
if( !QueryPerformanceFrequency( (LARGE_INTEGER*)&_timerlib_freq ) ||
|
||||
!QueryPerformanceCounter( (LARGE_INTEGER*)&unused ) )
|
||||
return -1;
|
||||
#elif TIMER_PLATFORM_APPLE
|
||||
if( mach_timebase_info( &_timerlib_info ) )
|
||||
return -1;
|
||||
_timerlib_freq = 1000000000ULL;
|
||||
#elif TIMER_PLATFORM_POSIX
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
|
||||
if( clock_gettime( CLOCK_MONOTONIC, &ts ) )
|
||||
return -1;
|
||||
_timerlib_freq = 1000000000ULL;
|
||||
#endif
|
||||
|
||||
_timerlib_oofreq = 1.0 / (double)_timerlib_freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void timer_lib_shutdown( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
tick_t timer_current( void )
|
||||
{
|
||||
#if TIMER_PLATFORM_WINDOWS
|
||||
|
||||
tick_t curclock;
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*)&curclock );
|
||||
return curclock;
|
||||
|
||||
#elif TIMER_PLATFORM_APPLE
|
||||
|
||||
tick_t curclock = 0;
|
||||
absolutetime_to_nanoseconds( mach_absolute_time(), &curclock );
|
||||
return curclock;
|
||||
|
||||
#elif TIMER_PLATFORM_POSIX
|
||||
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
|
||||
clock_gettime( CLOCK_MONOTONIC, &ts );
|
||||
return ( (uint64_t)ts.tv_sec * 1000000000ULL ) + ts.tv_nsec;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
tick_t timer_ticks_per_second( void )
|
||||
{
|
||||
return _timerlib_freq;
|
||||
}
|
||||
|
||||
|
||||
deltatime_t timer_elapsed( const tick_t t )
|
||||
{
|
||||
return (deltatime_t)( (double)timer_elapsed_ticks( t ) * _timerlib_oofreq );
|
||||
}
|
||||
|
||||
|
||||
tick_t timer_elapsed_ticks( const tick_t t )
|
||||
{
|
||||
tick_t dt = 0;
|
||||
|
||||
#if TIMER_PLATFORM_WINDOWS
|
||||
|
||||
tick_t curclock = t;
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*)&curclock );
|
||||
dt = curclock - t;
|
||||
|
||||
#elif TIMER_PLATFORM_APPLE
|
||||
|
||||
tick_t curclock = t;
|
||||
absolutetime_to_nanoseconds( mach_absolute_time(), &curclock );
|
||||
dt = curclock - t;
|
||||
|
||||
#elif TIMER_PLATFORM_POSIX
|
||||
|
||||
tick_t curclock;
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
|
||||
clock_gettime( CLOCK_MONOTONIC, &ts );
|
||||
|
||||
curclock = ( (tick_t)ts.tv_sec * 1000000000ULL ) + ts.tv_nsec;
|
||||
dt = curclock - t;
|
||||
|
||||
#endif
|
||||
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
||||
deltatime_t timer_ticks_to_seconds( const tick_t dt )
|
||||
{
|
||||
return (deltatime_t)( (double)dt * _timerlib_oofreq );
|
||||
}
|
||||
|
||||
|
||||
#if TIMER_PLATFORM_WINDOWS
|
||||
struct __timeb64 {
|
||||
__time64_t time;
|
||||
unsigned short millitm;
|
||||
short timezone;
|
||||
short dstflag;
|
||||
};
|
||||
_CRTIMP errno_t __cdecl _ftime64_s(_Out_ struct __timeb64 * _Time);
|
||||
#endif
|
||||
|
||||
tick_t timer_system( void )
|
||||
{
|
||||
#if TIMER_PLATFORM_WINDOWS
|
||||
|
||||
struct __timeb64 tb;
|
||||
_ftime64_s( &tb );
|
||||
return ( (tick_t)tb.time * 1000ULL ) + (tick_t)tb.millitm;
|
||||
|
||||
#elif TIMER_PLATFORM_APPLE
|
||||
|
||||
tick_t curclock = 0;
|
||||
absolutetime_to_nanoseconds( mach_absolute_time(), &curclock );
|
||||
return ( curclock / 1000000ULL );
|
||||
|
||||
#elif TIMER_PLATFORM_POSIX
|
||||
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
|
||||
clock_gettime( CLOCK_REALTIME, &ts );
|
||||
return ( (uint64_t)ts.tv_sec * 1000ULL ) + ( ts.tv_nsec / 1000000ULL );
|
||||
|
||||
#endif
|
||||
}
|
||||
77
timer.h
Normal file
77
timer.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* timer.h - Cross-platform timer library - Public Domain - 2011 Mattias Jansson / Rampant Pixels
|
||||
*
|
||||
* This library provides a cross-platform interface to measure
|
||||
* elapsed time with (at least) millisecond accuracy.
|
||||
*
|
||||
* This library is put in the public domain; you can redistribute
|
||||
* it and/or modify it without any restrictions.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*! \file timer.h
|
||||
Time measurements */
|
||||
|
||||
#if TIMER_COMPILE
|
||||
#define TIMER_API
|
||||
#else
|
||||
#if __cplusplus
|
||||
#define TIMER_API extern "C"
|
||||
#else
|
||||
#define TIMER_API extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined( _WIN32 ) || defined( _WIN64 )
|
||||
|
||||
//! Tick type
|
||||
typedef unsigned __int64 tick_t;
|
||||
|
||||
#else
|
||||
|
||||
#include <stdint.h>
|
||||
//! Tick type
|
||||
typedef uint64_t tick_t;
|
||||
|
||||
#endif
|
||||
|
||||
//! Deltatime type (float or double)
|
||||
//typedef float deltatime_t;
|
||||
typedef double deltatime_t;
|
||||
|
||||
|
||||
/*! Initialize timer library */
|
||||
TIMER_API int timer_lib_initialize( void );
|
||||
|
||||
/*! Shutdown timer library */
|
||||
TIMER_API void timer_lib_shutdown( void );
|
||||
|
||||
/*! Get current timestamp, in ticks of system-specific frequency (queryable with timer_ticks_per_second), measured from some system-specific base timestamp
|
||||
and not in sync with other timestamps
|
||||
\return Current timestamp */
|
||||
TIMER_API tick_t timer_current( void );
|
||||
|
||||
/*! Get elapsed time since given timestamp
|
||||
\param t Timestamp
|
||||
\return Number of seconds elapsed */
|
||||
TIMER_API deltatime_t timer_elapsed( const tick_t t );
|
||||
|
||||
/*! Get elapsed ticks since given timestamp
|
||||
\param t Timestamp
|
||||
\return Number of ticks elapsed */
|
||||
TIMER_API tick_t timer_elapsed_ticks( const tick_t t );
|
||||
|
||||
/*! Get timer frequency, as number of ticks per second
|
||||
\return Ticks per second */
|
||||
TIMER_API tick_t timer_ticks_per_second( void );
|
||||
|
||||
/*! Get ticks as seconds (effectively calculating ticks/timer_ticks_per_second())
|
||||
\param dt Deltatime in ticks
|
||||
\return Deltatime in seconds */
|
||||
TIMER_API deltatime_t timer_ticks_to_seconds( const tick_t dt );
|
||||
|
||||
/*! Get system time, in milliseconds since the epoch (UNIX time)
|
||||
\return Current timestamp, in milliseconds */
|
||||
TIMER_API tick_t timer_system( void );
|
||||
|
||||
Reference in New Issue
Block a user