time.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2001-2013, 2018 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file util/time.c
  18. * @author Christian Grothoff
  19. * @brief functions for handling time and time arithmetic
  20. */
  21. #include "platform.h"
  22. #include "gnunet_util_lib.h"
  23. #if __STDC_NO_ATOMICS__
  24. #define ATOMIC
  25. #else
  26. #ifdef HAVE_STDATOMIC_H
  27. #include <stdatomic.h>
  28. #define ATOMIC _Atomic
  29. #else
  30. #define __STDC_NO_ATOMICS__ 1
  31. #define ATOMIC
  32. #endif
  33. #endif
  34. #define LOG(kind, ...) GNUNET_log_from (kind, "util-time", __VA_ARGS__)
  35. /**
  36. * Variable used to simulate clock skew. Used for testing, never in production.
  37. */
  38. static long long timestamp_offset;
  39. /**
  40. * Set the timestamp offset for this instance.
  41. *
  42. * @param offset the offset to skew the locale time by
  43. */
  44. void
  45. GNUNET_TIME_set_offset (long long offset)
  46. {
  47. timestamp_offset = offset;
  48. }
  49. /**
  50. * Get the timestamp offset for this instance.
  51. *
  52. * @return the offset we currently skew the locale time by
  53. */
  54. long long
  55. GNUNET_TIME_get_offset ()
  56. {
  57. return timestamp_offset;
  58. }
  59. /**
  60. * Round a time value so that it is suitable for transmission
  61. * via JSON encodings.
  62. *
  63. * @param at time to round
  64. * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
  65. * it was just now rounded
  66. */
  67. int
  68. GNUNET_TIME_round_abs (struct GNUNET_TIME_Absolute *at)
  69. {
  70. if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
  71. return GNUNET_OK;
  72. if (0 == at->abs_value_us % 1000000)
  73. return GNUNET_OK;
  74. at->abs_value_us -= at->abs_value_us % 1000000;
  75. return GNUNET_NO;
  76. }
  77. /**
  78. * Round a time value so that it is suitable for transmission
  79. * via JSON encodings.
  80. *
  81. * @param rt time to round
  82. * @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
  83. * it was just now rounded
  84. */
  85. int
  86. GNUNET_TIME_round_rel (struct GNUNET_TIME_Relative *rt)
  87. {
  88. if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
  89. return GNUNET_OK;
  90. if (0 == rt->rel_value_us % 1000000)
  91. return GNUNET_OK;
  92. rt->rel_value_us -= rt->rel_value_us % 1000000;
  93. return GNUNET_NO;
  94. }
  95. /**
  96. * Get the current time (works just as "time", just that we use the
  97. * unit of time that the cron-jobs use (and is 64 bit)).
  98. *
  99. * @return the current time
  100. */
  101. struct GNUNET_TIME_Absolute
  102. GNUNET_TIME_absolute_get ()
  103. {
  104. struct GNUNET_TIME_Absolute ret;
  105. struct timeval tv;
  106. gettimeofday (&tv, NULL);
  107. ret.abs_value_us = (uint64_t) (((uint64_t) tv.tv_sec * 1000LL * 1000LL)
  108. + ((uint64_t) tv.tv_usec))
  109. + timestamp_offset;
  110. return ret;
  111. }
  112. /**
  113. * Return relative time of 0ms.
  114. */
  115. struct GNUNET_TIME_Relative
  116. GNUNET_TIME_relative_get_zero_ ()
  117. {
  118. static struct GNUNET_TIME_Relative zero;
  119. return zero;
  120. }
  121. /**
  122. * Return absolute time of 0ms.
  123. */
  124. struct GNUNET_TIME_Absolute
  125. GNUNET_TIME_absolute_get_zero_ ()
  126. {
  127. static struct GNUNET_TIME_Absolute zero;
  128. return zero;
  129. }
  130. /**
  131. * Return relative time of 1us.
  132. */
  133. struct GNUNET_TIME_Relative
  134. GNUNET_TIME_relative_get_unit_ ()
  135. {
  136. static struct GNUNET_TIME_Relative one = { 1 };
  137. return one;
  138. }
  139. /**
  140. * Return relative time of 1ms.
  141. */
  142. struct GNUNET_TIME_Relative
  143. GNUNET_TIME_relative_get_millisecond_ ()
  144. {
  145. static struct GNUNET_TIME_Relative one = { 1000 };
  146. return one;
  147. }
  148. /**
  149. * Return relative time of 1s.
  150. */
  151. struct GNUNET_TIME_Relative
  152. GNUNET_TIME_relative_get_second_ ()
  153. {
  154. static struct GNUNET_TIME_Relative one = { 1000 * 1000LL };
  155. return one;
  156. }
  157. /**
  158. * Return relative time of 1 minute.
  159. */
  160. struct GNUNET_TIME_Relative
  161. GNUNET_TIME_relative_get_minute_ ()
  162. {
  163. static struct GNUNET_TIME_Relative one = { 60 * 1000 * 1000LL };
  164. return one;
  165. }
  166. /**
  167. * Return relative time of 1 hour.
  168. */
  169. struct GNUNET_TIME_Relative
  170. GNUNET_TIME_relative_get_hour_ ()
  171. {
  172. static struct GNUNET_TIME_Relative one = { 60 * 60 * 1000 * 1000LL };
  173. return one;
  174. }
  175. /**
  176. * Return "forever".
  177. */
  178. struct GNUNET_TIME_Relative
  179. GNUNET_TIME_relative_get_forever_ ()
  180. {
  181. static struct GNUNET_TIME_Relative forever = { UINT64_MAX };
  182. return forever;
  183. }
  184. /**
  185. * Return "forever".
  186. */
  187. struct GNUNET_TIME_Absolute
  188. GNUNET_TIME_absolute_get_forever_ ()
  189. {
  190. static struct GNUNET_TIME_Absolute forever = { UINT64_MAX };
  191. return forever;
  192. }
  193. /**
  194. * Convert relative time to an absolute time in the
  195. * future.
  196. *
  197. * @return timestamp that is "rel" in the future, or FOREVER if rel==FOREVER (or if we would overflow)
  198. */
  199. struct GNUNET_TIME_Absolute
  200. GNUNET_TIME_relative_to_absolute (struct GNUNET_TIME_Relative rel)
  201. {
  202. struct GNUNET_TIME_Absolute ret;
  203. if (rel.rel_value_us == UINT64_MAX)
  204. return GNUNET_TIME_UNIT_FOREVER_ABS;
  205. struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
  206. if (rel.rel_value_us + now.abs_value_us < rel.rel_value_us)
  207. {
  208. GNUNET_break (0); /* overflow... */
  209. return GNUNET_TIME_UNIT_FOREVER_ABS;
  210. }
  211. ret.abs_value_us = rel.rel_value_us + now.abs_value_us;
  212. return ret;
  213. }
  214. /**
  215. * Return the minimum of two relative time values.
  216. *
  217. * @param t1 first timestamp
  218. * @param t2 other timestamp
  219. * @return timestamp that is smaller
  220. */
  221. struct GNUNET_TIME_Relative
  222. GNUNET_TIME_relative_min (struct GNUNET_TIME_Relative t1,
  223. struct GNUNET_TIME_Relative t2)
  224. {
  225. return (t1.rel_value_us < t2.rel_value_us) ? t1 : t2;
  226. }
  227. /**
  228. * Return the maximum of two relative time values.
  229. *
  230. * @param t1 first timestamp
  231. * @param t2 other timestamp
  232. * @return timestamp that is larger
  233. */
  234. struct GNUNET_TIME_Relative
  235. GNUNET_TIME_relative_max (struct GNUNET_TIME_Relative t1,
  236. struct GNUNET_TIME_Relative t2)
  237. {
  238. return (t1.rel_value_us > t2.rel_value_us) ? t1 : t2;
  239. }
  240. /**
  241. * Return the minimum of two relative time values.
  242. *
  243. * @param t1 first timestamp
  244. * @param t2 other timestamp
  245. * @return timestamp that is smaller
  246. */
  247. struct GNUNET_TIME_Absolute
  248. GNUNET_TIME_absolute_min (struct GNUNET_TIME_Absolute t1,
  249. struct GNUNET_TIME_Absolute t2)
  250. {
  251. return (t1.abs_value_us < t2.abs_value_us) ? t1 : t2;
  252. }
  253. /**
  254. * Return the maximum of two relative time values.
  255. *
  256. * @param t1 first timestamp
  257. * @param t2 other timestamp
  258. * @return timestamp that is bigger
  259. */
  260. struct GNUNET_TIME_Absolute
  261. GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1,
  262. struct GNUNET_TIME_Absolute t2)
  263. {
  264. return (t1.abs_value_us > t2.abs_value_us) ? t1 : t2;
  265. }
  266. /**
  267. * Given a timestamp in the future, how much time
  268. * remains until then?
  269. *
  270. * @return future - now, or 0 if now >= future, or FOREVER if future==FOREVER.
  271. */
  272. struct GNUNET_TIME_Relative
  273. GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future)
  274. {
  275. struct GNUNET_TIME_Relative ret;
  276. if (future.abs_value_us == UINT64_MAX)
  277. return GNUNET_TIME_UNIT_FOREVER_REL;
  278. struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
  279. if (now.abs_value_us > future.abs_value_us)
  280. return GNUNET_TIME_UNIT_ZERO;
  281. ret.rel_value_us = future.abs_value_us - now.abs_value_us;
  282. return ret;
  283. }
  284. /**
  285. * Compute the time difference between the given start and end times.
  286. * Use this function instead of actual subtraction to ensure that
  287. * "FOREVER" and overflows are handled correctly.
  288. *
  289. * @return 0 if start >= end; FOREVER if end==FOREVER; otherwise end - start
  290. */
  291. struct GNUNET_TIME_Relative
  292. GNUNET_TIME_absolute_get_difference (struct GNUNET_TIME_Absolute start,
  293. struct GNUNET_TIME_Absolute end)
  294. {
  295. struct GNUNET_TIME_Relative ret;
  296. if (end.abs_value_us == UINT64_MAX)
  297. return GNUNET_TIME_UNIT_FOREVER_REL;
  298. if (end.abs_value_us < start.abs_value_us)
  299. return GNUNET_TIME_UNIT_ZERO;
  300. ret.rel_value_us = end.abs_value_us - start.abs_value_us;
  301. return ret;
  302. }
  303. /**
  304. * Get the duration of an operation as the
  305. * difference of the current time and the given start time "whence".
  306. *
  307. * @return 0 if whence > now, otherwise now-whence.
  308. */
  309. struct GNUNET_TIME_Relative
  310. GNUNET_TIME_absolute_get_duration (struct GNUNET_TIME_Absolute whence)
  311. {
  312. struct GNUNET_TIME_Absolute now;
  313. struct GNUNET_TIME_Relative ret;
  314. now = GNUNET_TIME_absolute_get ();
  315. if (whence.abs_value_us > now.abs_value_us)
  316. return GNUNET_TIME_UNIT_ZERO;
  317. ret.rel_value_us = now.abs_value_us - whence.abs_value_us;
  318. return ret;
  319. }
  320. /**
  321. * Add a given relative duration to the
  322. * given start time.
  323. *
  324. * @return FOREVER if either argument is FOREVER or on overflow; start+duration otherwise
  325. */
  326. struct GNUNET_TIME_Absolute
  327. GNUNET_TIME_absolute_add (struct GNUNET_TIME_Absolute start,
  328. struct GNUNET_TIME_Relative duration)
  329. {
  330. struct GNUNET_TIME_Absolute ret;
  331. if ((start.abs_value_us == UINT64_MAX) ||
  332. (duration.rel_value_us == UINT64_MAX))
  333. return GNUNET_TIME_UNIT_FOREVER_ABS;
  334. if (start.abs_value_us + duration.rel_value_us < start.abs_value_us)
  335. {
  336. GNUNET_break (0);
  337. return GNUNET_TIME_UNIT_FOREVER_ABS;
  338. }
  339. ret.abs_value_us = start.abs_value_us + duration.rel_value_us;
  340. return ret;
  341. }
  342. /**
  343. * Subtract a given relative duration from the
  344. * given start time.
  345. *
  346. * @param start some absolute time
  347. * @param duration some relative time to subtract
  348. * @return ZERO if start <= duration, or FOREVER if start time is FOREVER; start-duration otherwise
  349. */
  350. struct GNUNET_TIME_Absolute
  351. GNUNET_TIME_absolute_subtract (struct GNUNET_TIME_Absolute start,
  352. struct GNUNET_TIME_Relative duration)
  353. {
  354. struct GNUNET_TIME_Absolute ret;
  355. if (start.abs_value_us <= duration.rel_value_us)
  356. return GNUNET_TIME_UNIT_ZERO_ABS;
  357. if (start.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
  358. return GNUNET_TIME_UNIT_FOREVER_ABS;
  359. ret.abs_value_us = start.abs_value_us - duration.rel_value_us;
  360. return ret;
  361. }
  362. /**
  363. * Multiply relative time by a given factor.
  364. *
  365. * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
  366. */
  367. struct GNUNET_TIME_Relative
  368. GNUNET_TIME_relative_multiply (struct GNUNET_TIME_Relative rel,
  369. unsigned long long factor)
  370. {
  371. struct GNUNET_TIME_Relative ret;
  372. if (0 == factor)
  373. return GNUNET_TIME_UNIT_ZERO;
  374. if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
  375. return GNUNET_TIME_UNIT_FOREVER_REL;
  376. ret.rel_value_us = rel.rel_value_us * factor;
  377. if (ret.rel_value_us / factor != rel.rel_value_us)
  378. {
  379. GNUNET_break (0);
  380. return GNUNET_TIME_UNIT_FOREVER_REL;
  381. }
  382. return ret;
  383. }
  384. /**
  385. * Multiply relative time by a given floating-point factor. The factor must be
  386. * positive.
  387. *
  388. * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
  389. */
  390. struct GNUNET_TIME_Relative
  391. relative_multiply_double (struct GNUNET_TIME_Relative rel, double factor)
  392. {
  393. struct GNUNET_TIME_Relative out;
  394. double m;
  395. GNUNET_assert (0 <= factor);
  396. if (0 == factor)
  397. return GNUNET_TIME_UNIT_ZERO;
  398. if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
  399. return GNUNET_TIME_UNIT_FOREVER_REL;
  400. m = ((double) rel.rel_value_us) * factor;
  401. if (m >= (double) (GNUNET_TIME_UNIT_FOREVER_REL).rel_value_us)
  402. {
  403. GNUNET_break (0);
  404. return GNUNET_TIME_UNIT_FOREVER_REL;
  405. }
  406. out.rel_value_us = (uint64_t) m;
  407. return out;
  408. }
  409. /**
  410. * Saturating multiply relative time by a given factor.
  411. *
  412. * @param rel some duration
  413. * @param factor integer to multiply with
  414. * @return FOREVER if rel=FOREVER or on overflow; otherwise rel*factor
  415. */
  416. struct GNUNET_TIME_Relative
  417. GNUNET_TIME_relative_saturating_multiply (struct GNUNET_TIME_Relative rel,
  418. unsigned long long factor)
  419. {
  420. struct GNUNET_TIME_Relative ret;
  421. if (0 == factor)
  422. return GNUNET_TIME_UNIT_ZERO;
  423. if (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
  424. return GNUNET_TIME_UNIT_FOREVER_REL;
  425. ret.rel_value_us = rel.rel_value_us * factor;
  426. if (ret.rel_value_us / factor != rel.rel_value_us)
  427. {
  428. return GNUNET_TIME_UNIT_FOREVER_REL;
  429. }
  430. return ret;
  431. }
  432. /**
  433. * Divide relative time by a given factor.
  434. *
  435. * @param rel some duration
  436. * @param factor integer to divide by
  437. * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
  438. */
  439. struct GNUNET_TIME_Relative
  440. GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
  441. unsigned long long factor)
  442. {
  443. struct GNUNET_TIME_Relative ret;
  444. if ((0 == factor) ||
  445. (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
  446. return GNUNET_TIME_UNIT_FOREVER_REL;
  447. ret.rel_value_us = rel.rel_value_us / factor;
  448. return ret;
  449. }
  450. /**
  451. * Calculate the estimate time of arrival/completion
  452. * for an operation.
  453. *
  454. * @param start when did the operation start?
  455. * @param finished how much has been done?
  456. * @param total how much must be done overall (same unit as for "finished")
  457. * @return remaining duration for the operation,
  458. * assuming it continues at the same speed
  459. */
  460. struct GNUNET_TIME_Relative
  461. GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start,
  462. uint64_t finished,
  463. uint64_t total)
  464. {
  465. struct GNUNET_TIME_Relative due;
  466. double exp;
  467. struct GNUNET_TIME_Relative ret;
  468. GNUNET_break (finished <= total);
  469. if (finished >= total)
  470. return GNUNET_TIME_UNIT_ZERO;
  471. if (0 == finished)
  472. return GNUNET_TIME_UNIT_FOREVER_REL;
  473. due = GNUNET_TIME_absolute_get_duration (start);
  474. exp = ((double) due.rel_value_us) * ((double) total) / ((double) finished);
  475. ret.rel_value_us = ((uint64_t) exp) - due.rel_value_us;
  476. return ret;
  477. }
  478. /**
  479. * Add relative times together.
  480. *
  481. * @param a1 first timestamp
  482. * @param a2 second timestamp
  483. * @return FOREVER if either argument is FOREVER or on overflow; a1+a2 otherwise
  484. */
  485. struct GNUNET_TIME_Relative
  486. GNUNET_TIME_relative_add (struct GNUNET_TIME_Relative a1,
  487. struct GNUNET_TIME_Relative a2)
  488. {
  489. struct GNUNET_TIME_Relative ret;
  490. if ((a1.rel_value_us == UINT64_MAX) || (a2.rel_value_us == UINT64_MAX))
  491. return GNUNET_TIME_UNIT_FOREVER_REL;
  492. if (a1.rel_value_us + a2.rel_value_us < a1.rel_value_us)
  493. {
  494. GNUNET_break (0);
  495. return GNUNET_TIME_UNIT_FOREVER_REL;
  496. }
  497. ret.rel_value_us = a1.rel_value_us + a2.rel_value_us;
  498. return ret;
  499. }
  500. /**
  501. * Subtract relative timestamp from the other.
  502. *
  503. * @param a1 first timestamp
  504. * @param a2 second timestamp
  505. * @return ZERO if a2>=a1 (including both FOREVER), FOREVER if a1 is FOREVER, a1-a2 otherwise
  506. */
  507. struct GNUNET_TIME_Relative
  508. GNUNET_TIME_relative_subtract (struct GNUNET_TIME_Relative a1,
  509. struct GNUNET_TIME_Relative a2)
  510. {
  511. struct GNUNET_TIME_Relative ret;
  512. if (a2.rel_value_us >= a1.rel_value_us)
  513. return GNUNET_TIME_UNIT_ZERO;
  514. if (a1.rel_value_us == UINT64_MAX)
  515. return GNUNET_TIME_UNIT_FOREVER_REL;
  516. ret.rel_value_us = a1.rel_value_us - a2.rel_value_us;
  517. return ret;
  518. }
  519. /**
  520. * Convert relative time to network byte order.
  521. *
  522. * @param a time to convert
  523. * @return time in network byte order
  524. */
  525. struct GNUNET_TIME_RelativeNBO
  526. GNUNET_TIME_relative_hton (struct GNUNET_TIME_Relative a)
  527. {
  528. struct GNUNET_TIME_RelativeNBO ret;
  529. ret.rel_value_us__ = GNUNET_htonll (a.rel_value_us);
  530. return ret;
  531. }
  532. /**
  533. * Convert relative time from network byte order.
  534. *
  535. * @param a time to convert
  536. * @return time in host byte order
  537. */
  538. struct GNUNET_TIME_Relative
  539. GNUNET_TIME_relative_ntoh (struct GNUNET_TIME_RelativeNBO a)
  540. {
  541. struct GNUNET_TIME_Relative ret;
  542. ret.rel_value_us = GNUNET_ntohll (a.rel_value_us__);
  543. return ret;
  544. }
  545. /**
  546. * Convert absolute time to network byte order.
  547. *
  548. * @param a time to convert
  549. * @return time in network byte order
  550. */
  551. struct GNUNET_TIME_AbsoluteNBO
  552. GNUNET_TIME_absolute_hton (struct GNUNET_TIME_Absolute a)
  553. {
  554. struct GNUNET_TIME_AbsoluteNBO ret;
  555. ret.abs_value_us__ = GNUNET_htonll (a.abs_value_us);
  556. return ret;
  557. }
  558. /**
  559. * Convert absolute time from network byte order.
  560. *
  561. * @param a time to convert
  562. * @return time in host byte order
  563. */
  564. struct GNUNET_TIME_Absolute
  565. GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
  566. {
  567. struct GNUNET_TIME_Absolute ret;
  568. ret.abs_value_us = GNUNET_ntohll (a.abs_value_us__);
  569. return ret;
  570. }
  571. /**
  572. * Return the current year (i.e. '2011').
  573. */
  574. unsigned int
  575. GNUNET_TIME_get_current_year ()
  576. {
  577. time_t tp;
  578. struct tm *t;
  579. tp = time (NULL);
  580. t = gmtime (&tp);
  581. if (t == NULL)
  582. return 0;
  583. return t->tm_year + 1900;
  584. }
  585. /**
  586. * Convert an expiration time to the respective year (rounds)
  587. *
  588. * @param at absolute time
  589. * @return year a year (after 1970), 0 on error
  590. */
  591. unsigned int
  592. GNUNET_TIME_time_to_year (struct GNUNET_TIME_Absolute at)
  593. {
  594. struct tm *t;
  595. time_t tp;
  596. tp = at.abs_value_us / 1000LL / 1000LL; /* microseconds to seconds */
  597. t = gmtime (&tp);
  598. if (t == NULL)
  599. return 0;
  600. return t->tm_year + 1900;
  601. }
  602. /**
  603. * Convert a year to an expiration time of January 1st of that year.
  604. *
  605. * @param year a year (after 1970, please ;-)).
  606. * @return absolute time for January 1st of that year.
  607. */
  608. struct GNUNET_TIME_Absolute
  609. GNUNET_TIME_year_to_time (unsigned int year)
  610. {
  611. struct GNUNET_TIME_Absolute ret;
  612. time_t tp;
  613. struct tm t;
  614. memset (&t, 0, sizeof(t));
  615. if (year < 1900)
  616. {
  617. GNUNET_break (0);
  618. return GNUNET_TIME_absolute_get (); /* now */
  619. }
  620. t.tm_year = year - 1900;
  621. t.tm_mday = 1;
  622. t.tm_mon = 0;
  623. t.tm_wday = 1;
  624. t.tm_yday = 1;
  625. tp = mktime (&t);
  626. GNUNET_break (tp != (time_t) -1);
  627. ret.abs_value_us = tp * 1000LL * 1000LL; /* seconds to microseconds */
  628. return ret;
  629. }
  630. /**
  631. * Randomized exponential back-off, starting at 1 ms
  632. * and going up by a factor of 2+r, where 0 <= r <= 0.5, up
  633. * to a maximum of the given threshold.
  634. *
  635. * @param r current backoff time, initially zero
  636. * @param threshold maximum value for backoff
  637. * @return the next backoff time
  638. */
  639. struct GNUNET_TIME_Relative
  640. GNUNET_TIME_randomized_backoff (struct GNUNET_TIME_Relative rt,
  641. struct GNUNET_TIME_Relative threshold)
  642. {
  643. double r = (rand () % 500) / 1000.0;
  644. struct GNUNET_TIME_Relative t;
  645. t = relative_multiply_double (
  646. GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_MILLISECONDS, rt),
  647. 2 + r);
  648. return GNUNET_TIME_relative_min (threshold, t);
  649. }
  650. /**
  651. * Return a random time value between 0.5*r and 1.5*r.
  652. *
  653. * @param r input time for scaling
  654. * @return randomized time
  655. */
  656. struct GNUNET_TIME_Relative
  657. GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r)
  658. {
  659. double d = ((rand () % 1001) - 500) / 1000.0;
  660. return relative_multiply_double (r, d);
  661. }
  662. /**
  663. * Obtain the current time and make sure it is monotonically
  664. * increasing. Guards against systems without an RTC or
  665. * clocks running backwards and other nasty surprises. Does
  666. * not guarantee that the returned time is near the current
  667. * time returned by #GNUNET_TIME_absolute_get(). Two
  668. * subsequent calls (within a short time period) may return the
  669. * same value. Persists the last returned time on disk to
  670. * ensure that time never goes backwards. As a result, the
  671. * resulting value can be used to check if a message is the
  672. * "most recent" value and replays of older messages (from
  673. * the same origin) would be discarded.
  674. *
  675. * @param cfg configuration, used to determine where to
  676. * store the time; user can also insist RTC is working
  677. * nicely and disable the feature
  678. * @return monotonically increasing time
  679. */
  680. struct GNUNET_TIME_Absolute
  681. GNUNET_TIME_absolute_get_monotonic (
  682. const struct GNUNET_CONFIGURATION_Handle *cfg)
  683. {
  684. static const struct GNUNET_CONFIGURATION_Handle *last_cfg;
  685. static struct GNUNET_TIME_Absolute last_time;
  686. static struct GNUNET_DISK_MapHandle *map_handle;
  687. static ATOMIC volatile uint64_t *map;
  688. struct GNUNET_TIME_Absolute now;
  689. now = GNUNET_TIME_absolute_get ();
  690. if (last_cfg != cfg)
  691. {
  692. char *filename;
  693. if (NULL != map_handle)
  694. {
  695. GNUNET_DISK_file_unmap (map_handle);
  696. map_handle = NULL;
  697. }
  698. map = NULL;
  699. last_cfg = cfg;
  700. if ((NULL != cfg) &&
  701. (GNUNET_OK ==
  702. GNUNET_CONFIGURATION_get_value_filename (cfg,
  703. "util",
  704. "MONOTONIC_TIME_FILENAME",
  705. &filename)))
  706. {
  707. struct GNUNET_DISK_FileHandle *fh;
  708. fh = GNUNET_DISK_file_open (filename,
  709. GNUNET_DISK_OPEN_READWRITE
  710. | GNUNET_DISK_OPEN_CREATE,
  711. GNUNET_DISK_PERM_USER_WRITE
  712. | GNUNET_DISK_PERM_GROUP_WRITE
  713. | GNUNET_DISK_PERM_USER_READ
  714. | GNUNET_DISK_PERM_GROUP_READ);
  715. if (NULL == fh)
  716. {
  717. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  718. _ ("Failed to map `%s', cannot assure monotonic time!\n"),
  719. filename);
  720. }
  721. else
  722. {
  723. off_t size;
  724. size = 0;
  725. GNUNET_break (GNUNET_OK == GNUNET_DISK_file_handle_size (fh, &size));
  726. if (size < (off_t) sizeof(*map))
  727. {
  728. struct GNUNET_TIME_AbsoluteNBO o;
  729. o = GNUNET_TIME_absolute_hton (now);
  730. if (sizeof(o) != GNUNET_DISK_file_write (fh, &o, sizeof(o)))
  731. size = 0;
  732. else
  733. size = sizeof(o);
  734. }
  735. if (size == sizeof(*map))
  736. {
  737. map = GNUNET_DISK_file_map (fh,
  738. &map_handle,
  739. GNUNET_DISK_MAP_TYPE_READWRITE,
  740. sizeof(*map));
  741. if (NULL == map)
  742. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  743. _ (
  744. "Failed to map `%s', cannot assure monotonic time!\n"),
  745. filename);
  746. }
  747. else
  748. {
  749. GNUNET_log (
  750. GNUNET_ERROR_TYPE_WARNING,
  751. _ (
  752. "Failed to setup monotonic time file `%s', cannot assure monotonic time!\n"),
  753. filename);
  754. }
  755. }
  756. GNUNET_DISK_file_close (fh);
  757. GNUNET_free (filename);
  758. }
  759. }
  760. if (NULL != map)
  761. {
  762. struct GNUNET_TIME_AbsoluteNBO mt;
  763. #if __STDC_NO_ATOMICS__
  764. #if __GNUC__
  765. mt.abs_value_us__ = __sync_fetch_and_or (map, 0);
  766. #else
  767. mt.abs_value_us__ = *map; /* godspeed, pray this is atomic */
  768. #endif
  769. #else
  770. mt.abs_value_us__ = atomic_load (map);
  771. #endif
  772. last_time =
  773. GNUNET_TIME_absolute_max (GNUNET_TIME_absolute_ntoh (mt), last_time);
  774. }
  775. if (now.abs_value_us <= last_time.abs_value_us)
  776. now.abs_value_us = last_time.abs_value_us + 1;
  777. last_time = now;
  778. if (NULL != map)
  779. {
  780. uint64_t val = GNUNET_TIME_absolute_hton (now).abs_value_us__;
  781. #if __STDC_NO_ATOMICS__
  782. #if __GNUC__
  783. (void) __sync_lock_test_and_set (map, val);
  784. #else
  785. *map = val; /* godspeed, pray this is atomic */
  786. #endif
  787. #else
  788. atomic_store (map, val);
  789. #endif
  790. }
  791. return now;
  792. }
  793. /**
  794. * Destructor
  795. */
  796. void __attribute__ ((destructor))
  797. GNUNET_util_time_fini ()
  798. {
  799. (void) GNUNET_TIME_absolute_get_monotonic (NULL);
  800. }
  801. /* end of time.c */