summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/timespec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/timespec.c')
-rw-r--r--libglusterfs/src/timespec.c127
1 files changed, 97 insertions, 30 deletions
diff --git a/libglusterfs/src/timespec.c b/libglusterfs/src/timespec.c
index f7b2bea2f30..96cef5c6f07 100644
--- a/libglusterfs/src/timespec.c
+++ b/libglusterfs/src/timespec.c
@@ -12,51 +12,118 @@
#include <inttypes.h>
#include <time.h>
#include <sys/time.h>
+#include <string.h>
#if defined GF_DARWIN_HOST_OS
#include <mach/mach_time.h>
static mach_timebase_info_data_t gf_timebase;
#endif
-#include "logging.h"
-#include "timespec.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/timespec.h"
+#include "glusterfs/libglusterfs-messages.h"
+#include "glusterfs/common-utils.h"
-void timespec_now (struct timespec *ts)
+void
+timespec_now(struct timespec *ts)
{
-#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS || defined GF_BSD_HOST_OS
- if (0 == clock_gettime(CLOCK_MONOTONIC, ts))
- return;
- else {
- struct timeval tv;
- if (0 == gettimeofday(&tv, NULL))
- TIMEVAL_TO_TIMESPEC(&tv, ts);
- }
+#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS || \
+ defined GF_BSD_HOST_OS
+ if (0 == clock_gettime(CLOCK_MONOTONIC, ts)) {
+ /* All good */
+ return;
+ }
+
+ /* Fall back, but there is hope in gettimeofday() syscall */
+ struct timeval tv;
+ if (0 == gettimeofday(&tv, NULL)) {
+ /* Again, all good */
+ TIMEVAL_TO_TIMESPEC(&tv, ts);
+ return;
+ }
+
+ /* If control hits here, there is surely a problem,
+ mainly because, as per man page too, these syscalls
+ shouldn't fail. Best way is to ABORT, because it is
+ not right */
+ GF_ABORT("gettimeofday() failed!!");
+
#elif defined GF_DARWIN_HOST_OS
- uint64_t time = mach_absolute_time();
- static double scaling = 0.0;
+ uint64_t time = mach_absolute_time();
+ static double scaling = 0.0;
- if (mach_timebase_info(&gf_timebase) != KERN_SUCCESS) {
- gf_timebase.numer = 1;
- gf_timebase.denom = 1;
- }
- if (gf_timebase.denom == 0) {
- gf_timebase.numer = 1;
- gf_timebase.denom = 1;
- }
+ if (mach_timebase_info(&gf_timebase) != KERN_SUCCESS) {
+ gf_timebase.numer = 1;
+ gf_timebase.denom = 1;
+ }
+ if (gf_timebase.denom == 0) {
+ gf_timebase.numer = 1;
+ gf_timebase.denom = 1;
+ }
- scaling = (double) gf_timebase.numer / (double) gf_timebase.denom;
- time *= scaling;
+ scaling = (double)gf_timebase.numer / (double)gf_timebase.denom;
+ time *= scaling;
- ts->tv_sec = (time * NANO);
- ts->tv_nsec = (time - (ts->tv_sec * GIGA));
+ ts->tv_sec = (time * NANO);
+ ts->tv_nsec = (time - (ts->tv_sec * GIGA));
#endif /* Platform verification */
}
-void timespec_adjust_delta (struct timespec *ts, struct timespec delta)
+void
+timespec_now_realtime(struct timespec *ts)
+{
+#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS || \
+ defined GF_BSD_HOST_OS
+ if (0 == clock_gettime(CLOCK_REALTIME, ts)) {
+ return;
+ }
+#endif
+
+ /* Fall back to gettimeofday()*/
+ struct timeval tv = {
+ 0,
+ };
+ if (0 == gettimeofday(&tv, NULL)) {
+ TIMEVAL_TO_TIMESPEC(&tv, ts);
+ return;
+ }
+
+ return;
+}
+
+void
+timespec_adjust_delta(struct timespec *ts, struct timespec delta)
+{
+ ts->tv_nsec = ((ts->tv_nsec + delta.tv_nsec) % 1000000000);
+ ts->tv_sec += ((ts->tv_nsec + delta.tv_nsec) / 1000000000);
+ ts->tv_sec += delta.tv_sec;
+}
+
+void
+timespec_sub(const struct timespec *begin, const struct timespec *end,
+ struct timespec *res)
{
- ts->tv_nsec = ((ts->tv_nsec + delta.tv_nsec) % 1000000000);
- ts->tv_sec += ((ts->tv_nsec + delta.tv_nsec) / 1000000000);
- ts->tv_sec += delta.tv_sec;
+ if (end->tv_nsec < begin->tv_nsec) {
+ res->tv_sec = end->tv_sec - begin->tv_sec - 1;
+ res->tv_nsec = end->tv_nsec + 1000000000 - begin->tv_nsec;
+ } else {
+ res->tv_sec = end->tv_sec - begin->tv_sec;
+ res->tv_nsec = end->tv_nsec - begin->tv_nsec;
+ }
+}
+
+int
+timespec_cmp(const struct timespec *lhs_ts, const struct timespec *rhs_ts)
+{
+ if (lhs_ts->tv_sec < rhs_ts->tv_sec) {
+ return -1;
+ } else if (lhs_ts->tv_sec > rhs_ts->tv_sec) {
+ return 1;
+ } else if (lhs_ts->tv_nsec < rhs_ts->tv_nsec) {
+ return -1;
+ } else if (lhs_ts->tv_nsec > rhs_ts->tv_nsec) {
+ return 1;
+ }
+
+ return 0;
}