added hcl_add_ntime()/hcl_sub_ntime()

This commit is contained in:
hyung-hwan 2020-09-03 06:21:01 +00:00
parent 52aa942508
commit e8ac460f59
3 changed files with 147 additions and 2 deletions

View File

@ -564,11 +564,18 @@ typedef struct hcl_obj_t* hcl_oop_t;
#define HCL_SEC_TO_USEC(sec) ((sec) * HCL_USECS_PER_SEC)
#define HCL_USEC_TO_SEC(usec) ((usec) / HCL_USECS_PER_SEC)
#if defined(HCL_SIZEOF_INT64_T) && (HCL_SIZEOF_INT64_T > 0)
typedef hcl_int64_t hcl_ntime_sec_t;
#else
typedef hcl_int32_t hcl_ntime_sec_t;
#endif
typedef hcl_int32_t hcl_ntime_nsec_t;
typedef struct hcl_ntime_t hcl_ntime_t;
struct hcl_ntime_t
{
hcl_intptr_t sec;
hcl_int32_t nsec; /* nanoseconds */
hcl_ntime_sec_t sec;
hcl_ntime_nsec_t nsec; /* nanoseconds */
};
#define HCL_INIT_NTIME(c,s,ns) (((c)->sec = (s)), ((c)->nsec = (ns)))

View File

@ -758,6 +758,34 @@ HCL_EXPORT int hcl_ufmt_out (
...
);
/* =========================================================================
* TIME CALCULATION WITH OVERFLOW/UNDERFLOW DETECTION
* ========================================================================= */
/**
* The hcl_add_ntime() function adds two time structures pointed to by \a x and \a y
* and stores the result in the structure pointed to by \a z. If it detects overflow/
* underflow, it stores the largest/least possible value respectively.
* You may use the HCL_ADD_NTIME() macro if overflow/underflow check isn't needed.
*/
HCL_EXPORT void hcl_add_ntime (
hcl_ntime_t* z,
const hcl_ntime_t* x,
const hcl_ntime_t* y
);
/**
* The hcl_sub_ntime() function subtracts the time value \a y from the time value \a x
* and stores the result in the structure pointed to by \a z. If it detects overflow/
* underflow, it stores the largest/least possible value respectively.
* You may use the HCL_SUB_NTIME() macro if overflow/underflow check isn't needed.
*/
HCL_EXPORT void hcl_sub_ntime (
hcl_ntime_t* z,
const hcl_ntime_t* x,
const hcl_ntime_t* y
);
/* =========================================================================
* BIT SWAP
* ========================================================================= */

110
lib/utl.c
View File

@ -925,3 +925,113 @@ hcl_bch_t* hcl_dupbchars (hcl_t* hcl, const hcl_bch_t* bcs, hcl_oow_t bcslen)
return ptr;
}
/* ----------------------------------------------------------------------- */
void hcl_add_ntime (hcl_ntime_t* z, const hcl_ntime_t* x, const hcl_ntime_t* y)
{
hcl_ntime_sec_t xs, ys;
hcl_ntime_nsec_t ns;
/*HCL_ASSERT (x->nsec >= 0 && x->nsec < HCL_NSECS_PER_SEC);
HCL_ASSERT (y->nsec >= 0 && y->nsec < HCL_NSECS_PER_SEC);*/
ns = x->nsec + y->nsec;
if (ns >= HCL_NSECS_PER_SEC)
{
ns = ns - HCL_NSECS_PER_SEC;
if (x->sec == HCL_TYPE_MAX(hcl_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 > HCL_TYPE_MAX(hcl_ntime_sec_t) - ys) ||
(ys <= -1 && xs < HCL_TYPE_MIN(hcl_ntime_sec_t) - ys))
{
if (xs >= 0)
{
overflow:
xs = HCL_TYPE_MAX(hcl_ntime_sec_t);
ns = HCL_NSECS_PER_SEC - 1;
}
else
{
xs = HCL_TYPE_MIN(hcl_ntime_sec_t);
ns = 0;
}
}
else
{
xs = xs + ys;
}
z->sec = xs;
z->nsec = ns;
}
void hcl_sub_ntime (hcl_ntime_t* z, const hcl_ntime_t* x, const hcl_ntime_t* y)
{
hcl_ntime_sec_t xs, ys;
hcl_ntime_nsec_t ns;
/*HCL_ASSERT (x->nsec >= 0 && x->nsec < HCL_NSECS_PER_SEC);
HCL_ASSERT (y->nsec >= 0 && y->nsec < HCL_NSECS_PER_SEC);*/
ns = x->nsec - y->nsec;
if (ns < 0)
{
ns = ns + HCL_NSECS_PER_SEC;
if (x->sec == HCL_TYPE_MIN(hcl_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 < HCL_TYPE_MIN(hcl_ntime_sec_t) + ys) ||
(ys <= -1 && xs > HCL_TYPE_MAX(hcl_ntime_sec_t) + ys))
{
if (xs >= 0)
{
xs = HCL_TYPE_MAX(hcl_ntime_sec_t);
ns = HCL_NSECS_PER_SEC - 1;
}
else
{
underflow:
xs = HCL_TYPE_MIN(hcl_ntime_sec_t);
ns = 0;
}
}
else
{
xs = xs - ys;
}
z->sec = xs;
z->nsec = ns;
}