renamed some time functions.

enhanced hawk_add_ntime()/hawk_sub_ntime() to detect overflow/underflow
This commit is contained in:
hyung-hwan 2020-09-02 20:02:51 +00:00
parent 87e3601818
commit a3c7f4c6f7
9 changed files with 249 additions and 26 deletions

View File

@ -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)))

View File

@ -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
);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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

80
hawk/t/t-006.c Normal file
View File

@ -0,0 +1,80 @@
#include <hawk-utl.h>
#include <stdio.h>
#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;
}