// 
// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
// 
// clock -- 
// 
// Author           : Peter A. Buhr
// Created On       : Thu Apr 12 14:36:06 2018
// Last Modified By : Peter A. Buhr
// Last Modified On : Tue Jun 26 14:11:44 2018
// Update Count     : 6
// 

#include <time>


//######################### C time #########################

static inline char * ctime( time_t tp ) { char * buf = ctime( &tp ); buf[24] = '\0'; return buf; }
static inline char * ctime_r( time_t tp, char * buf ) { ctime_r( &tp, buf ); buf[24] = '\0'; return buf; }
static inline tm * gmtime( time_t tp ) { return gmtime( &tp ); }
static inline tm * gmtime_r( time_t tp, tm * result ) { return gmtime_r( &tp, result ); }
static inline tm * localtime( time_t tp ) { return localtime( &tp ); }
static inline tm * localtime_r( time_t tp, tm * result ) { return localtime_r( &tp, result ); }


//######################### Clock #########################

struct Clock {											// private
	Duration offset;									// for virtual clock: contains offset from real-time
	int clocktype;										// implementation only -1 (virtual), CLOCK_REALTIME
};

static inline void resetClock( Clock & clk ) with( clk ) {
	clocktype = CLOCK_REALTIME_COARSE;
} // Clock::resetClock

static inline void resetClock( Clock & clk, Duration adj ) with( clk ) {
	clocktype = -1;
	offset = adj + __timezone`s;							// timezone (global) is (UTC - local time) in seconds
} // resetClock

static inline void ?{}( Clock & clk ) { resetClock( clk ); }
static inline void ?{}( Clock & clk, Duration adj ) { resetClock( clk, adj ); }

static inline Duration getResNsec() {
	struct timespec res;
	clock_getres( CLOCK_REALTIME, &res );
	return ((int64_t)res.tv_sec * TIMEGRAN + res.tv_nsec)`ns;
} // getRes

static inline Duration getRes() {
	struct timespec res;
	clock_getres( CLOCK_REALTIME_COARSE, &res );
	return ((int64_t)res.tv_sec * TIMEGRAN + res.tv_nsec)`ns;
} // getRes

static inline Time getTimeNsec() {						// with nanoseconds
	timespec curr;
	clock_gettime( CLOCK_REALTIME, &curr );
	return (Time){ curr };
} // getTime

static inline Time getTime() {							// without nanoseconds
	timespec curr;
	clock_gettime( CLOCK_REALTIME_COARSE, &curr );
	curr.tv_nsec = 0;
	return (Time){ curr };
} // getTime

static inline Time getTime( Clock & clk ) with( clk ) {
	return getTime() + offset;
} // getTime

static inline Time ?()( Clock & clk ) with( clk ) {		// alternative syntax
	return getTime() + offset;
} // getTime

static inline timeval getTime( Clock & clk ) {
	return (timeval){ clk() };
} // getTime

static inline tm getTime( Clock & clk ) with( clk ) {
	tm ret;
	localtime_r( getTime( clk ).tv_sec, &ret );
	return ret;
} // getTime

// Local Variables: //
// mode: c //
// tab-width: 4 //
// End: //
