MSUTimer  v0.01 alpha
Simple High Resolution Timer for C
msutimer.h File Reference

Simple High Resolution Timer for C (public interface). More...

#include <stddef.h>
#include <stdbool.h>

Go to the source code of this file.

Macros

Convenience Macros

Benchmark functions (and others) return microseconds, so the following macros may prove handy to the caller.

#define MSUT_US2MS(usecs)   ((usecs) * 0.001)
 Convert microseconds to milliseconds.
 
#define MSUT_US2S(usecs)   ((usecs) * 0.000001)
 Convert microseconds to seconds.
 

Typedefs

typedef struct MSUTimer_ MSUTimer
 Opaque type (forward-declaration)
 

Functions

MSUTimermsutimer_new (void)
 Create a new timer. More...
 
MSUTimermsutimer_free (MSUTimer *timer)
 Free an existing timer. More...
 
double msutimer_accuracy_usecs (MSUTimer *timer)
 Get MSUTimer accuracy. More...
 
double msutimer_gettime (MSUTimer *timer)
 Get current time & update time-difference. More...
 
double msutimer_diff_usecs (MSUTimer *timer)
 Get updated time-difference in microseconds. More...
 
double msutimer_diff_msecs (MSUTimer *timer)
 Get updated time-difference in milliseconds. More...
 
double msutimer_diff_secs (MSUTimer *timer)
 Get updated time-difference in seconds. More...
 
double msutimer_bench (MSUTimer *timer, size_t nrepeats, bool(*callback)(void *), void *userdata, size_t *erepeat)
 Get callback's execution time. More...
 
double msutimer_bench_average (MSUTimer *timer, size_t nrepeats, bool(*callback)(void *), void *userdata, size_t *erepeat)
 Get callback's average execution time. More...
 
double msutimer_bench_median (MSUTimer *timer, size_t nrepeats, bool(*callback)(void *), void *userdata, size_t *erepeat)
 Get callback's median execution time. More...
 

Detailed Description

Simple High Resolution Timer for C (public interface).

Version
0.01 alpha
Date
19 June, 2021
Author
migf1 mig_f.nosp@m.1@ho.nosp@m.tmail.nosp@m..com
Language:
ISO C99
Online Docs:
https://migf1.github.io/msutimer-docs/
License
This project is released under the zlib license (see LICENSE.txt)

Function Documentation

◆ msutimer_accuracy_usecs()

double msutimer_accuracy_usecs ( MSUTimer timer)

Get MSUTimer accuracy.

Obtains the minimum time-interval that can be measured by MSUTimer, on the running platform. The returned microseconds can be converted to milliseconds or seconds, with the convenience macros MSUT_US2MS() or MSUT_US2S(), respectively.

Parameters
timerAny already created timer.
Returns
A double representing the MSUTimer accuracy on the current platform in microseconds, or -DBL_MAX on error.
Remarks
On Windows, a typical accuracy is around 0.320 microseconds. Occasionally the function may return a bogus value, but it is pretty rare (and I really don't know why it's doing that).
Failures:
  • timer is NULL (errno is set to EDOM)
See also
Platform Dependent Measurements
Sample Usage
#include "msutimer.h"
...
int main( void ) {
MSUTimer *timer = msutimer_new();
if (!timer) { fputs("msutimer_new()failed!\n", stderr); exit(1); }
double usecs = msutimer_accuracy_usecs(timer);
printf( "MSUTimer accuracy: %.9.lf secs\n", MSUT_US2S(usecs) );
printf( "MSUTimer accuracy: %.9.lf msecs\n", MSUT_US2MS(usecs) );
printf( "MSUTimer accuracy: %.9.lf usecs\n", usecs );
msutimer_free( timer );
exit(0);
}
// Output -------------
// MSUTimer accuracy: 0.000000320 secs
// MSUTimer accuracy: 0.000320801 msecs
// MSUTimer accuracy: 0.320312500 usecs
Simple High Resolution Timer for C (public interface).
double msutimer_accuracy_usecs(MSUTimer *timer)
Get MSUTimer accuracy.
Definition: msutimer.c:469
#define MSUT_US2S(usecs)
Convert microseconds to seconds.
Definition: msutimer.h:52
#define MSUT_US2MS(usecs)
Convert microseconds to milliseconds.
Definition: msutimer.h:51
MSUTimer * msutimer_free(MSUTimer *timer)
Free an existing timer.
Definition: msutimer.c:262
MSUTimer * msutimer_new(void)
Create a new timer.
Definition: msutimer.c:205

◆ msutimer_bench()

double msutimer_bench ( MSUTimer timer,
size_t  nrepeats,
bool(*)(void *)  callback,
void *  userdata,
size_t *  erepeat 
)

Get callback's execution time.

Measures the execution time of its callback-function argument, after a specified number of iterations.

Parameters
timerAn already created timer.
nrepeatsThe number of times to execute the callback-function (iterations).
callbackThe callback-function to be measured. It should be of type bool (C99) returning false on error, true otherwise. Its prototype should be the following:
bool (*callback)(void *userdata);
userdataA void pointer to caller-defined data, used by the callback-function. This pointer gets directly passed to the callback-function without any processing. It may be NULL if the callback-functions doesn't use any extra data.
erepeatIf non-NULL, then in case of callback error (false) erepeat passes back to the caller the last successful iteration.
Returns
A double representing the time spent (in microseconds) to execute the callback-function nrepeats times.

If the callback-function errors before completing nrepeats iterations, then the returned value is negative and erepeat (if non-NULL) passes back to the caller the last successful iteration. Hence a negative return value reflects the number of microseconds elpased until the erepeat'th iteration.

On all other errors, errno is set to EDOM and the function returns 0.0

Remarks
  • When the function returns 0.0, the caller can tell if there was an error by checking errno against EDOM (or not being 0). In MSUTimer debug mode (e.g. compiled with -DMSUTDEBUG or -DMSUTDEBUG=2) errors are auto reported to stderr.
  • The return value can be converted to milliseconds or seconds with the convenience macros MSUT_US2MS() or MSUT_US2S(), respectively.
  • For an example (without error-handling) see the section Benchmarking.
Failures:
  • timer is NULL (returns 0.0, errno is set to EDOM)
  • nrepeats is 0 (returns 0.0, errno is set to EDOM)
  • callback is NULL (returns 0.0, errno is set to EDOM)
  • callback returns false (erepeat is set to the last successful iteration and the function returns the elapsed microseconds until then, as a negative double).
See also
msutimer_bench_average(), msutimer_bench_median(), Benchmarking

◆ msutimer_bench_average()

double msutimer_bench_average ( MSUTimer timer,
size_t  nrepeats,
bool(*)(void *)  callback,
void *  userdata,
size_t *  erepeat 
)

Get callback's average execution time.

Measures the average execution time of its callback-function argument, after a specified number of iterations.

Remarks
For details see the function msutimer_bench(). The only difference is that msutimer_bench_average() returns the average time after nrepeats iterations, instead of summing up all iterations.

Put otherwise, msutimer_bench() returns the total time after nrepeats iterations, while msutimer_bench_average() returns the average time of a single call after nrepeats iterations.

Compared to msutimer_bench_median(), this function accounts excessive spikes in the computation (average vs. median).

See also
msutimer_bench(), msutimer_bench_median(), Benchmarking

◆ msutimer_bench_median()

double msutimer_bench_median ( MSUTimer timer,
size_t  nrepeats,
bool(*)(void *)  callback,
void *  userdata,
size_t *  erepeat 
)

Get callback's median execution time.

Measures the median execution time of its callback-function argument, after a specified number of iterations.

Remarks
For details see the function msutimer_bench(). The only difference is that msutimer_bench_median() returns the median time after nrepeats iterations, instead of summing up all iterations.

Put otherwise, msutimer_bench() returns the total time after nrepeats iterations, while msutimer_bench_median() returns the median time of a single call after nrepeats iterations.

Compared to msutimer_bench_average(), this function ignores excessive spikes in the computation (average vs. median).

See also
msutimer_bench(), msutimer_bench_median(), Benchmarking

◆ msutimer_diff_msecs()

double msutimer_diff_msecs ( MSUTimer timer)

Get updated time-difference in milliseconds.

Queries its timer argument for the updated time-difference, after a call to msutimer_gettime(). Calling this function before calling msutimer_gettime() first, results to a random value (bogus time-difference).

Parameters
timerThe timer to be queried.
Returns
A double reflecting the updated time-difference in milliseconds after a call to msutimer_gettime(), or -DBL_MAX on error.
Failures:
  • timer is NULL (errno is set to EDOM)
See also
msutimer_diff_usecs(), msutimer_diff_secs(), Usage Quick Guide

◆ msutimer_diff_secs()

double msutimer_diff_secs ( MSUTimer timer)

Get updated time-difference in seconds.

Queries its timer argument for the updated time-difference, after a call to msutimer_gettime(). Calling this function before calling msutimer_gettime() first, results to a random value (bogus time-difference).

Parameters
timerThe timer to be queried.
Returns
A double reflecting the updated time-difference in seconds after a call to msutimer_gettime(), or -DBL_MAX on error.
Failures:
  • timer is NULL (errno is set to EDOM)
See also
msutimer_diff_usecs(), msutimer_diff_msecs(), Usage Quick Guide

◆ msutimer_diff_usecs()

double msutimer_diff_usecs ( MSUTimer timer)

Get updated time-difference in microseconds.

Queries its timer argument for the updated time-difference, after a call to msutimer_gettime(). Calling this function before calling msutimer_gettime() first, results to a random value (bogus time-difference).

Parameters
timerThe timer to be queried.
Returns
A double reflecting the updated time-difference in microseconds after a call to msutimer_gettime(), or -DBL_MAX on error.
Failures:
  • timer is NULL (errno is set to EDOM)
See also
msutimer_diff_msecs(), msutimer_diff_secs(), Usage Quick Guide
Sample Usage
MSUTimer *timer = msutimer_new(); // if ( !timer1 ) { handle error here }
...
msutimer_gettime( timer );
printf( "Elapsed: %.9lf usecs\n", msutimer_diff_usecs(timer) );
...
msutimer_gettime( timer );
printf( "Elapsed: %.9lf usecs\n", msutimer_diff_usecs(timer) );
msutimer_free( timer );
double msutimer_diff_usecs(MSUTimer *timer)
Get updated time-difference in microseconds.
Definition: msutimer.c:353

◆ msutimer_free()

MSUTimer* msutimer_free ( MSUTimer timer)

Free an existing timer.

De-allocates the memory reserved for its timer argument.

Parameters
timerThe timer to be freed.
Returns
AlwaysNULL, so the caller can opt to assign it back to the freed pointer, to avoid leaving it in a dangling state.
Sample Usage
MSUTimer *timer1 = msutimer_new(); // if ( !timer1 ) { handle error here }
MSUTimer *timer2 = msutimer_new(); // if ( !timer2 ) { handle error here }
...
msutimer_free( timer2 ); // free timer2 and leave it dangling
timer1 = msutimer_free( timer1 ); // free timer1 and reset it to NULL

◆ msutimer_gettime()

double msutimer_gettime ( MSUTimer timer)

Get current time & update time-difference.

Gets the current time and Updates its timer argument with the elapsed time since the previous call of the function, or the construction of the timer (whichever came last). The time-difference can then get fetched as a double with one of the functions: msutimer_diff_usecs(), msutimer_diff_msecs(), msutimer_diff_secs(), which return microseconds, millseconds or seconds respectively.

Alternatively, the caller may opt to calculate the elapsed time manually, by storing and then subtracting the double values returned by 2 calls of the function (similar to how the standard C function clock() is used). This also allows for time measurements over multiple calls of the function. The result of the subtraction represents microseconds, which can then get passed to the convenience macros MSUT_US2MS() or MSUT_US2S() for converting them to milliseconds or seconds, respectively.

Parameters
timerThe timer to be updated.
Returns
A double, representing the current time in microseconds. Useful for calculating manually the time-difference between 2 calls of the function.
Remarks
Typically, the piece of code to be timed is placed between 2 calls of this function. The very first time, the code may also be placed between msutimer_new() and this function, but then the manual calculation method cannot be used (moreover, the construction validation overhead is added to the result).
Failures:
  • timer is NULL (errno is set to EDOM)
See also
msutimer_bench(), msutimer_bench_average(), msutimer_bench_median()
Sample Usage
See Usage Quick Guide for detailed examples.

◆ msutimer_new()

MSUTimer* msutimer_new ( void  )

Create a new timer.

Constructs, initializes and starts a new timer. De-allocation should be done by the caller, with msutimer_free().

Returns
The newly allocated timer, or NULL on error.
Failures:
  • memory allocation failure (errno is set by the C runtime)
  • no OS/hardware support for hires timer (errno is set to ERANGE)
Sample Usage
MSUTimer *timer = msutimer_new();
if ( !timer ) { handle error here }
...