-* crypo group changes from Dave Mills.
+* Grow ntpd/work_thread.c arrays as needed.
+* Add DEBUG_* variants of ntp_assert.h macros which compile away using
+ ./configure --disable-debugging.
+* Fix tvalops.cpp unit test failures for 32-bit builds.
+* Return to a single autoreconf invocation in ./bootstrap script.
+* Fix warnings seen on FreeBSD 9.
+* crypto group changes from Dave Mills.
* Lose the RANGEGATE check in PPS, from Dave Mills.
* ACTS refclock cleanup from Dave Mills.
* Documentation updates from Dave Mills.
+* NMEA driver documentation update from Juergen Perlinger.
(4.2.7p119) 2011/01/18 Released by Harlan Stenn <stenn@ntp.org>
* added timespecops.{c,h} and tievalops.{c.h} to libntp and include
added tspecops.cpp to tests/libntp
cp bincheck.mf sntp/
cp depsver.mf sntp/
-${AUTORECONF} -i -v --no-recursive "$@"
+${AUTORECONF} -i -v "$@"
+# DH: 20110118: Due to our workaround for the AM_COND_IF bug that was
+# triggering the buggy recursive autoreconf, we can once again use a
+# single autoreconf invocation. See
+# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=7860
# DH: 20101120: We are back to a single copy of libopts, and
# once again it seems we need to run autoreconf in sntp after
# the top-level run to get a correct sntp/libopts/Makefile.in.
## we get the correct srcdir path in sntp/libopts/Makefile.in
#rm -rf sntp/autom4te.cache
#
-(cd sntp && ${AUTORECONF} -i -v "$@")
+# (cd sntp && ${AUTORECONF} -i -v "$@")
* int result;
* int value;
*
- * NTP_REQUIRE(a != NULL);
+ * REQUIRE(a != NULL);
* ...
* bar(&value);
- * NTP_INSIST(value > 2);
+ * INSIST(value > 2);
* ...
*
- * NTP_ENSURE(result != 12);
+ * ENSURE(result != 12);
* return result;
* }
*
- * open question: when would we use NTP_INVARIANT()?
+ * open question: when would we use INVARIANT()?
+ *
+ * For cases where the overhead for non-debug builds is deemed too high,
+ * use DEBUG_REQUIRE(), DEBUG_INSIST(), DEBUG_ENSURE(), and/or
+ * DEBUG_INVARIANT().
*/
#ifndef NTP_ASSERT_H
extern void calysto_assume(unsigned char cnd); /* assume this always holds */
extern void calysto_assert(unsigned char cnd); /* check whether this holds */
-#define NTP_REQUIRE(x) calysto_assert(x)
-#define NTP_INSIST(x) calysto_assume(x) /* DLH calysto_assert()? */
-#define NTP_INVARIANT(x) calysto_assume(x)
-#define NTP_ENSURE(x) calysto_assert(x)
+#define ALWAYS_REQUIRE(x) calysto_assert(x)
+#define ALWAYS_INSIST(x) calysto_assume(x) /* DLH calysto_assert()? */
+#define ALWAYS_INVARIANT(x) calysto_assume(x)
+#define ALWAYS_ENSURE(x) calysto_assert(x)
# elif defined(__COVERITY__)
* that seems to be a reasonable trade-off.
*/
-#define NTP_REQUIRE(x) assert(x)
-#define NTP_INSIST(x) assert(x)
-#define NTP_INVARIANT(x) assert(x)
-#define NTP_ENSURE(x) assert(x)
+#define ALWAYS_REQUIRE(x) assert(x)
+#define ALWAYS_INSIST(x) assert(x)
+#define ALWAYS_INVARIANT(x) assert(x)
+#define ALWAYS_ENSURE(x) assert(x)
# else /* neither Coverity nor Calysto */
#include "isc/assertions.h"
-#define NTP_REQUIRE(x) ISC_REQUIRE(x)
-#define NTP_INSIST(x) ISC_INSIST(x)
-#define NTP_INVARIANT(x) ISC_INVARIANT(x)
-#define NTP_ENSURE(x) ISC_ENSURE(x)
+#define ALWAYS_REQUIRE(x) ISC_REQUIRE(x)
+#define ALWAYS_INSIST(x) ISC_INSIST(x)
+#define ALWAYS_INVARIANT(x) ISC_INVARIANT(x)
+#define ALWAYS_ENSURE(x) ISC_ENSURE(x)
# endif /* neither Coverity nor Calysto */
+
+#define REQUIRE(x) ALWAYS_REQUIRE(x)
+#define INSIST(x) ALWAYS_INSIST(x)
+#define INVARIANT(x) ALWAYS_INVARIANT(x)
+#define ENSURE(x) ALWAYS_ENSURE(x)
+
+/*
+ * We initially used NTP_REQUIRE() instead of REQUIRE() etc, but that
+ * is unneccesarily verbose, as libisc use of REQUIRE() etc shows.
+ */
+#define NTP_REQUIRE(x) REQUIRE(x)
+#define NTP_INSIST(x) INSIST(x)
+#define NTP_INVARIANT(x) INVARIANT(x)
+#define NTP_ENSURE(x) ENSURE(x)
+
+# ifdef DEBUG
+#define DEBUG_REQUIRE(x) REQUIRE(x)
+#define DEBUG_INSIST(x) INSIST(x)
+#define DEBUG_INVARIANT(x) INVARIANT(x)
+#define DEBUG_ENSURE(x) ENSURE(x)
+# else
+#define DEBUG_REQUIRE(x) (void)(x)
+#define DEBUG_INSIST(x) (void)(x)
+#define DEBUG_INVARIANT(x) (void)(x)
+#define DEBUG_ENSURE(x) (void)(x)
+# endif
+
#endif /* NTP_ASSERT_H */
# include "isc/md5.h"
typedef isc_md5_t MD5_CTX;
# define MD5Init(c) isc_md5_init(c)
-# define MD5Update(c, p, s) isc_md5_update(c, (const void *)(p), s)
+# define MD5Update(c, p, s) isc_md5_update(c, p, s)
# define MD5Final(d, c) isc_md5_final((c), (d)) /* swapped */
# endif
typedef MD5_CTX EVP_MD_CTX;
# define EVP_get_digestbynid(t) NULL
# define EVP_DigestInit(c, dt) MD5Init(c)
-# define EVP_DigestUpdate(c, p, s) MD5Update(c, p, s)
+# define EVP_DigestUpdate(c, p, s) MD5Update(c, (const void *)(p), \
+ s)
# define EVP_DigestFinal(c, d, pdl) \
do { \
MD5Final((d), (c)); \
* Input and output operands may overlap; all input is consumed before
* the output is written to.
*/
-#ifndef TIMPESPECOPS_H
-#define TIMPESPECOPS_H
+#ifndef TIMESPECOPS_H
+#define TIMESPECOPS_H
-#include <config.h>
#include <sys/types.h>
#include <stdio.h>
+
+#include "ntp.h"
#include "ntp_unixtime.h"
-#include "ntp_fp.h"
/*
* here.
*/
-/* predicate: returns TRUE if the nanoseconds are out-of-bounds */
-#define timespec_isdenormal(x) \
- ((u_long)(x)->tv_nsec >= 1000000000)
-
/* predicate: returns TRUE if the nanoseconds are in nominal range */
#define timespec_isnormal(x) \
- ((u_long)(x)->tv_nsec < 1000000000)
+ ((u_long)(x)->tv_nsec < 1000000000)
+
+/* predicate: returns TRUE if the nanoseconds are out-of-bounds */
+#define timespec_isdenormal(x) (!timespec_isnormal(x))
/*make sure nanoseconds are in nominal range */
extern void timespec_norm(struct timespec *x);
-/* x = a, normlised */
+/* x = a, normalised */
extern void timespec_copy(struct timespec *x, const struct timespec *a);
/* x = a + b */
const struct timespec *b);
/* x = a + b, b is fraction only */
-extern void timespec_addns(struct timespec *x, const struct timespec *a,
+extern void timespec_addns(struct timespec *x, const struct timespec *a,
long b);
-/* x = a + b */
+/* x = a - b */
extern void timespec_sub(struct timespec *x, const struct timespec *a,
const struct timespec *b);
/* x = -a */
extern void timespec_neg(struct timespec *x, const struct timespec *a);
-/* x = ( a < 0) ? -a : a
- * return if negation was needed
+/*
+ * x = abs(a)
+ * returns nonzero if negation was needed
*/
extern int timespec_abs(struct timespec *x, const struct timespec *a);
-/* compare a <--> b
+/*
+ * compare previously-normalised a and b
* return 1 / 0 / -1 if a < / == / > b
*/
extern int timespec_cmp_fast(const struct timespec *a,
const struct timespec *b);
+/*
+ * compare possibly-denormal a and b
+ * return 1 / 0 / -1 if a < / == / > b
+ */
extern int timespec_cmp(const struct timespec *a,
const struct timespec *b);
-/* test a
+/*
+ * test previously-normalised a
* return 1 / 0 / -1 if a < / == / > 0
*/
extern int timespec_test_fast(const struct timespec *a);
+
+/*
+ * test possibly-denormal a
+ * return 1 / 0 / -1 if a < / == / > 0
+ */
extern int timespec_test(const struct timespec *a);
/* return LIB buffer ptr to string rep */
-extern const char* timespec_tostr(const struct timespec *x);
+extern const char * timespec_tostr(const struct timespec *x);
/*
convert to l_fp type, relative and absolute
*/
-/* convert from duration to duration */
+/* convert from timespec duration to l_fp duration */
extern void timespec_reltolfp(l_fp *y, const struct timespec *x);
-/* 'x' must be UN*X epoch, output will be in NTP epoch */
+/* x must be UN*X epoch, output *y will be in NTP epoch */
extern void timespec_abstolfp(l_fp *y, const struct timespec *x);
-/*
- convert to l_fp type, relative signed/unsigned and absolute
-*/
+/* convert to l_fp type, relative signed/unsigned and absolute */
extern void timespec_relfromlfp(struct timespec *y, const l_fp *x);
extern void timespec_urelfromlfp(struct timespec *y, const l_fp *x);
-/* absolute (timestamp) conversion. Input is time in NTP epoch, output
- * is in UN*X epoch. The NTP time stamp will be expanded the pivot time
- * '*' or the current time, if 'p' is NULL.
+/*
+ * absolute (timestamp) conversion. Input is time in NTP epoch, output
+ * is in UN*X epoch. The NTP time stamp will be expanded around the
+ * pivot time *p or the current time, if p is NULL.
*/
extern void timespec_absfromlfp(struct timespec *y, const l_fp *x,
const time_t *p);
-#endif
-/* -*- EOF -*- */
+
+#endif /* TIMESPECOPS_H */
* For a rationale look at 'timespecops.h'; we do the same here, but the
* normalisation keeps the microseconds in [0 .. 10^6[, of course.
*/
-#ifndef TIMPEVALOPS_H
-#define TIMPEVALOPS_H
+#ifndef TIMEVALOPS_H
+#define TIMEVALOPS_H
-#include <config.h>
#include <sys/types.h>
#include <stdio.h>
+
+#include "ntp.h"
#include "ntp_unixtime.h"
-#include "ntp_fp.h"
/*
* We avoid to use/define MICROSECONDS here, as it is also possibly
* clashes here.
*/
-/* predicate: returns TRUE if the microseconds are out-of-bounds */
-/* use like: int timeval_isdenormal(const struct timeval *x) */
-#define timeval_isdenormal(x) \
- ((u_long)(x)->tv_usec >= 1000000)
-
-/* predicate: returns TRUE if the microseconds are in nominal range */
-/* use like: int timeval_isnormal(const struct timeval *x) */
+/*
+ * predicate: returns TRUE if the microseconds are in nominal range
+ * use like: int timeval_isnormal(const struct timeval *x)
+ */
#define timeval_isnormal(x) \
- ((u_long)(x)->tv_usec < 1000000)
+ ((u_long)(x)->tv_usec < 1000000)
+/*
+ * predicate: returns TRUE if the microseconds are out-of-bounds
+ * use like: int timeval_isdenormal(const struct timeval *x)
+ */
+#define timeval_isdenormal(x) (!timeval_isnormal(x))
-/*make sure microseconds are in nominal range */
+/* make sure microseconds are in nominal range */
extern void timeval_norm(struct timeval *x);
-/* x = a, normlised */
+/* x = a, normalised */
extern void timeval_copy(struct timeval *x, const struct timeval *a);
/* x = a + b */
extern void timeval_addus(struct timeval *x, const struct timeval *a,
long b);
-/* x = a + b */
+/* x = a - b */
extern void timeval_sub(struct timeval *x, const struct timeval *a,
const struct timeval *b);
/* x = -a */
extern void timeval_neg(struct timeval *x, const struct timeval *a);
-/* x = ( a < 0) ? -a : a
- * return if negation was needed
+/*
+ * x = abs(a)
+ * returns nonzero if negation was needed
*/
extern int timeval_abs(struct timeval *x, const struct timeval *a);
-/* compare a <--> b
+/*
+ * compare previously-normalised a and b
* return 1 / 0 / -1 if a < / == / > b
*/
extern int timeval_cmp_fast(const struct timeval *a,
const struct timeval *b);
-
+/*
+ * compare possibly-denormal a and b
+ * return 1 / 0 / -1 if a < / == / > b
+ */
extern int timeval_cmp(const struct timeval *a,
const struct timeval *b);
-/* test a
+/*
+ * test previously-normalised a
* return 1 / 0 / -1 if a < / == / > 0
*/
extern int timeval_test_fast(const struct timeval *a);
+
+/*
+ * test possibly-denormal a
+ * return 1 / 0 / -1 if a < / == / > 0
+ */
extern int timeval_test(const struct timeval *a);
/* return LIB buffer ptr to string rep */
-extern const char* timeval_tostr(const struct timeval *x);
-
-/*
- convert to l_fp type, relative and absolute
-*/
+extern const char * timeval_tostr(const struct timeval *x);
-/* convert from duration to duration */
+/* convert from timeval duration to l_fp duration */
extern void timeval_reltolfp(l_fp *y, const struct timeval *x);
-/* 'x' must be UN*X epoch, output will be in NTP epoch */
+/* x must be UN*X epoch, output *y will be in NTP epoch */
extern void timeval_abstolfp(l_fp *y, const struct timeval *x);
-/*
- convert to l_fp type, relative signed/unsigned and absolute
-*/
+/* convert to l_fp type, relative signed/unsigned and absolute */
extern void timeval_relfromlfp(struct timeval *y, const l_fp *x);
extern void timeval_urelfromlfp(struct timeval *y, const l_fp *x);
-/* absolute (timestamp) conversion. Input is time in NTP epoch, output
- * is in UN*X epoch. The NTP time stamp will be expanded the pivot time
- * '*' or the current time, if 'p' is NULL.
+/*
+ * absolute (timestamp) conversion. Input is time in NTP epoch, output
+ * is in UN*X epoch. The NTP time stamp will be expanded around the
+ * pivot time *p or the current time, if p is NULL.
*/
extern void timeval_absfromlfp(struct timeval *y, const l_fp *x,
const time_t *p);
-#endif
-/* -*- EOF -*- */
+#endif /* TIMEVALOPS_H */
#include <stdio.h>
#include "ntp.h"
-// #include "ntp_assert.h"
#include "ntp_types.h"
#include "ntp_net.h"
#include "ntp_io.h"
-#include <isc/util.h>
-
/*
* Windows C runtime ioctl() can't deal properly with sockets,
* map to ioctlsocket for this source file.
#define NANOSECONDS 1000000000
#if SIZEOF_LONG >= 8
-# define MYFTOTVN(tsf,tvu) \
- (tvu) = (int32)(((u_long)(tsf) * NANOSECONDS + 0x80000000) >> 32)
-# define MYTVNTOF(tvu,tsf) \
- (tsf) = (u_int32)((((u_long)(tvu)<<32)+NANOSECONDS/2) / NANOSECONDS)
+# define MYFTOTVN(tsf,tvu) \
+ ((tvu) = (int32) \
+ (((u_long)(tsf) * NANOSECONDS + 0x80000000) >> 32))
+# define MYTVNTOF(tvu, tsf) \
+ ((tsf) = (u_int32) \
+ ((((u_long)(tvu) << 32) + NANOSECONDS / 2) / \
+ NANOSECONDS))
#else
-# define MYFTOTVN(tsf,tvu) \
- (tvu) = (int32)floor((tsf) / 4.294967296 + 0.5)
-# define MYTVNTOF(tvu,tsf) \
- (tsf) = (u_int32)floor((tvu) * 4.294967296 + 0.5)
+# define MYFTOTVN(tsf, tvu) \
+ ((tvu) = (int32)floor((tsf) / 4.294967296 + 0.5))
+# define MYTVNTOF(tvu, tsf) \
+ ((tsf) = (u_int32)floor((tvu) * 4.294967296 + 0.5))
#endif
-#define COPYNORM(dst,src) \
- do { *(dst) = *(src); \
- if (timespec_isdenormal((dst))) \
- timespec_norm((dst)); \
- } while (0)
-
+#define COPYNORM(dst, src) \
+ do { \
+ *(dst) = *(src); \
+ if (timespec_isdenormal(dst)) \
+ timespec_norm(dst); \
+ } while (0)
+
void
timespec_norm(
* follows with the standard normalisation loops. Also note
* that 'abs' returns int, which might not be good here. */
long z;
+
z = x->tv_nsec;
- if (((z < 0 ? -z : z) >> 32) > 0) {
+ if ((labs(z) >> 32) > 0) {
z = x->tv_nsec / NANOSECONDS;
x->tv_nsec -= z * NANOSECONDS;
x->tv_sec += z;
} while (x->tv_nsec >= NANOSECONDS);
}
-/* x = a, normlised */
+/* x = a, normalised */
void
timespec_copy(
- struct timespec *x,
- const struct timespec *a
+ struct timespec * x,
+ const struct timespec * a
)
{
- COPYNORM(x,a);
+ COPYNORM(x, a);
}
/* x = a + b */
void
timespec_add(
- struct timespec *x,
- const struct timespec *a,
- const struct timespec *b
+ struct timespec * x,
+ const struct timespec * a,
+ const struct timespec * b
)
{
struct timespec c;
/* x = a + b, b is fraction only */
void
timespec_addns(
- struct timespec *x,
- const struct timespec *a,
- long b
+ struct timespec * x,
+ const struct timespec * a,
+ long b
)
{
struct timespec c;
COPYNORM(x, &c);
}
-/* x = a + b */
+/* x = a - b */
void
timespec_sub(
- struct timespec *x,
- const struct timespec *a,
- const struct timespec *b
+ struct timespec * x,
+ const struct timespec * a,
+ const struct timespec * b
)
{
struct timespec c;
/* x = a - b, b is fraction only */
void
timespec_subns(
- struct timespec *x,
- const struct timespec *a,
- long b
+ struct timespec * x,
+ const struct timespec * a,
+ long b
)
{
struct timespec c;
/* x = -a */
void
timespec_neg(
- struct timespec *x,
- const struct timespec *a
+ struct timespec * x,
+ const struct timespec * a
)
{
struct timespec c;
COPYNORM(x, &c);
}
-/* x = ( a < 0) ? -a : a
- * return if negation was needed
+/*
+ * x = abs(a)
+ * returns nonzero if negation was needed
*/
int
timespec_abs(
- struct timespec *x,
- const struct timespec *a
+ struct timespec * x,
+ const struct timespec * a
)
{
struct timespec c;
int r;
COPYNORM(&c, a);
- if ((r = (c.tv_sec < 0)) != 0) {
- c.tv_sec = - c.tv_sec;
- c.tv_nsec = - c.tv_nsec;
- if (c.tv_nsec < 0) {
- c.tv_sec -= 1;
- c.tv_nsec += NANOSECONDS;
- }
- }
- *x = c;
+ r = (c.tv_sec < 0);
+ if (r != 0)
+ timespec_neg(x, &c);
+ else
+ *x = c;
return r;
}
-/* compare a <--> b
+/*
+ * compare previously-normalised a and b
* return 1 / 0 / -1 if a < / == / > b
*/
int
{
int r;
- r = (a->tv_sec > b->tv_sec)
- - (a->tv_sec < b->tv_sec);
+ r = (a->tv_sec > b->tv_sec) - (a->tv_sec < b->tv_sec);
if (r == 0)
- r = (a->tv_nsec > b->tv_nsec)
- - (a->tv_nsec < b->tv_nsec);
+ r = (a->tv_nsec > b->tv_nsec) -
+ (a->tv_nsec < b->tv_nsec);
return r;
}
+/*
+ * compare possibly denormal a and b
+ * return 1 / 0 / -1 if a < / == / > b
+ */
int
timespec_cmp(
const struct timespec *a,
const struct timespec *b
)
{
- int r;
- struct timespec A;
- struct timespec B;
+ struct timespec A;
+ struct timespec B;
COPYNORM(&A, a);
COPYNORM(&B, b);
- r = (A.tv_sec > B.tv_sec)
- - (A.tv_sec < B.tv_sec);
- if (r == 0)
- r = (A.tv_nsec > B.tv_nsec)
- - (A.tv_nsec < B.tv_nsec);
-
- return r;
+
+ return timespec_cmp_fast(&A, &B);
}
-/* test a
+/*
+ * test previously-normalised a
* return 1 / 0 / -1 if a < / == / > 0
*/
int
return r;
}
+/*
+ * test possibly denormal a
+ * return 1 / 0 / -1 if a < / == / > 0
+ */
int
timespec_test(
const struct timespec *a
)
{
- int r;
struct timespec A;
COPYNORM(&A, a);
- r = (A.tv_sec > 0) - (A.tv_sec < 0);
- if (r == 0)
- r = (A.tv_nsec > 0);
-
- return r;
+
+ return timespec_test_fast(&A);
}
const char*
int s;
int digits;
int dig;
- char *cp;
+ char * cp;
time_t itmp;
long ftmp;
ftmp = v.tv_nsec / 10;
dig = (int)(v.tv_nsec - ftmp * 10);
v.tv_nsec = ftmp;
- *--cp = '0' + dig;
+ *--cp = '0' + (char)dig;
}
*--cp = '.';
* truncates towards zero, as required by the standard. */
itmp = v.tv_sec / 10;
dig = (int)(v.tv_sec - itmp * 10);
- v.tv_sec = (itmp < 0) ? -itmp : itmp;
- *--cp = '0' + ((dig < 0) ? -dig : dig);
+ v.tv_sec = max(-itmp, itmp);
+ *--cp = '0' + (char)abs(dig);
/* -*- convert remaining digits */
while (v.tv_sec != 0) {
itmp = v.tv_sec / 10;
dig = (int)(v.tv_sec - itmp * 10);
v.tv_sec = itmp;
- *--cp = '0' + dig;
+ *--cp = '0' + (char)dig;
}
/* add minus sign for negative integer part */
if (s)
void
timespec_abstolfp(
- l_fp *y,
- const struct timespec *x
+ l_fp * y,
+ const struct timespec * x
)
{
struct timespec v;
void
timespec_reltolfp(
- l_fp *y,
- const struct timespec *x
+ l_fp * y,
+ const struct timespec * x
)
{
struct timespec v;
COPYNORM(&v, x);
MYTVNTOF(v.tv_nsec, y->l_uf);
y->l_i = (int32)v.tv_sec;
-
}
void
timespec_relfromlfp(
struct timespec *y,
- const l_fp *x)
+ const l_fp *x
+ )
{
struct timespec out;
l_fp tmp;
int neg;
tmp = *x;
- if ((neg = L_ISNEG(&tmp)) != 0)
+ neg = L_ISNEG(&tmp);
+ if (neg)
L_NEG(&tmp);
MYFTOTVN(x->l_uf, out.tv_nsec);
out.tv_sec = x->l_ui;
if (neg) {
- out.tv_sec = - out.tv_sec;
- out.tv_nsec = - out.tv_nsec;
+ out.tv_sec = -out.tv_sec;
+ out.tv_nsec = -out.tv_nsec;
}
COPYNORM(y, &out);
}
void
timespec_urelfromlfp(
struct timespec *y,
- const l_fp *x)
+ const l_fp *x
+ )
{
struct timespec out;
MYFTOTVN(x->l_uf, out.tv_nsec);
/* copying a vint64 to a time_t needs some care... */
-# if SIZEOF_TIME_T <= 4
+#if SIZEOF_TIME_T <= 4
out.tv_sec = (time_t)sec.d_s.lo;
-# elif defined(HAVE_INT64)
+#elif defined(HAVE_INT64)
out.tv_sec = (time_t)sec.q_s;
-# else
+#else
out.tv_sec = ((time_t)sec.d_s.hi << 32) + sec.d_s.lo;
-# endif
+#endif
COPYNORM(y, &out);
}
#define MICROSECONDS 1000000
#if SIZEOF_LONG >= 8
-# define MYFTOTVU(tsf,tvu) \
- (tvu) = (int32)(((u_long)(tsf) * MICROSECONDS + 0x80000000) >> 32)
-# define MYTVUTOF(tvu,tsf) \
- (tsf) = (u_int32)((((u_long)(tvu)<<32)+MICROSECONDS/2) / MICROSECONDS)
+# define MYFTOTVU(tsf, tvu) \
+ (tvu) = (int32) \
+ (((u_long)(tsf) * MICROSECONDS + 0x80000000) >> 32)
+# define MYTVUTOF(tvu, tsf) \
+ (tsf) = (u_int32) \
+ ((((u_long)(tvu) << 32) + MICROSECONDS / 2) / \
+ MICROSECONDS)
#else
-# define MYFTOTVU(tsf,tvu) TSFTOTVU(tsf, tvu)
-# define MYTVUTOF(tvu,tsf) TVUTOTSF(tvu, tsf)
+# define MYFTOTVU(tsf, tvu) TSFTOTVU(tsf, tvu)
+# define MYTVUTOF(tvu, tsf) TVUTOTSF(tvu, tsf)
#endif
-#define COPYNORM(dst,src) \
- do { *(dst) = *(src); \
- if (timeval_isdenormal((dst)))\
- timeval_norm((dst)); \
- } while (0)
-
+#define COPYNORM(dst, src) \
+ do { \
+ *(dst) = *(src); \
+ if (timeval_isdenormal(dst)) \
+ timeval_norm(dst); \
+ } while (0)
+
void
timeval_norm(
* 'abs' returns int, which might not be good here. */
long z;
z = x->tv_usec;
- if ((z < 0 ? -z : z) > 3*MICROSECONDS) {
+ if (max(-z, z) > 3 * MICROSECONDS) {
z = x->tv_usec / MICROSECONDS;
x->tv_usec -= z * MICROSECONDS;
x->tv_sec += z;
} while (x->tv_usec >= MICROSECONDS);
}
-/* x = a, normlised */
+/* x = a, normalised */
void
timeval_copy(
- struct timeval *x,
- const struct timeval *a
+ struct timeval * x,
+ const struct timeval * a
)
{
- COPYNORM(x,a);
+ COPYNORM(x, a);
}
/* x = a + b */
void
timeval_add(
- struct timeval *x,
- const struct timeval *a,
- const struct timeval *b
+ struct timeval * x,
+ const struct timeval * a,
+ const struct timeval * b
)
{
struct timeval c;
/* x = a + b, b is fraction only */
void
timeval_addus(
- struct timeval *x,
- const struct timeval *a,
- long b
+ struct timeval * x,
+ const struct timeval * a,
+ long b
)
{
struct timeval c;
COPYNORM(x, &c);
}
-/* x = a + b */
+/* x = a - b */
void
timeval_sub(
- struct timeval *x,
- const struct timeval *a,
- const struct timeval *b
+ struct timeval * x,
+ const struct timeval * a,
+ const struct timeval * b
)
{
struct timeval c;
/* x = a - b, b is fraction only */
void
timeval_subus(
- struct timeval *x,
- const struct timeval *a,
- long b
+ struct timeval * x,
+ const struct timeval * a,
+ long b
)
{
struct timeval c;
/* x = -a */
void
timeval_neg(
- struct timeval *x,
- const struct timeval *a
+ struct timeval * x,
+ const struct timeval * a
)
{
struct timeval c;
- c.tv_sec = - a->tv_sec;
- c.tv_usec = - a->tv_usec;
+ c.tv_sec = -a->tv_sec;
+ c.tv_usec = -a->tv_usec;
COPYNORM(x, &c);
}
-/* x = ( a < 0) ? -a : a
- * return if negation was needed
+/*
+ * x = abs(a)
+ * return value is nonzero if negation was needed
*/
int
timeval_abs(
- struct timeval *x,
- const struct timeval *a
+ struct timeval * x,
+ const struct timeval * a
)
{
- struct timeval c;
+ struct timeval c;
int r;
COPYNORM(&c, a);
- if ((r = (c.tv_sec < 0)) != 0) {
- c.tv_sec = - c.tv_sec;
- c.tv_usec = - c.tv_usec;
- if (c.tv_usec < 0) {
- c.tv_sec -= 1;
- c.tv_usec += MICROSECONDS;
- }
- }
- *x = c;
+ r = (c.tv_sec < 0);
+ if (r)
+ timeval_neg(x, &c);
+ else
+ *x = c;
return r;
}
{
int r;
- r = (a->tv_sec > b->tv_sec)
- - (a->tv_sec < b->tv_sec);
+ r = (a->tv_sec > b->tv_sec) - (a->tv_sec < b->tv_sec);
if (r == 0)
- r = (a->tv_usec > b->tv_usec)
- - (a->tv_usec < b->tv_usec);
+ r = (a->tv_usec > b->tv_usec) -
+ (a->tv_usec < b->tv_usec);
return r;
}
const struct timeval *b
)
{
- int r;
struct timeval A;
struct timeval B;
COPYNORM(&A, a);
COPYNORM(&B, b);
- r = (A.tv_sec > B.tv_sec)
- - (A.tv_sec < B.tv_sec);
- if (r == 0)
- r = (A.tv_usec > B.tv_usec)
- - (A.tv_usec < B.tv_usec);
-
- return r;
+ return timeval_cmp_fast(&A, &B);
}
-/* test a
+/*
+ * test previously-normalised a
* return 1 / 0 / -1 if a < / == / > 0
*/
int
return r;
}
+/*
+ * test possibly denormal a
+ * return 1 / 0 / -1 if a < / == / > 0
+ */
int
timeval_test(
const struct timeval *a
)
{
struct timeval A;
- int r;
COPYNORM(&A, a);
- r = (A.tv_sec > 0) - (A.tv_sec < 0);
- if (r == 0)
- r = (A.tv_usec > 0);
-
- return r;
+ return timeval_test_fast(&A);
}
/* return LIB buffer ptr to string rep */
-const char*
+const char *
timeval_tostr(
const struct timeval *x
)
{
/* see timespecops.c for rationale -- this needs refactoring */
- struct timeval v;
- int s;
- int digits;
- int dig;
- char *cp;
- time_t itmp;
- long ftmp;
+ struct timeval v;
+ int s;
+ int digits;
+ int dig;
+ char * cp;
+ time_t itmp;
+ long ftmp;
s = timeval_abs(&v, x);
*cp = '\0';
/* convert fraction to decimal digits */
- for (digits = 6; digits; digits--) {
- ftmp = v.tv_usec / 10;
+ for (digits = 6; digits; digits--) {
+ ftmp = v.tv_usec / 10;
dig = (int)(v.tv_usec - ftmp * 10);
v.tv_usec = ftmp;
- *--cp = '0' + dig;
+ *--cp = '0' + (char)dig;
}
*--cp = '.';
/* convert first digit */
- itmp = v.tv_sec / 10;
+ itmp = v.tv_sec / 10;
dig = (int)(v.tv_sec - itmp * 10);
- v.tv_sec = (itmp < 0) ? -itmp : itmp;
- *--cp = '0' + ((dig < 0) ? -dig : dig);
+ v.tv_sec = max(-itmp, itmp);
+ *--cp = '0' + (char)abs(dig);
/* -*- convert remaining digits */
while (v.tv_sec != 0) {
- itmp = v.tv_sec / 10;
+ itmp = v.tv_sec / 10;
dig = (int)(v.tv_sec - itmp * 10);
v.tv_sec = itmp;
- *--cp = '0' + dig;
+ *--cp = '0' + (char)dig;
}
/* add minus sign for negative integer part */
if (s)
void
timeval_abstolfp(
- l_fp *y,
- const struct timeval *x
+ l_fp * y,
+ const struct timeval * x
)
{
struct timeval v;
void
timeval_reltolfp(
- l_fp *y,
- const struct timeval *x
+ l_fp * y,
+ const struct timeval * x
)
{
struct timeval v;
void
timeval_relfromlfp(
struct timeval *y,
- const l_fp *x)
+ const l_fp * x
+ )
{
- struct timeval out;
- l_fp tmp;
- int neg;
+ struct timeval out;
+ l_fp tmp;
+ int neg;
tmp = *x;
- if ((neg = L_ISNEG(&tmp)) != 0)
+ neg = L_ISNEG(&tmp);
+ if (neg)
L_NEG(&tmp);
MYFTOTVU(x->l_uf, out.tv_usec);
out.tv_sec = x->l_ui;
if (neg) {
- out.tv_sec = - out.tv_sec;
- out.tv_usec = - out.tv_usec;
+ out.tv_sec = -out.tv_sec;
+ out.tv_usec = -out.tv_usec;
}
COPYNORM(y, &out);
}
void
timeval_urelfromlfp(
struct timeval *y,
- const l_fp *x)
+ const l_fp * x
+ )
{
struct timeval out;
void
timeval_absfromlfp(
struct timeval *y,
- const l_fp *x,
- const time_t *p
+ const l_fp * x,
+ const time_t * p
)
{
- struct timeval out;
- vint64 sec;
+ struct timeval out;
+ vint64 sec;
sec = ntpcal_ntp_to_time(x->l_ui, p);
MYFTOTVU(x->l_uf, out.tv_usec);
/* copying a vint64 to a time_t needs some care... */
-# if SIZEOF_TIME_T == 4
+#if SIZEOF_TIME_T == 4
out.tv_sec = (time_t)sec.d_s.lo;
-# elif defined(HAVE_INT64)
+#elif defined(HAVE_INT64)
out.tv_sec = (time_t)sec.q_s;
-# else
+#else
out.tv_sec = ((time_t)sec.d_s.hi << 32) + sec.d_s.lo;
-# endif
+#endif
COPYNORM(y, &out);
}
#include <stdio.h>
#include <ctype.h>
-#ifdef HAVE_SYS_TERMIOS_H
+#if defined(HAVE_TERMIOS_H)
+# include <termios.h>
+#elif defined(HAVE_SYS_TERMIOS_H)
# include <sys/termios.h>
#endif
#ifdef HAVE_SYS_PPSCLOCK_H
#include "ntp_worker.h"
#define CHILD_EXIT_REQ ((blocking_pipe_header *)(intptr_t)-1)
+#define WORKITEMS_ALLOC_INC 16
+#define RESPONSES_ALLOC_INC 4
-blocking_pipe_header *blocking_workitems[128];
-blocking_pipe_header *blocking_responses[8];
-HANDLE blocking_child_thread;
+/*
+ * blocking workitems and blocking_responses are dynamically-sized
+ * one-dimensional arrays of pointers to blocking worker requests and
+ * responses.
+ */
+blocking_pipe_header **blocking_workitems;
+size_t blocking_workitems_alloc;
+size_t next_workitem;
+blocking_pipe_header **blocking_responses;
+size_t blocking_responses_alloc;
+size_t next_response;
+HANDLE blocking_child_thread; /* non-NULL when active */
+/* event handles (semaphore references) */
HANDLE child_is_blocking;
HANDLE wake_blocking_child;
HANDLE blocking_response_ready;
static void start_blocking_thread(void);
unsigned WINAPI blocking_thread(void *);
+static void ensure_workitems_empty_slot(void);
+static void ensure_workresp_empty_slot(void);
static int queue_req_pointer(blocking_pipe_header *);
{
DWORD rc;
- NTP_REQUIRE(seconds * 1000 < MAXDWORD);
+ DEBUG_REQUIRE(seconds * 1000 < MAXDWORD);
rc = WaitForSingleObject(wake_scheduled_sleep, (DWORD)seconds * 1000);
- NTP_INSIST(WAIT_FAILED != rc);
+ DEBUG_INSIST(WAIT_FAILED != rc);
return (WAIT_TIMEOUT == rc)
? 0
: -1;
}
+static void
+ensure_workitems_empty_slot(void)
+{
+ const size_t each = sizeof(blocking_workitems[0]);
+ size_t new_alloc;
+ size_t old_octets;
+ size_t new_octets;
+
+ if (blocking_workitems != NULL &&
+ NULL == blocking_workitems[next_workitem])
+ return;
+
+ new_alloc = blocking_workitems_alloc + WORKITEMS_ALLOC_INC;
+ old_octets = blocking_workitems_alloc * each;
+ new_octets = new_alloc * each;
+ blocking_workitems = erealloc_zero(blocking_workitems,
+ new_octets,
+ old_octets);
+ if (0 == next_workitem)
+ next_workitem = blocking_workitems_alloc;
+ blocking_workitems_alloc = new_alloc;
+}
+
+
+static void
+ensure_workresp_empty_slot(void)
+{
+ const size_t each = sizeof(blocking_responses[0]);
+ size_t new_alloc;
+ size_t old_octets;
+ size_t new_octets;
+
+ if (blocking_responses != NULL &&
+ NULL == blocking_responses[next_response])
+ return;
+
+ new_alloc = blocking_responses_alloc + RESPONSES_ALLOC_INC;
+ old_octets = blocking_responses_alloc * each;
+ new_octets = new_alloc * each;
+ blocking_responses = erealloc_zero(blocking_responses,
+ new_octets,
+ old_octets);
+ if (0 == next_response)
+ next_response = blocking_responses_alloc;
+ blocking_responses_alloc = new_alloc;
+}
+
+
/*
* queue_req_pointer() - append a work item or idle exit request to
* blocking_workitems[].
blocking_pipe_header * hdr
)
{
- static int next_workitem;
-
- if (NULL != blocking_workitems[next_workitem]) {
- DPRINTF(1, ("blocking_workitems full, max %d items\n",
- COUNTOF(blocking_workitems)));
- return -1;
- }
-
- blocking_workitems[next_workitem++] = hdr;
- if (COUNTOF(blocking_workitems) == next_workitem)
- next_workitem = 0;
+ blocking_workitems[next_workitem] = hdr;
+ next_workitem = (1 + next_workitem) % blocking_workitems_alloc;
/*
* We only want to signal the wakeup event if the child is
{
blocking_pipe_header * threadcopy;
- NTP_REQUIRE(hdr != NULL);
- NTP_REQUIRE(data != NULL);
- NTP_REQUIRE(BLOCKING_REQ_MAGIC == hdr->magic_sig);
+ DEBUG_REQUIRE(hdr != NULL);
+ DEBUG_REQUIRE(data != NULL);
+ DEBUG_REQUIRE(BLOCKING_REQ_MAGIC == hdr->magic_sig);
- if (NULL == blocking_child_thread)
+ ensure_workitems_empty_slot();
+ if (NULL == blocking_child_thread) {
+ ensure_workresp_empty_slot();
start_blocking_thread();
+ }
threadcopy = emalloc(hdr->octets);
memcpy(threadcopy, hdr, sizeof(*hdr));
void
)
{
- static int next_workitem;
+ static size_t next_workeritem;
blocking_pipe_header *req;
int once;
once = 1;
/* we block here when idle */
- if (NULL == blocking_workitems[next_workitem]) {
+ if (NULL == blocking_workitems[next_workeritem]) {
SetEvent(child_is_blocking);
- while (NULL == blocking_workitems[next_workitem])
+ while (NULL == blocking_workitems[next_workeritem])
if (WAIT_OBJECT_0 !=
WaitForSingleObject(wake_blocking_child, INFINITE)) {
DPRINTF(1, ("fatal receive_blocking_req_internal wait code\n"));
ResetEvent(child_is_blocking);
}
- req = blocking_workitems[next_workitem];
+ req = blocking_workitems[next_workeritem];
blocking_workitems[next_workitem] = NULL;
- next_workitem++;
- if (next_workitem >= COUNTOF(blocking_workitems))
- next_workitem = 0;
+ next_workeritem = (1 + next_workeritem) %
+ blocking_workitems_alloc;
if (CHILD_EXIT_REQ == req) /* idled out */
req = NULL;
blocking_pipe_header *resp
)
{
- static int next_blocking_response;
-
- if (NULL != blocking_responses[next_blocking_response]) {
- DPRINTF(1, ("blocking_responses full, max %d items\n",
- COUNTOF(blocking_workitems)));
- return -1;
- }
+ ensure_workresp_empty_slot();
- blocking_responses[next_blocking_response] = resp;
- next_blocking_response++;
- if (COUNTOF(blocking_responses) == next_blocking_response)
- next_blocking_response = 0;
+ blocking_responses[next_response] = resp;
+ next_response = (1 + next_response) % blocking_responses_alloc;
SetEvent(blocking_response_ready);
void
)
{
- static int next_blocking_response;
+ static size_t next_workresp;
blocking_pipe_header * retval;
- retval = blocking_responses[next_blocking_response];
+ retval = blocking_responses[next_workresp];
if (NULL != retval) {
- blocking_responses[next_blocking_response] = NULL;
- next_blocking_response++;
- if (next_blocking_response == COUNTOF(blocking_responses))
- next_blocking_response = 0;
- NTP_ENSURE(BLOCKING_RESP_MAGIC == retval->magic_sig);
+ blocking_responses[next_workresp] = NULL;
+ next_workresp = (1 + next_workresp) %
+ blocking_responses_alloc;
+ DEBUG_ENSURE(BLOCKING_RESP_MAGIC == retval->magic_sig);
}
return retval;
void
worker_idle_timer_fired(void)
{
- NTP_REQUIRE(0 == intres_req_pending);
+ DEBUG_REQUIRE(0 == intres_req_pending);
worker_idle_timer = 0;
if (NULL != blocking_child_thread) {
# End Source File\r
# Begin Source File\r
\r
+SOURCE=..\libntp\termios.c\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=..\..\..\lib\isc\win32\thread.c\r
# End Source File\r
# Begin Source File\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=..\..\..\libntp\tsftomsu.c\r
+SOURCE=..\..\..\libntp\timespecops.c\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=..\libntp\termios.c\r
+SOURCE=..\..\..\libntp\timevalops.c\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=..\..\..\libntp\tsftomsu.c\r
# End Source File\r
# Begin Source File\r
\r
<File
RelativePath="..\..\..\lib\isc\task.c">
</File>
+ <File
+ RelativePath="..\libntp\termios.c">
+ </File>
<File
RelativePath="..\..\..\lib\isc\win32\thread.c">
</File>
RelativePath="..\..\..\lib\isc\win32\time.c">
</File>
<File
- RelativePath="..\libntp\termios.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"
- BrowseInformation="1"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
- </FileConfiguration>
+ RelativePath="..\libntp\timespecops.c">
+ </File>
+ <File
+ RelativePath="..\libntp\timevalops.c">
</File>
<File
RelativePath="..\..\..\libntp\tsftomsu.c">
RelativePath="..\..\..\lib\isc\win32\time.c"
>
</File>
+ <File
+ RelativePath="..\..\..\libntp\timespecops.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\libntp\timevalops.c"
+ >
+ </File>
<File
RelativePath="..\..\..\libntp\tsftomsu.c"
>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
</File>
<File
RelativePath="..\..\..\libntp\tstotv.c"
RelativePath="..\..\..\..\lib\isc\win32\time.c"
>
</File>
+ <File
+ RelativePath="..\..\..\..\libntp\timespecops.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\libntp\timevalops.c"
+ >
+ </File>
<File
RelativePath="..\..\..\..\libntp\tsftomsu.c"
>
RelativePath="..\..\..\..\lib\isc\win32\include\isc\time.h"
>
</File>
+ <File
+ RelativePath="..\..\include\sys\time.h"
+ >
+ </File>
<File
RelativePath="..\..\..\..\lib\isc\win32\include\isc\time.h"
>
</File>
<File
- RelativePath="..\..\include\sys\time.h"
+ RelativePath="..\..\..\..\include\timespecops.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\timevalops.h"
>
</File>
<File
{ 956805507, 0xf4f134a9 }, { 982570733, 0xfb89c16c }
};
-struct TSPEC{
+class TSPEC {
+public:
struct timespec V;
TSPEC()
{ ZERO(V); }
TSPEC(time_t hi, long lo)
{ V.tv_sec = hi; V.tv_nsec = lo; }
- bool operator == (const TSPEC &rhs) const
+ bool operator == (const TSPEC& rhs) const
{ return timespec_cmp(&V, &rhs.V) == 0; }
bool valid() const
{ return timespec_isnormal(&V); }
{ return &V; }
operator struct timespec& ()
{ return V; }
- TSPEC &operator=(const TSPEC &rhs)
+ TSPEC& operator = (const TSPEC& rhs)
{ V = rhs.V; return *this; }
- TSPEC &operator=(const struct timespec &rhs)
+ TSPEC& operator = (const struct timespec& rhs)
{ V = rhs; return *this; }
};
static std::ostream&
-operator << (std::ostream& os, const TSPEC &val)
+operator << (std::ostream& os, const TSPEC& val)
{
os << timespec_tostr(&val.V);
return os;
}
-struct LFP {
+class LFP {
+public:
l_fp V;
LFP()
{ ZERO(V); }
LFP(u_int32 hi, u_int32 lo)
{ V.l_ui = hi; V.l_uf = lo; }
- bool operator == (const LFP &rhs) const
+ bool operator == (const LFP& rhs) const
{ return L_ISEQU(&V, &rhs.V); }
operator l_fp* ()
{ return &V; }
operator l_fp& ()
- { return V; }
- LFP &operator=(const LFP &rhs)
+ { return V; }
+ LFP& operator = (const LFP& rhs)
{ V = rhs.V; return *this; }
- LFP &operator=(const l_fp &rhs)
+ LFP& operator = (const l_fp& rhs)
{ V = rhs; return *this; }
};
// sign test, no fraction
for (int i = -4; i <= 4; ++i) {
TSPEC a(i, 0);
- int E = (i>0) - (i<0);
+ int E = (i > 0) - (i < 0);
int r = timespec_test(a);
ASSERT_EQ(E, r);
}
// sign test, with fraction
for (int i = -4; i <= 4; ++i) {
TSPEC a(i, 10);
- int E = (i>=0) - (i<0);
+ int E = (i >= 0) - (i < 0);
int r = timespec_test(a);
+
ASSERT_EQ(E, r);
}
}
TSPEC b( j , 200);
int E = (i > j) - (i < j);
int r = timespec_cmp(a, b);
+
ASSERT_EQ(E, r);
}
}
// fraction a bigger fraction b
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TSPEC a( i , 999999800);
- TSPEC b( j , 200);
+ TSPEC a(i, 999999800);
+ TSPEC b(j, 200);
int E = (i >= j) - (i < j);
int r = timespec_cmp(a, b);
+
ASSERT_EQ(E, r);
}
}
// fraction a less fraction b
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TSPEC a( i , 200);
- TSPEC b( j , 999999800);
+ TSPEC a(i, 200);
+ TSPEC b(j, 999999800);
int E = (i > j) - (i <= j);
int r = timespec_cmp(a, b);
+
ASSERT_EQ(E, r);
}
}
TEST_F(timespecTest, AddFullNorm) {
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TSPEC a( i , 200);
- TSPEC b( j , 400);
- TSPEC E(i+j, 600);
+ TSPEC a(i, 200);
+ TSPEC b(j, 400);
+ TSPEC E(i + j, 200 + 400);
TSPEC c;
+
timespec_add(c, a, b);
ASSERT_EQ(E, c);
}
TEST_F(timespecTest, AddFullOflow1) {
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TSPEC a( i , 200);
- TSPEC b( j , 999999900);
- TSPEC E(i+j+1, 100);
+ TSPEC a(i, 200);
+ TSPEC b(j, 999999900);
+ TSPEC E(i + j + 1, 100);
TSPEC c;
+
timespec_add(c, a, b);
ASSERT_EQ(E, c);
}
TSPEC a(i, 200);
TSPEC E(i, 600);
TSPEC c;
+
timespec_addns(c, a, 400);
ASSERT_EQ(E, c);
}
TEST_F(timespecTest, AddNsecOflow1) {
for (int i = -4; i <= 4; ++i) {
- TSPEC a( i , 200);
- TSPEC E(i+1, 100);
+ TSPEC a(i, 200);
+ TSPEC E(i + 1, 100);
TSPEC c;
+
timespec_addns(c, a, NANOSECONDS - 100);
ASSERT_EQ(E, c);
}
TSPEC b( j , 400);
TSPEC E(i-j, 200);
TSPEC c;
+
timespec_sub(c, a, b);
ASSERT_EQ(E, c);
}
TSPEC b( j , 999999900);
TSPEC E(i-j-1, 200);
TSPEC c;
+
timespec_sub(c, a, b);
ASSERT_EQ(E, c);
}
TSPEC a(i, 600);
TSPEC E(i, 200);
TSPEC c;
+
timespec_subns(c, a, 400);
ASSERT_EQ(E, c);
}
TSPEC a( i , 100);
TSPEC E(i-1, 200);
TSPEC c;
+
timespec_subns(c, a, NANOSECONDS - 100);
ASSERT_EQ(E, c);
}
TSPEC a( i , 100);
TSPEC b;
TSPEC c;
+
timespec_neg(b, a);
timespec_add(c, a, b);
ASSERT_EQ(0, timespec_test(c));
TSPEC a(i , 0);
TSPEC b;
int c;
+
c = timespec_abs(b, a);
ASSERT_EQ((i < 0), c);
ASSERT_EQ((i != 0), timespec_test(b));
TSPEC a(i , 100);
TSPEC b;
int c;
+
c = timespec_abs(b, a);
ASSERT_EQ((i < 0), c);
ASSERT_EQ(1, timespec_test(b));
// conversion to l_fp
TEST_F(timespecTest, ToLFPrelPos) {
- for (int i = 0; i < sizeof(fdata)/sizeof(*fdata); ++i) {
+ for (int i = 0; i < COUNTOF(fdata); i++) {
TSPEC a(1, fdata[i].nsec);
LFP E(1, fdata[i].frac);
LFP r;
+
timespec_reltolfp(r, a);
ASSERT_EQ(E, r);
}
}
TEST_F(timespecTest, ToLFPrelNeg) {
- for (int i = 0; i < sizeof(fdata)/sizeof(*fdata); ++i) {
+ for (int i = 0; i < COUNTOF(fdata); i++) {
TSPEC a(-1, fdata[i].nsec);
LFP E(~0, fdata[i].frac);
LFP r;
+
timespec_reltolfp(r, a);
ASSERT_EQ(E, r);
}
}
TEST_F(timespecTest, ToLFPabs) {
- for (int i = 0; i < sizeof(fdata)/sizeof(*fdata); ++i) {
- TSPEC a(1 , fdata[i].nsec);
- LFP E(1+JAN_1970, fdata[i].frac);
+ for (int i = 0; i < COUNTOF(fdata); i++) {
+ TSPEC a(1, fdata[i].nsec);
+ LFP E(1 + JAN_1970, fdata[i].frac);
LFP r;
+
timespec_abstolfp(r, a);
ASSERT_EQ(E, r);
}
TEST_F(timespecTest, ToString) {
static const struct {
- time_t sec;
- long nsec;
- const char *repr;
+ time_t sec;
+ long nsec;
+ const char * repr;
} data [] = {
{ 0, 0, "0.000000000" },
{ 2, 0, "2.000000000" },
{ 1,-1, "0.999999999" },
{-1, 1, "-0.999999999" }
};
- for (int i = 0; i < sizeof(data)/sizeof(*data); ++i) {
+ for (int i = 0; i < COUNTOF(data); i++) {
TSPEC a(data[i].sec, data[i].nsec);
std::string E(data[i].repr);
std::string r(timespec_tostr(a));
+
ASSERT_EQ(E, r);
}
}
#include "libntptest.h"
extern "C" {
+#include <math.h>
#include "timevalops.h"
}
// that's it...
struct lfpfracdata {
long usec;
- u_int32 frac;
+ u_int32 frac;
};
static const lfpfracdata fdata[];
};
};
-struct TVAL{
+class TVAL {
+public:
struct timeval V;
TVAL()
{ ZERO(V); }
TVAL(time_t hi, long lo)
{ V.tv_sec = hi; V.tv_usec = lo; }
- bool operator == (const TVAL &rhs) const
+ bool operator == (const TVAL& rhs) const
{ return timeval_cmp(&V, &rhs.V) == 0; }
bool valid() const
{ return timeval_isnormal(&V); }
operator struct timeval* ()
{ return &V; }
operator struct timeval& ()
- { return V; }
- TVAL &operator=(const TVAL &rhs)
+ { return V; }
+ TVAL& operator = (const TVAL& rhs)
{ V = rhs.V; return *this; }
- TVAL &operator=(const struct timeval &rhs)
+ TVAL& operator = (const struct timeval& rhs)
{ V = rhs; return *this; }
};
std::ostream&
-operator << (std::ostream& os, const TVAL &val)
+operator << (std::ostream& os, const TVAL& val)
{
os << timeval_tostr(&val.V);
return os;
}
-struct LFP {
+class LFP {
+public:
l_fp V;
LFP()
{ ZERO(V); }
LFP(u_int32 hi, u_int32 lo)
{ V.l_ui = hi; V.l_uf = lo; }
- bool operator == (const LFP &rhs) const
+ bool operator == (const LFP& rhs) const
{ return L_ISEQU(&V, &rhs.V); }
operator l_fp* ()
{ return &V; }
operator l_fp& ()
- { return V; }
- LFP &operator=(const LFP &rhs)
+ { return V; }
+ LFP& operator = (const LFP& rhs)
{ V = rhs.V; return *this; }
- LFP &operator=(const l_fp &rhs)
+ LFP& operator = (const l_fp& rhs)
{ V = rhs; return *this; }
};
static std::ostream&
-operator << (std::ostream& os, const LFP &val)
+operator << (std::ostream& os, const LFP& val)
{
os << ulfptoa(&val.V, 10);
return os;
TEST_F(timevalTest, Normalise) {
for (long ns = -2000000000; ns <= 2000000000; ns += 10000000) {
- TVAL x(0, ns);
+ TVAL x(0, ns);
+
timeval_norm(x);
ASSERT_TRUE(x.valid());
}
TEST_F(timevalTest, SignNoFrac) {
// sign test, no fraction
for (int i = -4; i <= 4; ++i) {
- TVAL a(i, 0);
- int E = (i>0) - (i<0);
- int r = timeval_test(a);
+ TVAL a(i, 0);
+ int E = (i > 0) - (i < 0);
+ int r = timeval_test(a);
+
ASSERT_EQ(E, r);
}
}
TEST_F(timevalTest, SignWithFrac) {
// sign test, with fraction
for (int i = -4; i <= 4; ++i) {
- TVAL a(i, 10);
- int E = (i>=0) - (i<0);
- int r = timeval_test(a);
+ TVAL a(i, 10);
+ int E = (i >= 0) - (i < 0);
+ int r = timeval_test(a);
+
ASSERT_EQ(E, r);
}
}
// fractions are equal
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TVAL a( i , 200);
- TVAL b( j , 200);
- int E = (i > j) - (i < j);
- int r = timeval_cmp(a, b);
+ TVAL a(i, 200);
+ TVAL b(j, 200);
+ int E = (i > j) - (i < j);
+ int r = timeval_cmp(a, b);
+
ASSERT_EQ(E, r);
}
}
// fraction a bigger fraction b
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TVAL a( i , 999800);
- TVAL b( j , 200);
- int E = (i >= j) - (i < j);
- int r = timeval_cmp(a, b);
+ TVAL a( i , 999800);
+ TVAL b( j , 200);
+ int E = (i >= j) - (i < j);
+ int r = timeval_cmp(a, b);
+
ASSERT_EQ(E, r);
}
}
// fraction a less fraction b
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TVAL a( i , 200);
- TVAL b( j , 999800);
- int E = (i > j) - (i <= j);
- int r = timeval_cmp(a, b);
+ TVAL a(i, 200);
+ TVAL b(j, 999800);
+ int E = (i > j) - (i <= j);
+ int r = timeval_cmp(a, b);
+
ASSERT_EQ(E, r);
}
}
TEST_F(timevalTest, AddFullNorm) {
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TVAL a( i , 200);
- TVAL b( j , 400);
- TVAL E(i+j, 600);
+ TVAL a(i, 200);
+ TVAL b(j, 400);
+ TVAL E(i + j, 200 + 400);
TVAL c;
+
timeval_add(c, a, b);
ASSERT_EQ(E, c);
}
TEST_F(timevalTest, AddFullOflow1) {
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TVAL a( i , 200);
- TVAL b( j , 999900);
- TVAL E(i+j+1, 100);
+ TVAL a(i, 200);
+ TVAL b(j, 999900);
+ TVAL E(i + j + 1, 100);
TVAL c;
timeval_add(c, a, b);
ASSERT_EQ(E, c);
TVAL a(i, 200);
TVAL E(i, 600);
TVAL c;
+
timeval_addus(c, a, 400);
ASSERT_EQ(E, c);
}
TEST_F(timevalTest, AddUsecOflow1) {
for (int i = -4; i <= 4; ++i) {
- TVAL a( i , 200);
- TVAL E(i+1, 100);
+ TVAL a(i, 200);
+ TVAL E(i + 1, 100);
TVAL c;
+
timeval_addus(c, a, MICROSECONDS - 100);
ASSERT_EQ(E, c);
}
TEST_F(timevalTest, SubFullNorm) {
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TVAL a( i , 600);
- TVAL b( j , 400);
- TVAL E(i-j, 200);
+ TVAL a(i, 600);
+ TVAL b(j, 400);
+ TVAL E(i - j, 600 - 400);
TVAL c;
+
timeval_sub(c, a, b);
ASSERT_EQ(E, c);
}
TEST_F(timevalTest, SubFullOflow) {
for (int i = -4; i <= 4; ++i)
for (int j = -4; j <= 4; ++j) {
- TVAL a( i , 100);
- TVAL b( j , 999900);
- TVAL E(i-j-1, 200);
+ TVAL a(i, 100);
+ TVAL b(j, 999900);
+ TVAL E(i - j - 1, 200);
TVAL c;
+
timeval_sub(c, a, b);
ASSERT_EQ(E, c);
}
TVAL a(i, 600);
TVAL E(i, 200);
TVAL c;
- timeval_subus(c, a, 400);
+
+ timeval_subus(c, a, 600 - 200);
ASSERT_EQ(E, c);
}
}
TEST_F(timevalTest, SubUsecOflow) {
for (int i = -4; i <= 4; ++i) {
- TVAL a( i , 100);
- TVAL E(i-1, 200);
+ TVAL a(i, 100);
+ TVAL E(i - 1, 200);
TVAL c;
+
timeval_subus(c, a, MICROSECONDS - 100);
ASSERT_EQ(E, c);
}
// test negation
TEST_F(timevalTest, Neg) {
for (int i = -4; i <= 4; ++i) {
- TVAL a( i , 100);
+ TVAL a(i, 100);
TVAL b;
TVAL c;
timeval_neg(b, a);
// test abs value
TEST_F(timevalTest, AbsNoFrac) {
for (int i = -4; i <= 4; ++i) {
- TVAL a(i , 0);
- TVAL b;
- int c;
+ TVAL a(i, 0);
+ TVAL b;
+ int c;
+
c = timeval_abs(b, a);
ASSERT_EQ((i < 0), c);
ASSERT_EQ((i != 0), timeval_test(b));
TEST_F(timevalTest, AbsWithFrac) {
for (int i = -4; i <= 4; ++i) {
- TVAL a(i , 100);
- TVAL b;
- int c;
+ TVAL a(i, 100);
+ TVAL b;
+ int c;
+
c = timeval_abs(b, a);
ASSERT_EQ((i < 0), c);
ASSERT_EQ(1, timeval_test(b));
// conversion to l_fp
TEST_F(timevalTest, ToLFPrelPos) {
- for (int i = 0; i < sizeof(fdata)/sizeof(*fdata); ++i) {
- TVAL a(1, fdata[i].usec);
- LFP E(1, fdata[i].frac);
- LFP r;
+ for (int i = 0; i < COUNTOF(fdata); i++) {
+ TVAL a(1, fdata[i].usec);
+ LFP E(1, fdata[i].frac);
+ LFP r;
+ double Ef;
+ double rf;
+
timeval_reltolfp(r, a);
- ASSERT_EQ(E, r);
+ LFPTOD(&E.V, Ef);
+ LFPTOD(&r.V, rf);
+ ASSERT_NEAR(Ef, rf, 1. / MICROSECONDS);
}
}
TEST_F(timevalTest, ToLFPrelNeg) {
- for (int i = 0; i < sizeof(fdata)/sizeof(*fdata); ++i) {
- TVAL a(-1, fdata[i].usec);
- LFP E(~0, fdata[i].frac);
- LFP r;
+ for (int i = 0; i < COUNTOF(fdata); i++) {
+ TVAL a(-1, fdata[i].usec);
+ LFP E(~0, fdata[i].frac);
+ LFP r;
+ double Ef;
+ double rf;
+
timeval_reltolfp(r, a);
- ASSERT_EQ(E, r);
+ LFPTOD(&E.V, Ef);
+ LFPTOD(&r.V, rf);
+ ASSERT_NEAR(Ef, rf, 1. / MICROSECONDS);
}
}
TEST_F(timevalTest, ToLFPabs) {
- for (int i = 0; i < sizeof(fdata)/sizeof(*fdata); ++i) {
- TVAL a(1 , fdata[i].usec);
- LFP E(1+JAN_1970, fdata[i].frac);
- LFP r;
+ for (int i = 0; i < COUNTOF(fdata); i++) {
+ TVAL a(1, fdata[i].usec);
+ LFP E(1 + JAN_1970, fdata[i].frac);
+ LFP r;
+ double Ef;
+ double rf;
+
timeval_abstolfp(r, a);
- ASSERT_EQ(E, r);
+ LFPTOD(&E.V, Ef);
+ LFPTOD(&r.V, rf);
+ ASSERT_NEAR(Ef, rf, 1. / MICROSECONDS);
}
}
TEST_F(timevalTest, ToString) {
static const struct {
- time_t sec;
- long usec;
- const char *repr;
+ time_t sec;
+ long usec;
+ const char * repr;
} data [] = {
{ 0, 0, "0.000000" },
{ 2, 0, "2.000000" },
{ 1,-1, "0.999999" },
{-1, 1, "-0.999999" }
};
- for (int i = 0; i < sizeof(data)/sizeof(*data); ++i) {
+ for (int i = 0; i < COUNTOF(data); ++i) {
TVAL a(data[i].sec, data[i].usec);
std::string E(data[i].repr);
std::string r(timeval_tostr(a));
+
ASSERT_EQ(E, r);
}
}
passwd2 = NULL;
gettimeofday(&tv, 0);
epoch = tv.tv_sec;
- fstamp = epoch + JAN_1970;
+ fstamp = (u_int)(epoch + JAN_1970);
{
int optct = ntpOptionProcess(&ntp_keygenOptions,