diff --git a/hawk/lib/hawk-cmn.h b/hawk/lib/hawk-cmn.h index 15e041e3..3c50d05a 100644 --- a/hawk/lib/hawk-cmn.h +++ b/hawk/lib/hawk-cmn.h @@ -647,11 +647,14 @@ struct hawk_link_t #define HAWK_SEC_TO_USEC(sec) ((sec) * HAWK_USECS_PER_SEC) #define HAWK_USEC_TO_SEC(usec) ((usec) / HAWK_USECS_PER_SEC) +typedef hawk_int64_t hawk_ntime_sec_t; +typedef hawk_int32_t hawk_ntime_nsec_t; + typedef struct hawk_ntime_t hawk_ntime_t; struct hawk_ntime_t { - hawk_intptr_t sec; - hawk_int32_t nsec; /* nanoseconds */ + hawk_ntime_sec_t sec; + hawk_ntime_nsec_t nsec; /* nanoseconds */ }; #define HAWK_INIT_NTIME(c,s,ns) (((c)->sec = (s)), ((c)->nsec = (ns))) diff --git a/hawk/lib/hawk-utl.h b/hawk/lib/hawk-utl.h index eaeebfb1..9201b28c 100644 --- a/hawk/lib/hawk-utl.h +++ b/hawk/lib/hawk-utl.h @@ -1607,24 +1607,31 @@ HAWK_EXPORT int hawk_qsortx ( /* ========================================================================= * TIME * ========================================================================= */ -HAWK_EXPORT int hawk_get_time ( +HAWK_EXPORT int hawk_get_ntime ( hawk_ntime_t* t ); -HAWK_EXPORT int hawk_set_time ( +HAWK_EXPORT int hawk_set_ntime ( const hawk_ntime_t* t ); -HAWK_EXPORT void hawk_add_time ( +/** + * The hawk_add_ntime() adds two time structures pointed to by x and y and + * stores the result in z. Upon overflow, it sets z to the largest value + * the hawk_ntime_t type can represent. Upon underflow, it sets z to the + * smallest value. If you don't need this extra range check, you may use + * the HAWK_ADD_NTIME() macro. + */ +HAWK_EXPORT void hawk_add_ntime ( + hawk_ntime_t* z, const hawk_ntime_t* x, - const hawk_ntime_t* y, - hawk_ntime_t* z + const hawk_ntime_t* y ); -HAWK_EXPORT void hawk_sub_time ( +HAWK_EXPORT void hawk_sub_ntime ( + hawk_ntime_t* z, const hawk_ntime_t* x, - const hawk_ntime_t* y, - hawk_ntime_t* z + const hawk_ntime_t* y ); diff --git a/hawk/lib/mod-math.c b/hawk/lib/mod-math.c index b0b576bc..8cb9cd8d 100644 --- a/hawk/lib/mod-math.c +++ b/hawk/lib/mod-math.c @@ -572,7 +572,7 @@ static int fnc_srand (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) if (nargs <= 0) { hawk_ntime_t tv; - hawk_get_time (&tv); + hawk_get_ntime (&tv); modctx->seed = tv.sec + tv.nsec; #if defined(HAVE_INITSTATE_R) && defined(HAVE_SRANDOM_R) && defined(HAVE_RANDOM_R) srandom_r (modctx->seed, &modctx->prand); @@ -710,7 +710,7 @@ int hawk_mod_math (hawk_mod_t* mod, hawk_t* hawk) HAWK_MEMSET (modctx, 0, HAWK_SIZEOF(*modctx)); - hawk_get_time (&tv); + hawk_get_ntime (&tv); modctx->seed = tv.sec + tv.nsec; #if defined(HAVE_INITSTATE_R) && defined(HAVE_SRANDOM_R) && defined(HAVE_RANDOM_R) initstate_r (0, modctx->prand_bin, HAWK_SIZEOF(modctx->prand_bin), &modctx->prand); diff --git a/hawk/lib/mod-sys.c b/hawk/lib/mod-sys.c index a2dff070..1e0ba9d6 100644 --- a/hawk/lib/mod-sys.c +++ b/hawk/lib/mod-sys.c @@ -2329,7 +2329,7 @@ static int fnc_gettime (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) hawk_val_t* retv; hawk_ntime_t now; - if (hawk_get_time(&now) <= -1) now.sec = 0; + if (hawk_get_ntime(&now) <= -1) now.sec = 0; retv = hawk_rtx_makeintval(rtx, now.sec); if (!retv) return -1; @@ -2351,7 +2351,7 @@ static int fnc_settime (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) else { now.sec = tmp; - if (hawk_set_time(&now) <= -1) rx = -1; + if (hawk_set_ntime(&now) <= -1) rx = -1; else rx = 0; } @@ -2440,7 +2440,7 @@ static int fnc_mktime (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) else { /* get the current time when no argument is given */ - hawk_get_time (&nt); + hawk_get_ntime (&nt); } retv = hawk_rtx_makeintval(rtx, nt.sec); @@ -4677,7 +4677,7 @@ static int fnc_writelog (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) if (!mctx->log.dmsgbuf) goto fail; } - if (hawk_get_time(&now) <= -1) + if (hawk_get_ntime(&now) <= -1) { rx = set_error_on_sys_list(rtx, sys_list, HAWK_ESYSERR, HAWK_T("unable to get time")); goto done; diff --git a/hawk/lib/mtx.c b/hawk/lib/mtx.c index c133aea8..c0d41d96 100644 --- a/hawk/lib/mtx.c +++ b/hawk/lib/mtx.c @@ -233,8 +233,8 @@ int hawk_mtx_lock (hawk_mtx_t* mtx, const hawk_ntime_t* waiting_time) struct timespec ts; int n; - hawk_get_time (&t); - hawk_add_time (&t, waiting_time, &t); + hawk_get_ntime (&t); + hawk_add_ntime (&t, waiting_time, &t); ts.tv_sec = t.sec; ts.tv_nsec = t.nsec; @@ -326,7 +326,7 @@ int hawk_mtx_trylock (hawk_mtx_t* mtx) #elif defined(HAVE_PTHREAD_MUTEX_TIMEDLOCK) hawk_ntime_t t; struct timespec ts; - hawk_get_time (&t); + hawk_get_ntime (&t); ts.tv_sec = t.sec; ts.tv_nsec = t.nsec; n = pthread_mutex_timedlock((pthread_mutex_t*)&mtx->hnd, &ts); diff --git a/hawk/lib/utl-sys.c b/hawk/lib/utl-sys.c index 1adb14c6..4ced2c3e 100644 --- a/hawk/lib/utl-sys.c +++ b/hawk/lib/utl-sys.c @@ -50,7 +50,7 @@ # endif #endif -int hawk_get_time (hawk_ntime_t* t) +int hawk_get_ntime (hawk_ntime_t* t) { #if defined(_WIN32) SYSTEMTIME st; @@ -161,7 +161,7 @@ int hawk_get_time (hawk_ntime_t* t) #endif } -int hawk_set_time (const hawk_ntime_t* t) +int hawk_set_ntime (const hawk_ntime_t* t) { #if defined(_WIN32) FILETIME ft; @@ -243,6 +243,7 @@ int hawk_set_time (const hawk_ntime_t* t) #endif } +#if 0 void hawk_add_time (const hawk_ntime_t* x, const hawk_ntime_t* y, hawk_ntime_t* z) { /*HAWK_ASSERT (x->nsec >= 0 && x->nsec < HAWK_NSECS_PER_SEC); @@ -272,4 +273,112 @@ void hawk_sub_time (const hawk_ntime_t* x, const hawk_ntime_t* y, hawk_ntime_t* z->nsec = z->nsec + HAWK_NSECS_PER_SEC; } } +#endif +void hawk_add_ntime (hawk_ntime_t* z, const hawk_ntime_t* x, const hawk_ntime_t* y) +{ + hawk_ntime_sec_t xs, ys; + hawk_ntime_nsec_t ns; + + HAWK_ASSERT (x->nsec >= 0 && x->nsec < HAWK_NSECS_PER_SEC); + HAWK_ASSERT (y->nsec >= 0 && y->nsec < HAWK_NSECS_PER_SEC); + + ns = x->nsec + y->nsec; + if (ns >= HAWK_NSECS_PER_SEC) + { + ns = ns - HAWK_NSECS_PER_SEC; + if (x->sec == HAWK_TYPE_MAX(hawk_ntime_sec_t)) + { + if (y->sec >= 0) goto overflow; + xs = x->sec; + ys = y->sec + 1; /* this won't overflow */ + } + else + { + xs = x->sec + 1; /* this won't overflow */ + ys = y->sec; + } + } + else + { + xs = x->sec; + ys = y->sec; + } + + if ((ys >= 1 && xs > HAWK_TYPE_MAX(hawk_ntime_sec_t) - ys) || + (ys <= -1 && xs < HAWK_TYPE_MIN(hawk_ntime_sec_t) - ys)) + { + if (xs >= 0) + { + overflow: + xs = HAWK_TYPE_MAX(hawk_ntime_sec_t); + ns = HAWK_NSECS_PER_SEC - 1; + } + else + { + xs = HAWK_TYPE_MIN(hawk_ntime_sec_t); + ns = 0; + } + } + else + { + xs = xs + ys; + } + + z->sec = xs; + z->nsec = ns; +} + +void hawk_sub_ntime (hawk_ntime_t* z, const hawk_ntime_t* x, const hawk_ntime_t* y) +{ + hawk_ntime_sec_t xs, ys; + hawk_ntime_nsec_t ns; + + HAWK_ASSERT (x->nsec >= 0 && x->nsec < HAWK_NSECS_PER_SEC); + HAWK_ASSERT (y->nsec >= 0 && y->nsec < HAWK_NSECS_PER_SEC); + + ns = x->nsec - y->nsec; + if (ns < 0) + { + ns = ns + HAWK_NSECS_PER_SEC; + if (x->sec == HAWK_TYPE_MIN(hawk_ntime_sec_t)) + { + if (y->sec <= 0) goto underflow; + xs = x->sec; + ys = y->sec - 1; /* this won't underflow */ + } + else + { + xs = x->sec - 1; /* this won't underflow */ + ys = y->sec; + } + } + else + { + xs = x->sec; + ys = y->sec; + } + + if ((ys >= 1 && xs < HAWK_TYPE_MIN(hawk_ntime_sec_t) + ys) || + (ys <= -1 && xs > HAWK_TYPE_MAX(hawk_ntime_sec_t) + ys)) + { + if (xs >= 0) + { + xs = HAWK_TYPE_MAX(hawk_ntime_sec_t); + ns = HAWK_NSECS_PER_SEC - 1; + } + else + { + underflow: + xs = HAWK_TYPE_MIN(hawk_ntime_sec_t); + ns = 0; + } + } + else + { + xs = xs - ys; + } + + z->sec = xs; + z->nsec = ns; +} diff --git a/hawk/t/Makefile.am b/hawk/t/Makefile.am index 03b8f771..945b9008 100644 --- a/hawk/t/Makefile.am +++ b/hawk/t/Makefile.am @@ -16,7 +16,7 @@ check_SCRIPTS = h-001.hawk ##noinst_SCRIPTS = $(check_SCRIPTS) EXTRA_DIST = $(check_SCRIPTS) -check_PROGRAMS = t-001 t-002 t-003 t-004 t-005 +check_PROGRAMS = t-001 t-002 t-003 t-004 t-005 t-006 t_001_SOURCES = t-001.c t.h @@ -36,6 +36,10 @@ t_005_SOURCES = t-005.c t.h t_005_LDADD = -lhawk $(LDADD) t_005_DEPENDENCIES = ../lib/libhawk.la +t_006_SOURCES = t-006.c t.h +t_006_LDADD = -lhawk $(LDADD) +t_006_DEPENDENCIES = ../lib/libhawk.la + TESTS = $(check_PROGRAMS) $(check_SCRIPTS) diff --git a/hawk/t/Makefile.in b/hawk/t/Makefile.in index 26297b36..ca95a7aa 100644 --- a/hawk/t/Makefile.in +++ b/hawk/t/Makefile.in @@ -88,7 +88,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ check_PROGRAMS = t-001$(EXEEXT) t-002$(EXEEXT) t-003$(EXEEXT) \ - t-004$(EXEEXT) t-005$(EXEEXT) + t-004$(EXEEXT) t-005$(EXEEXT) t-006$(EXEEXT) subdir = t ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \ @@ -125,6 +125,8 @@ am_t_004_OBJECTS = t-004.$(OBJEXT) t_004_OBJECTS = $(am_t_004_OBJECTS) am_t_005_OBJECTS = t-005.$(OBJEXT) t_005_OBJECTS = $(am_t_005_OBJECTS) +am_t_006_OBJECTS = t-006.$(OBJEXT) +t_006_OBJECTS = $(am_t_006_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -141,7 +143,8 @@ DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/ac/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/t-001.Po ./$(DEPDIR)/t-002.Po \ - ./$(DEPDIR)/t-003.Po ./$(DEPDIR)/t-004.Po ./$(DEPDIR)/t-005.Po + ./$(DEPDIR)/t-003.Po ./$(DEPDIR)/t-004.Po ./$(DEPDIR)/t-005.Po \ + ./$(DEPDIR)/t-006.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -162,9 +165,9 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(t_001_SOURCES) $(t_002_SOURCES) $(t_003_SOURCES) \ - $(t_004_SOURCES) $(t_005_SOURCES) + $(t_004_SOURCES) $(t_005_SOURCES) $(t_006_SOURCES) DIST_SOURCES = $(t_001_SOURCES) $(t_002_SOURCES) $(t_003_SOURCES) \ - $(t_004_SOURCES) $(t_005_SOURCES) + $(t_004_SOURCES) $(t_005_SOURCES) $(t_006_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -569,6 +572,9 @@ t_004_DEPENDENCIES = ../lib/libhawk.la t_005_SOURCES = t-005.c t.h t_005_LDADD = -lhawk $(LDADD) t_005_DEPENDENCIES = ../lib/libhawk.la +t_006_SOURCES = t-006.c t.h +t_006_LDADD = -lhawk $(LDADD) +t_006_DEPENDENCIES = ../lib/libhawk.la TESTS = $(check_PROGRAMS) $(check_SCRIPTS) TEST_EXTENSIONS = .hawk HAWK_LOG_COMPILER = ../bin/hawk @@ -636,6 +642,10 @@ t-005$(EXEEXT): $(t_005_OBJECTS) $(t_005_DEPENDENCIES) $(EXTRA_t_005_DEPENDENCIE @rm -f t-005$(EXEEXT) $(AM_V_CCLD)$(LINK) $(t_005_OBJECTS) $(t_005_LDADD) $(LIBS) +t-006$(EXEEXT): $(t_006_OBJECTS) $(t_006_DEPENDENCIES) $(EXTRA_t_006_DEPENDENCIES) + @rm -f t-006$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(t_006_OBJECTS) $(t_006_LDADD) $(LIBS) + mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -647,6 +657,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-003.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-004.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-005.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-006.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @@ -912,6 +923,13 @@ t-005.log: t-005$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +t-006.log: t-006$(EXEEXT) + @p='t-006$(EXEEXT)'; \ + b='t-006'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) .hawk.log: @p='$<'; \ $(am__set_b); \ @@ -1010,6 +1028,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/t-003.Po -rm -f ./$(DEPDIR)/t-004.Po -rm -f ./$(DEPDIR)/t-005.Po + -rm -f ./$(DEPDIR)/t-006.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -1060,6 +1079,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/t-003.Po -rm -f ./$(DEPDIR)/t-004.Po -rm -f ./$(DEPDIR)/t-005.Po + -rm -f ./$(DEPDIR)/t-006.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/hawk/t/t-006.c b/hawk/t/t-006.c new file mode 100644 index 00000000..1ae32285 --- /dev/null +++ b/hawk/t/t-006.c @@ -0,0 +1,80 @@ + +#include +#include +#include "t.h" + + +struct +{ + hawk_ntime_sec_t s1; + hawk_ntime_nsec_t ns1; + hawk_ntime_sec_t s2; + hawk_ntime_nsec_t ns2; + + hawk_ntime_sec_t add_s; + hawk_ntime_nsec_t add_ns; + hawk_ntime_sec_t sub_s; + hawk_ntime_nsec_t sub_ns; +} tab[] = +{ + { 12345678, HAWK_NSECS_PER_SEC - 1, + 0, 10, + 12345679, 9, + 12345678, HAWK_NSECS_PER_SEC - 11 }, + + { HAWK_TYPE_MAX(hawk_ntime_sec_t), 0, + 0, 0, + HAWK_TYPE_MAX(hawk_ntime_sec_t), 0, + HAWK_TYPE_MAX(hawk_ntime_sec_t), 0 }, + + { HAWK_TYPE_MIN(hawk_ntime_sec_t), 0, + 0, 0, + HAWK_TYPE_MIN(hawk_ntime_sec_t), 0, + HAWK_TYPE_MIN(hawk_ntime_sec_t), 0 }, + + { 0, 0, + HAWK_TYPE_MIN(hawk_ntime_sec_t), 0, + HAWK_TYPE_MIN(hawk_ntime_sec_t), 0, + HAWK_TYPE_MAX(hawk_ntime_sec_t), HAWK_NSECS_PER_SEC - 1 }, + + { HAWK_TYPE_MAX(hawk_ntime_sec_t), 0, + 1, 0, + HAWK_TYPE_MAX(hawk_ntime_sec_t), HAWK_NSECS_PER_SEC - 1, + HAWK_TYPE_MAX(hawk_ntime_sec_t) - 1, 0 }, + + { HAWK_TYPE_MAX(hawk_ntime_sec_t), 0, + HAWK_TYPE_MIN(hawk_ntime_sec_t), 0, + -1, 0, + HAWK_TYPE_MAX(hawk_ntime_sec_t), HAWK_NSECS_PER_SEC - 1 } +}; + +int main () +{ + hawk_ntime_t x, y, z; + int i; + char buf[64]; + + for (i = 0; i < HAWK_COUNTOF(tab); i++) + { + sprintf (buf, "test index %d", i); + + x.sec = tab[i].s1; + x.nsec = tab[i].ns1; + y.sec = tab[i].s2; + y.nsec = tab[i].ns2; + + hawk_add_ntime (&z, &x, &y); + T_ASSERT1 (z.sec == tab[i].add_s, buf); + T_ASSERT1 (z.nsec == tab[i].add_ns, buf); + + hawk_sub_ntime (&z, &x, &y); + T_ASSERT1 (z.sec == tab[i].sub_s, buf); + T_ASSERT1 (z.nsec == tab[i].sub_ns, buf); + + } + + return 0; + +oops: + return -1; +}