X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=common.c;h=43217719ba99144150d997adb32998bb9c3e4833;hb=refs%2Fheads%2Fmaster;hp=9dbadf369983950b2126efc8a5dcde63a307d2f2;hpb=4706199a81dc631b6969927e1a6ad27591852b20;p=dcpu16 diff --git a/common.c b/common.c index 9dbadf3..4321771 100644 --- a/common.c +++ b/common.c @@ -7,6 +7,13 @@ #include #include #include +#include +#include + +#ifdef __MACH__ +#include +#include +#endif /* __MACH__ */ #include "common.h" #include "dcpu16.h" @@ -58,6 +65,17 @@ struct dynamic_array *dynarray_new(size_t entry_size, size_t grow_size) { return da; } +void dynarray_empty(struct dynamic_array *da, void (*free_element)(void *)) { + while ( da->entries-- ) { + void *element = (void *)DYNARRAY_ITEM(*da, da->entries); + + free_element(element); + } + free(da->a); + da->a = NULL; + da->allocated = 0; +} + /* copy item onto end of array */ void *dynarray_add(struct dynamic_array *da, void *item) { void *dst; @@ -126,7 +144,11 @@ char *strqtok_r(char *str, const char *sep, int esc, const char *quote, char **l } /* next token starts after any leading seps */ - *lasts += strspn(*lasts, sep); + while (**lasts && strchr(sep, **lasts)) { + **lasts = '\0'; + (*lasts)++; + } + tok = *lasts; if (*tok == '\0') return NULL; @@ -200,3 +222,74 @@ char *strqtok_r(char *str, const char *sep, int esc, const char *quote, char **l return tok; } + +/* like gettimeofday, except with nanoseconds */ +inline +int gettimespecofday(struct timespec *ts) { + int retval = 0; +#ifdef __MACH__ + clock_serv_t cclock; + mach_timespec_t mts; + + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + ts->tv_sec = mts.tv_sec; + ts->tv_nsec = mts.tv_nsec; +#else /* __MACH__ */ + retval = clock_gettime(CLOCK_REALTIME, ts); +#endif /* __MACH__ */ + + return retval; +} + +inline +int timespec_add(struct timespec *result, const struct timespec *x) { + result->tv_sec += x->tv_sec; + result->tv_nsec += x->tv_nsec; + + result->tv_sec += result->tv_nsec / 1000000000; + result->tv_nsec %= 1000000000; + + return 0; +} + +inline +int timespec_subtract(struct timespec *result, struct timespec *x, struct timespec *y) { + if (x->tv_nsec < y->tv_nsec) { + int z = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1; + y->tv_nsec -= 1000000000 * z; + y->tv_sec += z; + } + if (x->tv_nsec - y->tv_nsec > 1000000000) { + int z = (x->tv_nsec - y->tv_nsec) / 1000000000; + y->tv_nsec += 1000000000 * z; + y->tv_sec -= z; + } + result->tv_sec = x->tv_sec - y->tv_sec; + result->tv_nsec = x->tv_nsec - y->tv_nsec; + + return x->tv_sec < y->tv_sec; +} + +int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) { + /* Perform the carry for the later subtraction by updating y. */ + if (x->tv_usec < y->tv_usec) { + int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; + y->tv_usec -= 1000000 * nsec; + y->tv_sec += nsec; + } + if (x->tv_usec - y->tv_usec > 1000000) { + int nsec = (x->tv_usec - y->tv_usec) / 1000000; + y->tv_usec += 1000000 * nsec; + y->tv_sec -= nsec; + } + + /* Compute the time remaining to wait. + tv_usec is certainly positive. */ + result->tv_sec = x->tv_sec - y->tv_sec; + result->tv_usec = x->tv_usec - y->tv_usec; + + /* Return 1 if result is negative. */ + return x->tv_sec < y->tv_sec; +}