@@ -674,25 +674,61 @@ uint64_t clockGetLast() {
674
674
return sClock ;
675
675
}
676
676
677
+
678
+ /*
679
+ #include <mach/mach_time.h>
680
+ #include <iostream>
681
+
682
+ int main() {
683
+ uint64_t start = mach_absolute_time();
684
+
685
+ // Perform some actions here
686
+
687
+ uint64_t end = mach_absolute_time();
688
+
689
+ // Get the conversion factor to convert ticks to nanoseconds
690
+ mach_timebase_info_data_t timebase;
691
+ mach_timebase_info(&timebase);
692
+ uint64_t duration = (end - start) * timebase.numer / timebase.denom;
693
+
694
+ std::cout << "Duration in nanoseconds: " << duration << std::endl;
695
+ return 0;
696
+ }
697
+
698
+ */
699
+
700
+
701
+
677
702
#if defined(_LINUX ) // Linux
678
703
679
704
/*
705
+ Option OPTION_ARB_CLOCK provides a clock with 1us resolution since program start
706
+
707
+
680
708
Linux clock type
681
- CLOCK_REALTIME This clock is affected by incremental adjustments performed by NTP
682
- CLOCK_TAI This clock does not experience discontinuities and backwards jumps caused by NTP inserting leap seconds as CLOCK_REALTIME does.
683
- Not available on WSL
709
+ CLOCK_REALTIME This clock is affected by incremental adjustments performed by NTP
710
+ 1ns resolution on MacOS
711
+ CLOCK_TAI This clock does not experience discontinuities and backwards jumps caused by NTP or inserting leap seconds as CLOCK_REALTIME does.
712
+ Not available on Linux and MacOS
713
+ CLOCK_MONOTONIC_RAW Provides a monotonic clock without time drift adjustments by NTP, giving higher stability and resolution
714
+ 1ns resolution also on MACOS
684
715
*/
685
- #define CLOCK_TYPE CLOCK_REALTIME
686
- // #define CLOCK_TYPE CLOCK_TAI
716
+
717
+
718
+ #define CLOCK_TYPE CLOCK_MONOTONIC_RAW
719
+ //#define CLOCK_TYPE CLOCK_REALTIME
720
+ //#define CLOCK_TYPE CLOCK_TAI
721
+
687
722
688
723
static struct timespec gtr ;
689
- #ifndef CLOCK_USE_UTC_TIME_NS
724
+ #ifdef OPTION_ARB_CLOCK
690
725
static struct timespec gts0 ;
691
726
#endif
692
727
728
+
693
729
char * clockGetString (char * s , uint32_t l , uint64_t c ) {
694
730
695
- #ifndef CLOCK_USE_UTC_TIME_NS
731
+ #ifdef OPTION_ARB_CLOCK
696
732
SNPRINTF (s ,l , "%gs" , (double )c / CLOCK_TICKS_PER_S );
697
733
#else
698
734
time_t t = (time_t )(c / CLOCK_TICKS_PER_S ); // s since 1.1.1970
@@ -711,43 +747,41 @@ char* clockGetString(char* s, uint32_t l, uint64_t c) {
711
747
BOOL clockInit ()
712
748
{
713
749
DBG_PRINT3 ("\nInit clock\n (" );
714
- #ifdef CLOCK_USE_UTC_TIME_NS
715
- DBG_PRINT3 ("CLOCK_USE_UTC_TIME_NS," );
716
- #endif
717
- #ifdef CLOCK_USE_APP_TIME_US
718
- DBG_PRINT3 ("CLOCK_USE_APP_TIME_US," );
719
- #endif
720
- #if CLOCK_TYPE == CLOCK_TAI
721
- DBG_PRINT3 ("CLOCK_TYPE_TAI," );
750
+ #ifdef OPTION_TAI_CLOCK
751
+ DBG_PRINT3 ("OPTION_TAI_CLOCK\n" );
722
752
#endif
723
- #if CLOCK_TYPE == CLOCK_REALTIME
724
- DBG_PRINT3 ("CLOCK_TYPE_REALTIME, " );
753
+ #ifdef OPTION_ARB_CLOCK
754
+ DBG_PRINT3 ("OPTION_TAI_CLOCK\n " );
725
755
#endif
726
- DBG_PRINT3 (")\n" );
727
-
756
+
728
757
sClock = 0 ;
729
758
730
759
clock_getres (CLOCK_TYPE , & gtr );
731
- DBG_PRINTF4 ("Clock resolution is %lds,%ldns!\n" , gtr .tv_sec , gtr .tv_nsec );
760
+ DBG_PRINTF3 ("Clock resolution is %lds,%ldns!\n" , gtr .tv_sec , gtr .tv_nsec );
732
761
733
- #ifndef CLOCK_USE_UTC_TIME_NS
762
+ #ifdef OPTION_ARB_CLOCK
734
763
clock_gettime (CLOCK_TYPE , & gts0 );
735
764
#endif
736
765
clockGet ();
737
766
738
767
#ifdef DBG_LEVEL
739
- if (DBG_LEVEL >= 4 ) {
768
+ if (DBG_LEVEL >= 4 ) { // Test
740
769
uint64_t t1 , t2 ;
741
770
char s [128 ];
771
+ /*
742
772
struct timespec gts;
743
773
struct timeval ptm;
744
774
time_t now = time(NULL);
745
775
gettimeofday(&ptm, NULL);
746
776
clock_gettime(CLOCK_TYPE, >s);
747
- DBG_PRINTF4 (" CLOCK_REALTIME=%lus time=%lu timeofday=%lu\n" , gts .tv_sec , now , ptm .tv_sec );
748
- t1 = clockGet (); sleepNs (100000 ); t2 = clockGet ();
777
+ DBG_PRINTF5(" CLOCK_REALTIME=%lus time=%lu timeofday=%lu\n", gts.tv_sec, now, ptm.tv_sec);
778
+ */
779
+ t1 = clockGet (); sleepMs (1 ); t2 = clockGet ();
780
+ DBG_PRINTF4 (" +0us: %llu %s\n" , t1 , clockGetString (s , sizeof (s ), t1 ));
781
+ DBG_PRINTF4 (" +1ms: %llu %s (dt=%u)\n" , t2 , clockGetString (s , sizeof (s ), t2 ), (uint32_t )(t2 - t1 ));
782
+ t1 = clockGet (); sleepMs (100 ); t2 = clockGet ();
749
783
DBG_PRINTF4 (" +0us: %llu %s\n" , t1 , clockGetString (s , sizeof (s ), t1 ));
750
- DBG_PRINTF4 (" +100us : %llu %s (dt=%u)\n" , t2 , clockGetString (s , sizeof (s ), t2 ), (uint32_t )(t2 - t1 ));
784
+ DBG_PRINTF4 (" +100ms : %llu %s (dt=%u)\n" , t2 , clockGetString (s , sizeof (s ), t2 ), (uint32_t )(t2 - t1 ));
751
785
DBG_PRINT4 ("\n" );
752
786
}
753
787
#endif
@@ -761,7 +795,7 @@ uint64_t clockGet() {
761
795
762
796
struct timespec ts ;
763
797
clock_gettime (CLOCK_TYPE , & ts );
764
- #ifdef CLOCK_USE_UTC_TIME_NS // ns since 1.1.1970
798
+ #ifndef OPTION_ARB_CLOCK // ns since 1.1.1970
765
799
return sClock = (((uint64_t )(ts .tv_sec ) * 1000000000ULL ) + (uint64_t )(ts .tv_nsec )); // ns
766
800
#else // us since init
767
801
return sClock = (((uint64_t )(ts .tv_sec - gts0 .tv_sec ) * 1000000ULL ) + (uint64_t )(ts .tv_nsec / 1000 )); // us
@@ -772,14 +806,14 @@ uint64_t clockGet() {
772
806
773
807
// Performance counter to clock conversion
774
808
static uint64_t sFactor = 0 ; // ticks per us
775
- #ifdef CLOCK_USE_UTC_TIME_NS
809
+ #ifndef OPTION_ARB_CLOCK
776
810
static uint8_t sDivide = 0 ; // divide or multiply
777
811
#endif
778
812
static uint64_t sOffset = 0 ; // offset
779
813
780
814
char * clockGetString (char * str , uint32_t l , uint64_t c ) {
781
815
782
- #ifndef CLOCK_USE_UTC_TIME_NS
816
+ #ifdef OPTION_ARB_CLOCK
783
817
SNPRINTF (str , l , "%gs" , (double )c / CLOCK_TICKS_PER_S );
784
818
#else
785
819
uint64_t s = c / CLOCK_TICKS_PER_S ;
@@ -799,7 +833,7 @@ char* clockGetString(char* str, uint32_t l, uint64_t c) {
799
833
800
834
char * clockGetTimeString (char * str , uint32_t l , int64_t t ) {
801
835
802
- #ifndef CLOCK_USE_UTC_TIME_NS
836
+ #ifdef OPTION_ARB_CLOCK
803
837
SNPRINTF (str , l , "%gs" , (double )t /CLOCK_TICKS_PER_S );
804
838
#else
805
839
char sign = '+' ; if (t < 0 ) { sign = '-' ; t = - t ; }
@@ -815,10 +849,8 @@ char* clockGetTimeString(char* str, uint32_t l, int64_t t) {
815
849
BOOL clockInit () {
816
850
817
851
DBG_PRINT3 ("\nInit clock\n" );
818
- #ifdef CLOCK_USE_UTC_TIME_NS
819
- DBG_PRINT3 (" CLOCK_USE_UTC_TIME_NS\n" );
820
- #else
821
- DBG_PRINT3 (" CLOCK_USE_APP_TIME_US\n" );
852
+ #ifndef OPTION_ARB_CLOCK
853
+ DBG_PRINT3 (" OPTION_TAI_CLOCK\n" );
822
854
#endif
823
855
824
856
sClock = 0 ;
@@ -835,7 +867,7 @@ BOOL clockInit() {
835
867
DBG_PRINT_ERROR ("ERROR: Unexpected performance counter frequency!\n" );
836
868
return FALSE;
837
869
}
838
- #ifdef CLOCK_USE_UTC_TIME_NS
870
+ #ifndef OPTION_ARB_CLOCK
839
871
if (CLOCK_TICKS_PER_S > tF .u .LowPart ) {
840
872
sFactor = CLOCK_TICKS_PER_S / tF .u .LowPart ;
841
873
sDivide = 0 ;
@@ -849,7 +881,7 @@ BOOL clockInit() {
849
881
#endif
850
882
851
883
// Get current performance counter to absolute time relation
852
- #ifdef CLOCK_USE_UTC_TIME_NS
884
+ #ifndef OPTION_ARB_CLOCK
853
885
854
886
// Set time zone from TZ environment variable. If TZ is not set, the operating system is queried
855
887
_tzset ();
@@ -867,7 +899,7 @@ BOOL clockInit() {
867
899
// Calculate factor and offset
868
900
QueryPerformanceCounter (& tC );
869
901
tp = (((int64_t )tC .u .HighPart ) << 32 ) | (int64_t )tC .u .LowPart ;
870
- #ifdef CLOCK_USE_UTC_TIME_NS
902
+ #ifndef OPTION_ARB_CLOCK
871
903
// set offset from local clock UTC value t
872
904
// this is inaccurate up to 1 s, but irrelevant because system clock UTC offset is also not accurate
873
905
sOffset = time_s * CLOCK_TICKS_PER_S + (uint64_t )time_ms * CLOCK_TICKS_PER_MS - tp * sFactor ;
@@ -880,7 +912,7 @@ BOOL clockInit() {
880
912
881
913
#ifdef DBG_LEVEL
882
914
if (DBG_LEVEL >= 5 ) {
883
- #ifdef CLOCK_USE_UTC_TIME_NS
915
+ #ifndef OPTION_ARB_CLOCK
884
916
if (DBG_LEVEL >= 6 ) {
885
917
struct tm tm ;
886
918
_gmtime64_s (& tm , (const __time64_t * )& time_s );
@@ -915,7 +947,7 @@ uint64_t clockGet() {
915
947
916
948
QueryPerformanceCounter (& tp );
917
949
t = (((uint64_t )tp .u .HighPart ) << 32 ) | (uint64_t )tp .u .LowPart ;
918
- #ifdef CLOCK_USE_UTC_TIME_NS
950
+ #ifndef OPTION_ARB_CLOCK
919
951
if (sDivide ) {
920
952
t = t / sFactor + sOffset ;
921
953
}
0 commit comments