/**
 * Timer that measures real elapsed time, that is "wall clock time".
 * A timer can be started, stopped, restarted and reset.
 * There is no guarantee this timer may return accurate results on any system,
 * but a granularity better than 1 ms should be expected.
 * 
 * @file
 * @author Umberto Salsi <salsi@icosaedro.it>
 * @version $Date: 2017/08/19 02:05:03 $
 */

#ifndef TIMER_H
#define TIMER_H

#include <stdint.h>

#ifdef timer_IMPORT
	#define EXTERN
#else
	#define EXTERN extern
#endif

typedef struct timer_Type timer_Type;

/**
 * Allocates a new stopped timer.
 * @return New stopped timer. Must be released with memory_dispose().
 */
EXTERN timer_Type * timer_new(void);

/**
 * Starts or restarts the timer, continuing accounting elapsed time.
 * Does nothing if the timer is already running.
 * @param t
 */
EXTERN void timer_start(timer_Type *t);

/**
 * Stops the timer. Does nothing if already stopped.
 * @param t
 */
EXTERN void timer_stop(timer_Type *t);

/**
 * Returns the current timer reading as nanoseconds.
 * @param t
 * @return Current timer reading as nanoseconds (1e-9 s).
 */
EXTERN int64_t timer_getElapsedNanoseconds(timer_Type *t);

/**
 * Returns the current timer reading as microseconds.
 * @param t
 * @return Current timer reading as microseconds (1e-6 s).
 */
EXTERN int64_t timer_getElapsedMicroseconds(timer_Type *t);

/**
 * Returns the current timer reading as milliseconds.
 * @param t
 * @return Current timer reading as milliseconds (1e-3 s), possibly INT_MAX if
 * more than 24 days elapsed.
 */
EXTERN int timer_getElapsedMilliseconds(timer_Type *t);

/**
 * Resets the timer.
 * @param t
 */
EXTERN void timer_reset(timer_Type *t);

/**
 * Stops for the given real, wall clock time.
 * @param ms Time to sleep (ms). Does nothing if zero or negative.
 */
EXTERN void timer_sleepMilliseconds(int ms);

#undef EXTERN
#endif
