Browse Source

Add a slew of timer helper functions to libckpool

master
Con Kolivas 11 years ago
parent
commit
e349ec2435
  1. 2
      configure.ac
  2. 3
      src/ckpool.h
  3. 174
      src/libckpool.c
  4. 22
      src/libckpool.h

2
configure.ac

@ -32,7 +32,7 @@ AC_FUNC_ALLOCA
PKG_PROG_PKG_CONFIG()
AC_CHECK_HEADERS(stdio.h stdlib.h fcntl.h sys/time.h unistd.h)
AC_CHECK_HEADERS(ctype.h errno.h byteswap.h string.h)
AC_CHECK_HEADERS(ctype.h errno.h byteswap.h string.h time.h)
AC_CHECK_HEADERS(endian.h sys/endian.h arpa/inet.h)
AC_CHECK_HEADERS(alloca.h pthread.h)
AC_CHECK_HEADERS(sys/types.h sys/socket.h)

3
src/ckpool.h

@ -70,6 +70,9 @@
/* Typedefs are evil but we use this one so often... */
typedef unsigned char uchar;
typedef struct timeval tv_t;
typedef struct timespec ts_t;
static inline void swap_256(void *dest_p, const void *src_p)
{
uint32_t *dest = dest_p;

174
src/libckpool.c

@ -18,6 +18,9 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include "ckpool.h"
#include "libckpool.h"
@ -160,7 +163,7 @@ void b58tobin(uchar *b58bin, const uchar *b58)
}
}
void address_to_pubkeyhash(uchar *pkh, const uchar *addr)
void address_to_pubkeytxn(uchar *pkh, const uchar *addr)
{
uchar b58bin[25];
@ -192,3 +195,172 @@ int ser_number(uchar *s, int32_t val)
s[0] = len++;
return len;
}
/* For testing a le encoded 256 byte hash against a target */
bool fulltest(const uchar *hash, const uchar *target)
{
uint32_t *hash32 = (uint32_t *)hash;
uint32_t *target32 = (uint32_t *)target;
bool ret = true;
int i;
for (i = 28 / 4; i >= 0; i--) {
uint32_t h32tmp = le32toh(hash32[i]);
uint32_t t32tmp = le32toh(target32[i]);
if (h32tmp > t32tmp) {
ret = false;
break;
}
if (h32tmp < t32tmp) {
ret = true;
break;
}
}
return ret;
}
void copy_tv(tv_t *dest, const tv_t *src)
{
memcpy(dest, src, sizeof(tv_t));
}
void ts_to_tv(tv_t *val, const ts_t *spec)
{
val->tv_sec = spec->tv_sec;
val->tv_usec = spec->tv_nsec / 1000;
}
void tv_to_ts(ts_t *spec, const tv_t *val)
{
spec->tv_sec = val->tv_sec;
spec->tv_nsec = val->tv_usec * 1000;
}
void us_to_tv(tv_t *val, int64_t us)
{
lldiv_t tvdiv = lldiv(us, 1000000);
val->tv_sec = tvdiv.quot;
val->tv_usec = tvdiv.rem;
}
void us_to_ts(ts_t *spec, int64_t us)
{
lldiv_t tvdiv = lldiv(us, 1000000);
spec->tv_sec = tvdiv.quot;
spec->tv_nsec = tvdiv.rem * 1000;
}
void ms_to_ts(ts_t *spec, int64_t ms)
{
lldiv_t tvdiv = lldiv(ms, 1000);
spec->tv_sec = tvdiv.quot;
spec->tv_nsec = tvdiv.rem * 1000000;
}
void ms_to_tv(tv_t *val, int64_t ms)
{
lldiv_t tvdiv = lldiv(ms, 1000);
val->tv_sec = tvdiv.quot;
val->tv_usec = tvdiv.rem * 1000;
}
void tv_time(tv_t *tv)
{
gettimeofday(tv, NULL);
}
void ts_time(ts_t *ts)
{
clock_gettime(CLOCK_MONOTONIC, ts);
}
void cksleep_prepare_r(ts_t *ts)
{
ts_time(ts);
}
void nanosleep_abstime(ts_t *ts_end)
{
int ret;
do {
ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts_end, NULL);
} while (ret == EINTR);
}
void timeraddspec(ts_t *a, const ts_t *b)
{
a->tv_sec += b->tv_sec;
a->tv_nsec += b->tv_nsec;
if (a->tv_nsec >= 1000000000) {
a->tv_nsec -= 1000000000;
a->tv_sec++;
}
}
/* Reentrant version of cksleep functions allow start time to be set separately
* from the beginning of the actual sleep, allowing scheduling delays to be
* counted in the sleep. */
void cksleep_ms_r(ts_t *ts_start, int ms)
{
ts_t ts_end;
ms_to_ts(&ts_end, ms);
timeraddspec(&ts_end, ts_start);
nanosleep_abstime(&ts_end);
}
void cksleep_us_r(ts_t *ts_start, int64_t us)
{
ts_t ts_end;
us_to_ts(&ts_end, us);
timeraddspec(&ts_end, ts_start);
nanosleep_abstime(&ts_end);
}
void cksleep_ms(int ms)
{
ts_t ts_start;
cksleep_prepare_r(&ts_start);
cksleep_ms_r(&ts_start, ms);
}
void cksleep_us(int64_t us)
{
ts_t ts_start;
cksleep_prepare_r(&ts_start);
cksleep_us_r(&ts_start, us);
}
/* Returns the microseconds difference between end and start times as a double */
double us_tvdiff(tv_t *end, tv_t *start)
{
/* Sanity check. We should only be using this for small differences so
* limit the max to 60 seconds. */
if (unlikely(end->tv_sec - start->tv_sec > 60))
return 60000000;
return (end->tv_sec - start->tv_sec) * 1000000 + (end->tv_usec - start->tv_usec);
}
/* Returns the milliseconds difference between end and start times */
int ms_tvdiff(tv_t *end, tv_t *start)
{
/* Like us_tdiff, limit to 1 hour. */
if (unlikely(end->tv_sec - start->tv_sec > 3600))
return 3600000;
return (end->tv_sec - start->tv_sec) * 1000 + (end->tv_usec - start->tv_usec) / 1000;
}
/* Returns the seconds difference between end and start times as a double */
double tvdiff(tv_t *end, tv_t *start)
{
return end->tv_sec - start->tv_sec + (end->tv_usec - start->tv_usec) / 1000000.0;
}

22
src/libckpool.h

@ -20,7 +20,27 @@ void __bin2hex(uchar *s, const uchar *p, size_t len);
void *bin2hex(const uchar *p, size_t len);
bool hex2bin(uchar *p, const uchar *hexstr, size_t len);
void b58tobin(uchar *b58bin, const uchar *b58);
void address_to_pubkeyhash(uchar *pkh, const uchar *addr);
void address_to_pubkeytxn(uchar *pkh, const uchar *addr);
int ser_number(uchar *s, int32_t val);
bool fulltest(const uchar *hash, const uchar *target);
void copy_tv(tv_t *dest, const tv_t *src);
void ts_to_tv(tv_t *val, const ts_t *spec);
void tv_to_ts(ts_t *spec, const tv_t *val);
void us_to_tv(tv_t *val, int64_t us);
void us_to_ts(ts_t *spec, int64_t us);
void ms_to_ts(ts_t *spec, int64_t ms);
void ms_to_tv(tv_t *val, int64_t ms);
void tv_time(tv_t *tv);
void ts_time(ts_t *ts);
void cksleep_prepare_r(ts_t *ts);
void nanosleep_abstime(ts_t *ts_end);
void timeraddspec(ts_t *a, const ts_t *b);
void cksleep_ms_r(ts_t *ts_start, int ms);
void cksleep_us_r(ts_t *ts_start, int64_t us);
void cksleep_ms(int ms);
void cksleep_us(int64_t us);
double us_tvdiff(tv_t *end, tv_t *start);
int ms_tvdiff(tv_t *end, tv_t *start);
double tvdiff(tv_t *end, tv_t *start);
#endif /* LIBCKPOOL_H */

Loading…
Cancel
Save