Changeset ca37445 for src/libcfa/time
- Timestamp:
- Apr 10, 2018, 3:31:07 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, with_gc
- Children:
- 33f5b57
- Parents:
- 9d1e3f7 (diff), 8ad6533 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/time
r9d1e3f7 rca37445 1 1 // 2 // Cforall Version 1.0.0 Copyright (C) 201 6University of Waterloo2 // Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo 3 3 // 4 4 // The contents of this file are covered under the licence agreement in the 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // calendar--7 // time -- 8 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Wed Mar 14 23:18:57 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 22 17:11:19201813 // Update Count : 49512 // Last Modified On : Mon Apr 9 13:10:23 2018 13 // Update Count : 616 14 14 // 15 15 … … 19 19 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0355r5.html#refcc 20 20 21 #include <time.h> 21 #include <time.h> // timespec 22 22 extern "C" { 23 #include <sys/time.h> 24 int snprintf( char * buf, size_t size, const char * fmt, ... ); 23 #include <sys/time.h> // timeval 25 24 } 26 #include <fstream> 27 28 enum { 29 CLOCKGRAN = 15_000_000L, // ALWAYS in nanoseconds, MUST BE less than 1 second 30 TIMEGRAN = 1_000_000_000L // nanosecond granularity, except for timeval 31 }; 32 33 34 #if defined( REALTIME_POSIX ) 35 #define tv_XSEC tv_nsec 36 #else 37 #define tv_XSEC tv_usec 38 #endif 39 40 41 #if defined( __linux__ ) 42 // fake a few things 43 #define CLOCK_REALTIME 0 // real (clock on the wall) time 44 #endif 45 46 // conversions for existing time types 25 #include <iostream> // istype/ostype 26 27 enum { TIMEGRAN = 1_000_000_000LL }; // nanosecond granularity, except for timeval 28 29 30 //######################### Duration ######################### 31 32 struct Duration { // private 33 int64_t tv; // nanoseconds 34 }; // Duration 35 36 static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; } 37 static inline void ?{}( Duration & dur, Duration d ) with( dur ) { tv = d.tv; } 38 39 static inline void ?{}( Duration & dur, zero_t ) with( dur ) { tv = 0; } 40 static inline Duration ?=?( Duration & dur, zero_t ) { return dur{ 0 }; } 41 42 static inline Duration +?( Duration rhs ) with( rhs ) { return (Duration)@{ +tv }; } 43 static inline Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv + rhs.tv }; } 44 static inline Duration ?+=?( Duration & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; } 45 46 static inline Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tv }; } 47 static inline Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; } 48 static inline Duration ?-=?( Duration & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; } 49 50 static inline Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv * rhs }; } 51 static inline Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tv }; } 52 static inline Duration ?*=?( Duration & lhs, int64_t rhs ) { lhs = lhs * rhs; return lhs; } 53 54 static inline int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tv / rhs.tv; } 55 static inline Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv / rhs }; } 56 static inline Duration ?/=?( Duration & lhs, int64_t rhs ) { lhs = lhs / rhs; return lhs; } 57 static inline double div( Duration lhs, Duration rhs ) { return (double)lhs.tv / (double)rhs.tv; } 58 59 static inline Duration ?%?( Duration lhs, Duration rhs ) { return (Duration)@{ lhs.tv % rhs.tv }; } 60 static inline Duration ?%=?( Duration & lhs, Duration rhs ) { lhs = lhs % rhs; return lhs; } 61 62 static inline _Bool ?==?( Duration lhs, Duration rhs ) { return lhs.tv == rhs.tv; } 63 static inline _Bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tv != rhs.tv; } 64 static inline _Bool ?<? ( Duration lhs, Duration rhs ) { return lhs.tv < rhs.tv; } 65 static inline _Bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tv <= rhs.tv; } 66 static inline _Bool ?>? ( Duration lhs, Duration rhs ) { return lhs.tv > rhs.tv; } 67 static inline _Bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tv >= rhs.tv; } 68 69 static inline _Bool ?==?( Duration lhs, zero_t ) { return lhs.tv == 0; } 70 static inline _Bool ?!=?( Duration lhs, zero_t ) { return lhs.tv != 0; } 71 static inline _Bool ?<? ( Duration lhs, zero_t ) { return lhs.tv < 0; } 72 static inline _Bool ?<=?( Duration lhs, zero_t ) { return lhs.tv <= 0; } 73 static inline _Bool ?>? ( Duration lhs, zero_t ) { return lhs.tv > 0; } 74 static inline _Bool ?>=?( Duration lhs, zero_t ) { return lhs.tv >= 0; } 75 76 static inline Duration abs( Duration rhs ) { return rhs.tv >= 0 ? rhs : -rhs; } 77 78 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Duration dur ); 79 80 static inline Duration ?`ns( int64_t nsec ) { return (Duration)@{ nsec }; } 81 static inline Duration ?`us( int64_t usec ) { return (Duration)@{ usec * (TIMEGRAN / 1_000_000LL) }; } 82 static inline Duration ?`ms( int64_t msec ) { return (Duration)@{ msec * (TIMEGRAN / 1_000LL) }; } 83 static inline Duration ?`s( int64_t sec ) { return (Duration)@{ sec * TIMEGRAN }; } 84 static inline Duration ?`s( double sec ) { return (Duration)@{ sec * TIMEGRAN }; } 85 static inline Duration ?`m( int64_t min ) { return (Duration)@{ min * (60LL * TIMEGRAN) }; } 86 static inline Duration ?`m( double min ) { return (Duration)@{ min * (60LL * TIMEGRAN) }; } 87 static inline Duration ?`h( int64_t hours ) { return (Duration)@{ hours * (60LL * 60LL * TIMEGRAN) }; } 88 static inline Duration ?`h( double hours ) { return (Duration)@{ hours * (60LL * 60LL * TIMEGRAN) }; } 89 static inline Duration ?`d( int64_t days ) { return (Duration)@{ days * (24LL * 60LL * 60LL * TIMEGRAN) }; } 90 static inline Duration ?`d( double days ) { return (Duration)@{ days * (24LL * 60LL * 60LL * TIMEGRAN) }; } 91 static inline Duration ?`w( int64_t weeks ) { return (Duration)@{ weeks * (7LL * 24LL * 60LL * 60LL * TIMEGRAN) }; } 92 static inline Duration ?`w( double weeks ) { return (Duration)@{ weeks * (7LL * 24LL * 60LL * 60LL * TIMEGRAN) }; } 93 94 static inline int64_t ?`ns( Duration dur ) { return dur.tv; } 95 static inline int64_t ?`us( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000_000LL); } 96 static inline int64_t ?`ms( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000LL); } 97 static inline int64_t ?`s( Duration dur ) { return dur.tv / TIMEGRAN; } 98 static inline int64_t ?`m( Duration dur ) { return dur.tv / (60LL * TIMEGRAN); } 99 static inline int64_t ?`h( Duration dur ) { return dur.tv / (60LL * 60LL * TIMEGRAN); } 100 static inline int64_t ?`d( Duration dur ) { return dur.tv / (24LL * 60LL * 60LL * TIMEGRAN); } 101 static inline int64_t ?`w( Duration dur ) { return dur.tv / (7LL * 24LL * 60LL * 60LL * TIMEGRAN); } 102 103 104 //######################### C timeval ######################### 105 47 106 static inline void ?{}( timeval & t ) {} 48 static inline void ?{}( timeval & t, time_t sec ) { t.tv_sec = sec; t.tv_usec = 0; }49 107 static inline void ?{}( timeval & t, time_t sec, suseconds_t usec ) { t.tv_sec = sec; t.tv_usec = usec; } 108 static inline void ?{}( timeval & t, time_t sec ) { t{ sec, 0 }; } 109 static inline void ?{}( timeval & t, zero_t ) { t{ 0, 0 }; } 110 static inline timeval ?=?( timeval & t, zero_t ) { return t{ 0 }; } 111 static inline timeval ?+?( timeval & lhs, timeval rhs ) { return (timeval)@{ lhs.tv_sec + rhs.tv_sec, lhs.tv_usec + rhs.tv_usec }; } 112 static inline timeval ?-?( timeval & lhs, timeval rhs ) { return (timeval)@{ lhs.tv_sec - rhs.tv_sec, lhs.tv_usec - rhs.tv_usec }; } 113 static inline _Bool ?==?( timeval lhs, timeval rhs ) { return lhs.tv_sec == rhs.tv_sec && lhs.tv_usec == rhs.tv_usec; } 114 static inline _Bool ?!=?( timeval lhs, timeval rhs ) { return lhs.tv_sec != rhs.tv_sec || lhs.tv_usec != rhs.tv_usec; } 115 116 117 //######################### C timespec ######################### 50 118 51 119 static inline void ?{}( timespec & t ) {} 52 static inline void ?{}( timespec & t, time_t sec ) { t.tv_sec = sec; t.tv_nsec = 0; }53 120 static inline void ?{}( timespec & t, time_t sec, __syscall_slong_t nsec ) { t.tv_sec = sec; t.tv_nsec = nsec; } 121 static inline void ?{}( timespec & t, time_t sec ) { t{ sec, 0}; } 122 static inline void ?{}( timespec & t, zero_t ) { t{ 0, 0 }; } 123 static inline timespec ?=?( timespec & t, zero_t ) { return t{ 0 }; } 124 static inline timespec ?+?( timespec & lhs, timespec rhs ) { return (timespec)@{ lhs.tv_sec + rhs.tv_sec, lhs.tv_nsec + rhs.tv_nsec }; } 125 static inline timespec ?-?( timespec & lhs, timespec rhs ) { return (timespec)@{ lhs.tv_sec - rhs.tv_sec, lhs.tv_nsec - rhs.tv_nsec }; } 126 static inline _Bool ?==?( timespec lhs, timespec rhs ) { return lhs.tv_sec == rhs.tv_sec && lhs.tv_nsec == rhs.tv_nsec; } 127 static inline _Bool ?!=?( timespec lhs, timespec rhs ) { return lhs.tv_sec != rhs.tv_sec || lhs.tv_nsec != rhs.tv_nsec; } 128 129 130 //######################### C itimerval ######################### 131 132 static inline void ?{}( itimerval & itv, Duration alarm ) with( itv ) { 133 // itimerval contains durations but but uses time data-structure timeval. 134 it_value{ alarm`s, (alarm % 1`s)`us }; // seconds, microseconds 135 it_interval{ 0 }; // 0 seconds, 0 microseconds 136 } // itimerval 137 138 static inline void ?{}( itimerval & itv, Duration alarm, Duration interval ) with( itv ) { 139 // itimerval contains durations but but uses time data-structure timeval. 140 it_value{ alarm`s, (alarm % 1`s)`us }; // seconds, microseconds 141 it_interval{ interval`s, interval`us }; // seconds, microseconds 142 } // itimerval 143 144 145 //######################### C time ######################### 54 146 55 147 static inline char * ctime( time_t tp ) { char * buf = ctime( &tp ); buf[24] = '\0'; return buf; } … … 61 153 62 154 63 //######################### Duration #########################64 65 struct Duration {66 int64_t tv;67 };68 69 static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; }70 static inline void ?{}( Duration & dur, Duration d ) with( dur ) { tv = d.tv; }71 72 static inline void ?{}( Duration & dur, timeval t ) with( dur ) {73 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000;74 } // Duration75 76 static inline void ?{}( Duration & dur, timespec t ) with( dur ) {77 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;78 } // Duration79 80 static inline Duration ?=?( Duration & dur, timeval t ) with( dur ) {81 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000;82 return dur;83 } // ?=?84 85 static inline Duration ?=?( Duration & dur, timespec t ) with( dur ) {86 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;87 return dur;88 } // ?=? timespec89 90 static inline void ?{}( timeval & t, Duration dur ) with( dur ) {91 t.tv_sec = tv / TIMEGRAN; // seconds92 t.tv_usec = tv % TIMEGRAN / ( TIMEGRAN / 1000000L ); // microseconds93 } // ?{}94 95 static inline void ?{}( timespec & t, Duration dur ) with( dur ) {96 t.tv_sec = tv / TIMEGRAN; // seconds97 t.tv_nsec = tv % TIMEGRAN; // nanoseconds98 } // Timespec99 100 static inline int64_t nsecs( Duration dur ) with( dur ) { return tv; }101 102 static inline Duration +?( Duration rhs ) with( rhs ) { return (Duration)@{ +tv }; }103 static inline Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv + rhs.tv }; }104 static inline Duration ?+=?( Duration & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; }105 106 static inline Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tv }; }107 static inline Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; }108 static inline Duration ?-=?( Duration & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; }109 110 static inline Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv * rhs }; }111 static inline Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tv }; }112 static inline Duration ?*=?( Duration & lhs, int64_t rhs ) { lhs = lhs * rhs; return lhs; }113 114 static inline Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv / rhs }; }115 static inline int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tv / rhs.tv; }116 static inline Duration ?/=?( Duration & lhs, int64_t rhs ) { lhs = lhs / rhs; return lhs; }117 118 static inline Duration ?%?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv % rhs }; }119 static inline int64_t ?%?( int64_t lhs, Duration rhs ) { return lhs % (rhs.tv / TIMEGRAN); }120 static inline int64_t ?%?( Duration lhs, Duration rhs ) { return lhs.tv % rhs.tv; }121 122 static inline _Bool ?==?( Duration lhs, Duration rhs ) { return lhs.tv == rhs.tv; }123 static inline _Bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tv != rhs.tv; }124 static inline _Bool ?<?( Duration lhs, Duration rhs ) { return lhs.tv < rhs.tv; }125 static inline _Bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tv <= rhs.tv; }126 static inline _Bool ?>?( Duration lhs, Duration rhs ) { return lhs.tv > rhs.tv; }127 static inline _Bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tv >= rhs.tv; }128 129 static inline Duration abs( Duration lhs ) {130 return lhs.tv >= 0 ? lhs : -lhs;131 } // abs132 133 static inline forall( dtype ostype | ostream( ostype ) )134 ostype & ?|?( ostype & os, Duration dur ) with( dur ) {135 os | tv / TIMEGRAN;136 char buf[16];137 snprintf( buf, 16, "%09ld", ((tv < 0 ? -tv : tv) % TIMEGRAN) );138 int i;139 for ( i = 8; i >= 0 && buf[i] == '0' ; i -= 1 ); // find least significant digit140 if ( i != -1 ) { buf[i + 1] = '\0'; os | '.' | buf; }141 return os;142 }143 144 static inline Duration ?`ns( int64_t nsec ) { return (Duration)@{ nsec }; }145 static inline Duration ?`us( int64_t usec ) { return (Duration)@{ usec * (TIMEGRAN / 1_000l) }; }146 static inline Duration ?`ms( int64_t msec ) { return (Duration)@{ msec * (TIMEGRAN / 1_000_000l) }; }147 static inline Duration ?`s ( int64_t sec ) { return (Duration)@{ sec * TIMEGRAN }; }148 static inline Duration ?`s ( double sec ) { return (Duration)@{ sec * TIMEGRAN }; }149 static inline Duration ?`m ( int64_t min ) { return (Duration)@{ min * (60L * TIMEGRAN) }; }150 static inline Duration ?`m ( double min ) { return (Duration)@{ min * (60L * TIMEGRAN) }; }151 static inline Duration ?`h ( int64_t hours ) { return (Duration)@{ hours * (3600L * TIMEGRAN) }; }152 static inline Duration ?`h ( double hours ) { return (Duration)@{ hours * (3600L * TIMEGRAN) }; }153 static inline Duration ?`d ( int64_t days ) { return (Duration)@{ days * (24L * 3600L * TIMEGRAN) }; }154 static inline Duration ?`d ( double days ) { return (Duration)@{ days * (24L * 3600L * TIMEGRAN) }; }155 static inline Duration ?`w ( int64_t weeks ) { return (Duration)@{ weeks * (7L * 24L * 3600L * TIMEGRAN) }; }156 static inline Duration ?`f ( int64_t fortnight ) { return (Duration)@{ fortnight * (14L * 24L * 3600L * TIMEGRAN) }; }157 158 static inline int64_t ?`s ( Duration dur ) { return dur.tv / TIMEGRAN; }159 static inline int64_t ?`m ( Duration dur ) { return dur.tv / (60L * TIMEGRAN); }160 static inline int64_t ?`h ( Duration dur ) { return dur.tv / (3600L * TIMEGRAN); }161 static inline int64_t ?`d ( Duration dur ) { return dur.tv / (24L * 3600L * TIMEGRAN); }162 static inline int64_t ?`w ( Duration dur ) { return dur.tv / (7L * 24L * 3600L * TIMEGRAN); }163 static inline int64_t ?`f ( Duration dur ) { return dur.tv / (14L * 24L * 3600L * TIMEGRAN); }164 165 166 155 //######################### Time ######################### 167 156 168 169 struct Time { 170 uint64_t tv; 171 }; 172 173 #ifdef __CFA_DEBUG__ 174 #define CreateFmt "Attempt to create Time( year=%d, month=%d, day=%d, hour=%d, min=%d, sec=%d, nsec=%d ), " \ 175 "which exceeds range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038." 176 #endif // __CFA_DEBUG__ 177 178 void mktime( Time & time, int year, int month, int day, int hour, int min, int sec, int nsec ) with( time ) { 179 tm tm; 180 181 // tzset(); // initialize time global variables 182 tm.tm_isdst = -1; // let mktime determine if alternate timezone is in effect 183 tm.tm_year = year - 1900; // mktime uses 1900 as its starting point 184 tm.tm_mon = month - 1; 185 tm.tm_mday = day; // mktime uses range 1-31 186 tm.tm_hour = hour; 187 tm.tm_min = min; 188 tm.tm_sec = sec; 189 time_t epochsec = mktime( &tm ); 190 #ifdef __CFA_DEBUG__ 191 if ( epochsec == (time_t)-1 ) { 192 abort( CreateFmt, year, month, day, hour, min, sec, nsec ); 193 } // if 194 #endif // __CFA_DEBUG__ 195 tv = (int64_t)(epochsec) * TIMEGRAN + nsec; // convert to nanoseconds 196 #ifdef __CFA_DEBUG__ 197 if ( tv > 2147483647LL * TIMEGRAN ) { // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038. 198 abort( CreateFmt, year, month, day, hour, min, sec, nsec ); 199 } // if 200 #endif // __CFA_DEBUG__ 201 } // mktime 202 203 static inline void ?{}( Time & t ) with( t ) { 204 tv = 0; 205 } // Time 206 207 // These two constructors must not call mktime because it calls malloc. The malloc calls lead to recursion problems 208 // because Time values are created from the sigalrm handler in composing the next context switch event. 209 210 static inline void ?{}( Time & t, int sec ) with( t ) { 211 #ifdef __CFA_DEBUG__ 212 if ( tv < 0 || tv > 2147483647LL ) { // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038. 213 abort( CreateFmt, 1970, 0, 0, 0, 0, sec, 0 ); 214 } // if 215 #endif // __CFA_DEBUG__ 216 tv = (int64_t)sec * TIMEGRAN; 217 } // Time 218 219 static inline void ?{}( Time & t, int sec, int nsec ) with( t ) { 220 #ifdef __U_DEBUG__ 221 if ( tv < 0 || tv > 2147483647LL || nsec < 0 ) { // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038. 222 abort( CreateFmt, 1970, 0, 0, 0, 0, sec, nsec ); 223 } // if 224 #endif // __U_DEBUG__ 225 tv = (int64_t)sec * TIMEGRAN + nsec; 226 } // Time 227 228 static inline void ?{}( Time & time, int min, int sec, long int nsec ) { 229 mktime( time, 1970, 1, 1, 0, min, sec, nsec ); 230 } // Time 231 232 static inline void ?{}( Time & time, int hour, int min, int sec, long int nsec ) { 233 mktime( time, 1970, 1, 1, hour, min, sec, nsec ); 234 } // Time 235 236 static inline void ?{}( Time & time, int day, int hour, int min, int sec, long int nsec ) { 237 mktime( time, 1970, 1, day, hour, min, sec, nsec ); 238 } // Time 239 240 static inline void ?{}( Time & time, int month, int day, int hour, int min, int sec, long int nsec ) { 241 mktime( time, 1970, month, day, hour, min, sec, nsec ); 242 } // Time 243 244 static inline void ?{}( Time & time, int year, int month, int day, int hour, int min, int sec, long int nsec ) { 245 mktime( time, year, month, day, hour, min, sec, nsec ); 246 } // Time 157 struct Time { // private 158 uint64_t tv; // nanoseconds since UNIX epoch 159 }; // Time 160 161 static inline void ?{}( Time & t ) with( t ) { tv = 0; } // fast 162 void ?{}( Time & time, int year, int month = 0, int day = 0, int hour = 0, int min = 0, int sec = 0, int nsec = 0 ); // slow 163 164 static inline void ?{}( Time & t, zero_t ) { t.tv = 0; } 165 static inline Time ?=?( Time & t, zero_t ) { return t{ 0 }; } 247 166 248 167 static inline void ?{}( Time & time, timeval t ) with( time ) { … … 250 169 } // Time 251 170 171 static inline Time ?=?( Time & time, timeval t ) with( time ) { 172 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * (TIMEGRAN / 1_000_000LL); 173 return time; 174 } // ?=? 175 252 176 static inline void ?{}( Time & time, timespec t ) with( time ) { 253 177 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec; 254 178 } // Time 255 256 static inline Time ?=?( Time & time, timeval t ) with( time ) {257 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000;258 return time;259 } // ?=?260 179 261 180 static inline Time ?=?( Time & time, timespec t ) with( time ) { … … 263 182 return time; 264 183 } // ?=? 265 266 static inline void ?{}( timeval & t, Time time ) with( time ) {267 t.tv_sec = tv / TIMEGRAN; // seconds268 t.tv_usec = tv % TIMEGRAN / ( TIMEGRAN / 1_000_000L ); // microseconds269 } // ?{}270 271 static inline void ?{}( timespec & t, Time time ) with( time ) {272 t.tv_sec = tv / TIMEGRAN; // seconds273 t.tv_nsec = tv % TIMEGRAN; // nanoseconds274 } // ?{}275 276 static inline int64_t nsec( Time time ) with( time ) { return tv; }277 184 278 185 static inline Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tv + rhs.tv }; } … … 290 197 static inline _Bool ?>=?( Time lhs, Time rhs ) { return lhs.tv >= rhs.tv; } 291 198 292 static inline char * yymmd( Time time, char * buf ) with( time ) { 293 tm tm; 294 time_t s = tv / TIMEGRAN; 295 gmtime_r( &s, &tm ); 296 snprintf( buf, 9, "%02d/%02d/%02d", tm.tm_year % 99, tm.tm_mon, tm.tm_mday ); 297 return buf; 298 } // yymmd 299 300 static inline char * mmyyd( Time time, char * buf ) with( time ) { 301 tm tm; 302 time_t s = tv / TIMEGRAN; 303 gmtime_r( &s, &tm ); 304 snprintf( buf, 9, "%02d/%02d/%02d", tm.tm_mon, tm.tm_year % 99, tm.tm_mday ); 305 return buf; 306 } // yymmd 307 308 static inline char * dmmyy( Time time, char * buf ) with( time ) { 309 tm tm; 310 time_t s = tv / TIMEGRAN; 311 gmtime_r( &s, &tm ); 312 snprintf( buf, 9, "%02d/%02d/%02d", tm.tm_mday, tm.tm_mon, tm.tm_year % 99 ); 313 return buf; 314 } // yymmd 315 316 static inline forall( dtype ostype | ostream( ostype ) ) 317 ostype & ?|?( ostype & os, Time time ) with( time ) { 318 char buf[32]; // at least 26 319 time_t s = tv / TIMEGRAN; 320 tm tm; 321 gmtime_r( &s, &tm ); // ctime_r adjusts for timezone 322 asctime_r( &tm, (char *)&buf ); 323 buf[24] = '\0'; // remove trailing '\n' 324 long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN; 325 if ( ns == 0 ) { 326 os | buf; 327 } else { 328 buf[19] = '\0'; 329 os | buf; 330 char buf2[16]; 331 snprintf( buf2, 16, "%09ld", ns ); 332 int i; 333 for ( i = 8; i >= 0 && buf2[i] == '0' ; i -= 1 ); // find least significant digit 334 if ( i != -1 ) { buf2[i + 1] = '\0'; os | '.' | buf2; } 335 os | ' ' | &buf[20]; 336 } // if 337 return os; 338 } // ?|? 199 char * yy_mm_dd( Time time, char * buf ); 200 static inline char * ?`ymd( Time time, char * buf ) { // short form 201 return yy_mm_dd( time, buf ); 202 } // ymd 203 204 char * mm_dd_yy( Time time, char * buf ); 205 static inline char * ?`mdy( Time time, char * buf ) { // short form 206 return mm_dd_yy( time, buf ); 207 } // mdy 208 209 char * dd_mm_yy( Time time, char * buf ); 210 static inline char * ?`dmy( Time time, char * buf ) { // short form 211 return dd_mm_yy( time, buf );; 212 } // dmy 213 214 size_t strftime( char * buf, size_t size, const char * fmt, Time time ); 215 216 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time ); 217 218 //------------------------- timeval (cont) ------------------------- 219 220 static inline void ?{}( timeval & t, Time time ) with( t, time ) { 221 tv_sec = tv / TIMEGRAN; // seconds 222 tv_usec = tv % TIMEGRAN / (TIMEGRAN / 1_000_000LL); // microseconds 223 } // ?{} 224 225 //------------------------- timespec (cont) ------------------------- 226 227 static inline void ?{}( timespec & t, Time time ) with( t, time ) { 228 tv_sec = tv / TIMEGRAN; // seconds 229 tv_nsec = tv % TIMEGRAN; // nanoseconds 230 } // ?{} 231 339 232 340 233 //######################### Clock ######################### 341 234 342 343 struct Clock { 235 struct Clock { // private 344 236 Duration offset; // for virtual clock: contains offset from real-time 345 237 int clocktype; // implementation only -1 (virtual), CLOCK_REALTIME 346 238 }; 347 239 348 void resetClock( Clock & clk ) with( clk ) {349 clocktype = CLOCK_REALTIME ;240 static inline void resetClock( Clock & clk ) with( clk ) { 241 clocktype = CLOCK_REALTIME_COARSE; 350 242 } // Clock::resetClock 351 243 352 void resetClock( Clock & clk, Duration adj ) with( clk ) {244 static inline void resetClock( Clock & clk, Duration adj ) with( clk ) { 353 245 clocktype = -1; 354 Duration tz = (timeval){ timezone, 0 }; 355 offset = adj + tz; 246 offset = adj + timezone`s; // timezone (global) is (UTC - local time) in seconds 356 247 } // resetClock 357 248 358 void ?{}( Clock & clk ) {249 static inline void ?{}( Clock & clk ) { 359 250 resetClock( clk ); 360 251 } // Clock 361 252 362 void ?{}( Clock & clk, Duration adj ) {253 static inline void ?{}( Clock & clk, Duration adj ) { 363 254 resetClock( clk, adj ); 364 255 } // Clock 365 256 366 Duration getRes() {257 static inline Duration getRes() { 367 258 struct timespec res; 368 clock_getres( CLOCK_REALTIME , &res );369 return ( Duration){ res };259 clock_getres( CLOCK_REALTIME_COARSE, &res ); 260 return ((int64_t)res.tv_sec * TIMEGRAN + res.tv_nsec)`ns; 370 261 } // getRes 371 262 372 Time getTime() { 263 static inline Time getTimeNsec() { // with nanoseconds 373 264 timespec curr; 374 265 clock_gettime( CLOCK_REALTIME_COARSE, &curr ); … … 376 267 } // getTime 377 268 378 Time getTime( Clock & clk ) with( clk ) { 269 static inline Time getTime() { // without nanoseconds 270 timespec curr; 271 clock_gettime( CLOCK_REALTIME_COARSE, &curr ); 272 curr.tv_nsec = 0; 273 return (Time){ curr }; 274 } // getTime 275 276 static inline Time getTime( Clock & clk ) with( clk ) { 379 277 return getTime() + offset; 380 278 } // getTime 381 279 382 Time ?()( Clock & clk ) with( clk ) {// alternative syntax280 static inline Time ?()( Clock & clk ) with( clk ) { // alternative syntax 383 281 return getTime() + offset; 384 282 } // getTime 385 283 386 timeval getTime( Clock & clk ) {284 static inline timeval getTime( Clock & clk ) { 387 285 return (timeval){ clk() }; 388 286 } // getTime 389 287 390 tm getTime( Clock & clk ) with( clk ) {288 static inline tm getTime( Clock & clk ) with( clk ) { 391 289 tm ret; 392 290 localtime_r( getTime( clk ).tv_sec, &ret ); … … 398 296 // tab-width: 4 // 399 297 // End: // 400
Note:
See TracChangeset
for help on using the changeset viewer.