opr: Add simple time type
authorSimon Wilkinson <sxw@your-file-system.com>
Tue, 15 May 2012 15:45:57 +0000 (16:45 +0100)
committerDerrick Brashear <shadow@dementix.org>
Thu, 14 Jun 2012 22:23:02 +0000 (15:23 -0700)
Add a simple time type to the opr library, which provides helper
routines to implement the 100ns time format selected for on-the-wire
use for AFS-3 (this also provides a handy single integer internal
time format)

Change-Id: I1f2d81e61a3e4124e0dd49830a115b72d7a7b37f
Reviewed-on: http://gerrit.openafs.org/7559
Reviewed-by: Derrick Brashear <shadow@dementix.org>
Tested-by: Derrick Brashear <shadow@dementix.org>

src/opr/Makefile.in
src/opr/NTMakefile
src/opr/opr_time.h [new file with mode: 0644]
tests/TESTS
tests/opr/.gitignore
tests/opr/Makefile.in
tests/opr/time-t.c [new file with mode: 0644]

index 4a60726..6640779 100644 (file)
@@ -8,7 +8,8 @@ HEADERS = $(TOP_INCDIR)/afs/opr.h \
          $(TOP_INCDIR)/afs/opr_assert.h \
          $(TOP_INCDIR)/opr/jhash.h \
          $(TOP_INCDIR)/opr/queue.h \
-         $(TOP_INCDIR)/opr/rbtree.h
+         $(TOP_INCDIR)/opr/rbtree.h \
+         $(TOP_INCDIR)/opr/time.h
 
 all: $(HEADERS) $(TOP_LIBDIR)/libopr.a
 
@@ -35,6 +36,9 @@ $(TOP_INCDIR)/opr/queue.h: ${srcdir}/queue.h
 $(TOP_INCDIR)/opr/rbtree.h: ${srcdir}/rbtree.h
        $(INSTALL_DATA) $? $@
 
+$(TOP_INCDIR)/opr/time.h: ${srcdir}/opr_time.h
+       $(INSTALL_DATA) $? $@
+
 clean:
        rm -f $(objects) libopr.a
 
index 8ef134c..0eeefda 100644 (file)
@@ -15,7 +15,11 @@ INCFILES = \
        $(INCFILEDIR)\opr_assert.h \
        $(DESTDIR)\include\opr\jhash.h \
        $(DESTDIR)\include\opr\queue.h \
-       $(DESTDIR)\include\opr\rbtree.h
+       $(DESTDIR)\include\opr\rbtree.h \
+       $(DESTDIR)\include\opr\time.h
+
+$(DESTDIR)\include\opr\time.h: opr_time.h
+        $(COPY) $** $@
 
 LIBFILE = $(DESTDIR)\lib\opr.lib
 
diff --git a/src/opr/opr_time.h b/src/opr/opr_time.h
new file mode 100644 (file)
index 0000000..7641e9f
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012 Your File System Inc. All rights reserved.
+ */
+
+/* This header provides routines for dealing with the 100ns based AFS
+ * time type. We hide the actual variable behind a structure, so that
+ * attempts to do
+ *
+ *     time_t ourTime;
+ *     opr_time theirTime;
+ *
+ *     ourTime = theirTime;
+ *
+ * will be caught by the compiler.
+ */
+
+#ifndef OPENAFS_OPR_TIME_H
+#define OPENAFS_OPR_TIME_H
+
+struct opr_time {
+    afs_int64 time;
+};
+
+static_inline void
+opr_time_FromSecs(struct opr_time *out, time_t in)
+{
+    out->time = ((afs_int64)in) * 10000000;
+}
+
+static_inline time_t
+opr_time_ToSecs(struct opr_time *in)
+{
+    return in->time/10000000;;
+}
+
+static_inline void
+opr_time_FromMsecs(struct opr_time *out, int msecs)
+{
+    out->time = ((afs_int64)msecs) * 10000;
+}
+
+static_inline int
+opr_time_ToMsecs(struct opr_time *in)
+{
+    return in->time/10000;
+}
+
+static_inline void
+opr_time_FromTimeval(struct opr_time *out, struct timeval *in)
+{
+    out->time = ((afs_int64)in->tv_sec) * 10000000 + in->tv_usec * 10;
+}
+
+static_inline void
+opr_time_ToTimeval(struct opr_time *in, struct timeval *out)
+{
+    out->tv_sec = in->time / 10000000;
+    out->tv_usec = (in->time / 10) % 1000000;
+}
+
+static_inline int
+opr_time_Now(struct opr_time *out)
+{
+    struct timeval tv;
+    int code;
+
+    code = gettimeofday(&tv, NULL);
+    if (code == 0)
+       opr_time_FromTimeval(out, &tv);
+
+    return code;
+}
+
+static_inline int
+opr_time_GreaterThan(struct opr_time *t1, struct opr_time *t2)
+{
+    return t1->time > t2->time;
+}
+
+static_inline int
+opr_time_LessThan(struct opr_time *t1, struct opr_time *t2)
+{
+    return t1->time < t2->time;
+}
+
+static_inline void
+opr_time_Add(struct opr_time *t1, struct opr_time *t2)
+{
+    t1->time += t2->time;
+}
+
+static_inline void
+opr_time_Sub(struct opr_time *t1, struct opr_time *t2)
+{
+    t1->time -= t2->time;
+}
+
+static_inline void
+opr_time_AddMsec(struct opr_time *t1, int msec)
+{
+    struct opr_time t2;
+
+    opr_time_FromMsecs(&t2, msec);
+    opr_time_Add(t1, &t2);
+}
+
+#endif
index 95e9cdc..4ed9809 100644 (file)
@@ -8,6 +8,7 @@ cmd/command
 opr/jhash
 opr/queues
 opr/rbtree
+opr/time
 ptserver/pt_util
 ptserver/pts-man
 rx/event
index 1ad4326..578ee06 100644 (file)
@@ -5,3 +5,4 @@
 /jhash-t
 /rbtree-t
 /queues-t
+/time-t
index 2e9e867..dccdb58 100644 (file)
@@ -7,7 +7,7 @@ MODULE_CFLAGS = -I$(srcdir)/../..
 
 LIBS=../tap/libtap.a $(abs_top_builddir)/lib/libopr.a
 
-tests = jhash-t queues-t rbtree-t
+tests = jhash-t queues-t rbtree-t time-t
 
 all check test tests: $(tests)
 
@@ -20,5 +20,8 @@ rbtree-t: rbtree-t.o $(LIBS)
 jhash-t: jhash-t.o
        $(AFS_LDRULE) jhash-t.o ../tap/libtap.a $(XLIBS)
 
+time-t: time-t.o
+       $(AFS_LDRULE) time-t.o ../tap/libtap.a $(XLIBS)
+
 clean distclean:
        $(RM) -f $(tests) *.o core
diff --git a/tests/opr/time-t.c b/tests/opr/time-t.c
new file mode 100644 (file)
index 0000000..d650c8f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012 Your File System Inc. All rights reserved.
+ */
+
+/* Some trivial tests for the very straightforwards OPR 100ns time
+ * implementation.
+ */
+
+#include <afsconfig.h>
+#include <afs/param.h>
+
+#include <roken.h>
+
+#include <tests/tap/basic.h>
+
+#include <opr/time.h>
+
+int
+main(int argc, char **argv)
+{
+    struct opr_time oprTime;
+    struct timeval osTimeval;
+    time_t osTime, osNow;
+    plan(4);
+
+    /* Check that FromSecs, then ToSecs results in the same value coming out */
+
+    opr_time_FromSecs(&oprTime, 1337065355);
+    osTime = opr_time_ToSecs(&oprTime);
+    ok(osTime == 1337065355, "ToSecs(FromSecs(time)) == time");
+
+    /* Check the FromTimeval, then ToTimeval result in the same value. Note that
+     * our chosen microseconds field is very close to overflow */
+
+    osTimeval.tv_sec = 1337065355;
+    osTimeval.tv_usec = 999;
+    opr_time_FromTimeval(&oprTime, &osTimeval);
+    opr_time_ToTimeval(&oprTime, &osTimeval);
+    ok(osTimeval.tv_sec == 1337065355 && osTimeval.tv_usec == 999,
+       "ToTimeval(FromTimeval(timeval) == timeval)");
+
+    /* Check that opr_time_Now looks reasonable */
+    is_int(0, opr_time_Now(&oprTime), "opr_time_Now succeeds");
+    osNow = time(NULL);
+    osTime = opr_time_ToSecs(&oprTime);
+    ok(abs(osTime - osNow) < 2, "opr_time_Now returns a reasonable value");
+
+    return 0;
+}