|
|
@ -581,6 +581,7 @@ struct signalfd_siginfo |
|
|
|
|
|
|
|
#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ |
|
|
|
#define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */ |
|
|
|
#define MAX_BLOCKTIME2 1500001.07 /* same, but when timerfd is used to detect jumps, also safe delay to not overflow */ |
|
|
|
|
|
|
|
/* find a portable timestamp that is "always" in the future but fits into time_t. |
|
|
|
* this is quite hard, and we are mostly guessing - we handle 32 bit signed/unsigned time_t, |
|
|
@ -646,15 +647,23 @@ struct signalfd_siginfo |
|
|
|
#define ECB_H |
|
|
|
|
|
|
|
/* 16 bits major, 16 bits minor */ |
|
|
|
#define ECB_VERSION 0x00010006 |
|
|
|
#define ECB_VERSION 0x00010008 |
|
|
|
|
|
|
|
#include <string.h> /* for memcpy */ |
|
|
|
|
|
|
|
#ifdef _WIN32 |
|
|
|
typedef signed char int8_t; |
|
|
|
typedef unsigned char uint8_t; |
|
|
|
typedef signed char int_fast8_t; |
|
|
|
typedef unsigned char uint_fast8_t; |
|
|
|
typedef signed short int16_t; |
|
|
|
typedef unsigned short uint16_t; |
|
|
|
typedef signed int int_fast16_t; |
|
|
|
typedef unsigned int uint_fast16_t; |
|
|
|
typedef signed int int32_t; |
|
|
|
typedef unsigned int uint32_t; |
|
|
|
typedef signed int int_fast32_t; |
|
|
|
typedef unsigned int uint_fast32_t; |
|
|
|
#if __GNUC__ |
|
|
|
typedef signed long long int64_t; |
|
|
|
typedef unsigned long long uint64_t; |
|
|
@ -662,6 +671,8 @@ struct signalfd_siginfo |
|
|
|
typedef signed __int64 int64_t; |
|
|
|
typedef unsigned __int64 uint64_t; |
|
|
|
#endif |
|
|
|
typedef int64_t int_fast64_t; |
|
|
|
typedef uint64_t uint_fast64_t; |
|
|
|
#ifdef _WIN64 |
|
|
|
#define ECB_PTRSIZE 8 |
|
|
|
typedef uint64_t uintptr_t; |
|
|
@ -683,6 +694,14 @@ struct signalfd_siginfo |
|
|
|
#define ECB_GCC_AMD64 (__amd64 || __amd64__ || __x86_64 || __x86_64__) |
|
|
|
#define ECB_MSVC_AMD64 (_M_AMD64 || _M_X64) |
|
|
|
|
|
|
|
#ifndef ECB_OPTIMIZE_SIZE |
|
|
|
#if __OPTIMIZE_SIZE__ |
|
|
|
#define ECB_OPTIMIZE_SIZE 1 |
|
|
|
#else |
|
|
|
#define ECB_OPTIMIZE_SIZE 0 |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
/* work around x32 idiocy by defining proper macros */ |
|
|
|
#if ECB_GCC_AMD64 || ECB_MSVC_AMD64 |
|
|
|
#if _ILP32 |
|
|
@ -1198,6 +1217,44 @@ ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { retu |
|
|
|
ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); } |
|
|
|
ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); } |
|
|
|
|
|
|
|
#if ECB_CPP |
|
|
|
|
|
|
|
inline uint8_t ecb_ctz (uint8_t v) { return ecb_ctz32 (v); } |
|
|
|
inline uint16_t ecb_ctz (uint16_t v) { return ecb_ctz32 (v); } |
|
|
|
inline uint32_t ecb_ctz (uint32_t v) { return ecb_ctz32 (v); } |
|
|
|
inline uint64_t ecb_ctz (uint64_t v) { return ecb_ctz64 (v); } |
|
|
|
|
|
|
|
inline bool ecb_is_pot (uint8_t v) { return ecb_is_pot32 (v); } |
|
|
|
inline bool ecb_is_pot (uint16_t v) { return ecb_is_pot32 (v); } |
|
|
|
inline bool ecb_is_pot (uint32_t v) { return ecb_is_pot32 (v); } |
|
|
|
inline bool ecb_is_pot (uint64_t v) { return ecb_is_pot64 (v); } |
|
|
|
|
|
|
|
inline int ecb_ld (uint8_t v) { return ecb_ld32 (v); } |
|
|
|
inline int ecb_ld (uint16_t v) { return ecb_ld32 (v); } |
|
|
|
inline int ecb_ld (uint32_t v) { return ecb_ld32 (v); } |
|
|
|
inline int ecb_ld (uint64_t v) { return ecb_ld64 (v); } |
|
|
|
|
|
|
|
inline int ecb_popcount (uint8_t v) { return ecb_popcount32 (v); } |
|
|
|
inline int ecb_popcount (uint16_t v) { return ecb_popcount32 (v); } |
|
|
|
inline int ecb_popcount (uint32_t v) { return ecb_popcount32 (v); } |
|
|
|
inline int ecb_popcount (uint64_t v) { return ecb_popcount64 (v); } |
|
|
|
|
|
|
|
inline uint8_t ecb_bitrev (uint8_t v) { return ecb_bitrev8 (v); } |
|
|
|
inline uint16_t ecb_bitrev (uint16_t v) { return ecb_bitrev16 (v); } |
|
|
|
inline uint32_t ecb_bitrev (uint32_t v) { return ecb_bitrev32 (v); } |
|
|
|
|
|
|
|
inline uint8_t ecb_rotl (uint8_t v, unsigned int count) { return ecb_rotl8 (v, count); } |
|
|
|
inline uint16_t ecb_rotl (uint16_t v, unsigned int count) { return ecb_rotl16 (v, count); } |
|
|
|
inline uint32_t ecb_rotl (uint32_t v, unsigned int count) { return ecb_rotl32 (v, count); } |
|
|
|
inline uint64_t ecb_rotl (uint64_t v, unsigned int count) { return ecb_rotl64 (v, count); } |
|
|
|
|
|
|
|
inline uint8_t ecb_rotr (uint8_t v, unsigned int count) { return ecb_rotr8 (v, count); } |
|
|
|
inline uint16_t ecb_rotr (uint16_t v, unsigned int count) { return ecb_rotr16 (v, count); } |
|
|
|
inline uint32_t ecb_rotr (uint32_t v, unsigned int count) { return ecb_rotr32 (v, count); } |
|
|
|
inline uint64_t ecb_rotr (uint64_t v, unsigned int count) { return ecb_rotr64 (v, count); } |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
#if ECB_GCC_VERSION(4,3) || (ECB_CLANG_BUILTIN(__builtin_bswap32) && ECB_CLANG_BUILTIN(__builtin_bswap64)) |
|
|
|
#if ECB_GCC_VERSION(4,8) || ECB_CLANG_BUILTIN(__builtin_bswap16) |
|
|
|
#define ecb_bswap16(x) __builtin_bswap16 (x) |
|
|
@ -1278,6 +1335,78 @@ ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_he |
|
|
|
ecb_inline ecb_const ecb_bool ecb_little_endian (void); |
|
|
|
ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44332211; } |
|
|
|
|
|
|
|
/*****************************************************************************/ |
|
|
|
/* unaligned load/store */ |
|
|
|
|
|
|
|
ecb_inline uint_fast16_t ecb_be_u16_to_host (uint_fast16_t v) { return ecb_little_endian () ? ecb_bswap16 (v) : v; } |
|
|
|
ecb_inline uint_fast32_t ecb_be_u32_to_host (uint_fast32_t v) { return ecb_little_endian () ? ecb_bswap32 (v) : v; } |
|
|
|
ecb_inline uint_fast64_t ecb_be_u64_to_host (uint_fast64_t v) { return ecb_little_endian () ? ecb_bswap64 (v) : v; } |
|
|
|
|
|
|
|
ecb_inline uint_fast16_t ecb_le_u16_to_host (uint_fast16_t v) { return ecb_big_endian () ? ecb_bswap16 (v) : v; } |
|
|
|
ecb_inline uint_fast32_t ecb_le_u32_to_host (uint_fast32_t v) { return ecb_big_endian () ? ecb_bswap32 (v) : v; } |
|
|
|
ecb_inline uint_fast64_t ecb_le_u64_to_host (uint_fast64_t v) { return ecb_big_endian () ? ecb_bswap64 (v) : v; } |
|
|
|
|
|
|
|
ecb_inline uint_fast16_t ecb_peek_u16_u (const void *ptr) { uint16_t v; memcpy (&v, ptr, sizeof (v)); return v; } |
|
|
|
ecb_inline uint_fast32_t ecb_peek_u32_u (const void *ptr) { uint32_t v; memcpy (&v, ptr, sizeof (v)); return v; } |
|
|
|
ecb_inline uint_fast64_t ecb_peek_u64_u (const void *ptr) { uint64_t v; memcpy (&v, ptr, sizeof (v)); return v; } |
|
|
|
|
|
|
|
ecb_inline uint_fast16_t ecb_peek_be_u16_u (const void *ptr) { return ecb_be_u16_to_host (ecb_peek_u16_u (ptr)); } |
|
|
|
ecb_inline uint_fast32_t ecb_peek_be_u32_u (const void *ptr) { return ecb_be_u32_to_host (ecb_peek_u32_u (ptr)); } |
|
|
|
ecb_inline uint_fast64_t ecb_peek_be_u64_u (const void *ptr) { return ecb_be_u64_to_host (ecb_peek_u64_u (ptr)); } |
|
|
|
|
|
|
|
ecb_inline uint_fast16_t ecb_peek_le_u16_u (const void *ptr) { return ecb_le_u16_to_host (ecb_peek_u16_u (ptr)); } |
|
|
|
ecb_inline uint_fast32_t ecb_peek_le_u32_u (const void *ptr) { return ecb_le_u32_to_host (ecb_peek_u32_u (ptr)); } |
|
|
|
ecb_inline uint_fast64_t ecb_peek_le_u64_u (const void *ptr) { return ecb_le_u64_to_host (ecb_peek_u64_u (ptr)); } |
|
|
|
|
|
|
|
ecb_inline uint_fast16_t ecb_host_to_be_u16 (uint_fast16_t v) { return ecb_little_endian () ? ecb_bswap16 (v) : v; } |
|
|
|
ecb_inline uint_fast32_t ecb_host_to_be_u32 (uint_fast32_t v) { return ecb_little_endian () ? ecb_bswap32 (v) : v; } |
|
|
|
ecb_inline uint_fast64_t ecb_host_to_be_u64 (uint_fast64_t v) { return ecb_little_endian () ? ecb_bswap64 (v) : v; } |
|
|
|
|
|
|
|
ecb_inline uint_fast16_t ecb_host_to_le_u16 (uint_fast16_t v) { return ecb_big_endian () ? ecb_bswap16 (v) : v; } |
|
|
|
ecb_inline uint_fast32_t ecb_host_to_le_u32 (uint_fast32_t v) { return ecb_big_endian () ? ecb_bswap32 (v) : v; } |
|
|
|
ecb_inline uint_fast64_t ecb_host_to_le_u64 (uint_fast64_t v) { return ecb_big_endian () ? ecb_bswap64 (v) : v; } |
|
|
|
|
|
|
|
ecb_inline void ecb_poke_u16_u (void *ptr, uint16_t v) { memcpy (ptr, &v, sizeof (v)); } |
|
|
|
ecb_inline void ecb_poke_u32_u (void *ptr, uint32_t v) { memcpy (ptr, &v, sizeof (v)); } |
|
|
|
ecb_inline void ecb_poke_u64_u (void *ptr, uint64_t v) { memcpy (ptr, &v, sizeof (v)); } |
|
|
|
|
|
|
|
ecb_inline void ecb_poke_be_u16_u (void *ptr, uint_fast16_t v) { ecb_poke_u16_u (ptr, ecb_host_to_be_u16 (v)); } |
|
|
|
ecb_inline void ecb_poke_be_u32_u (void *ptr, uint_fast32_t v) { ecb_poke_u32_u (ptr, ecb_host_to_be_u32 (v)); } |
|
|
|
ecb_inline void ecb_poke_be_u64_u (void *ptr, uint_fast64_t v) { ecb_poke_u64_u (ptr, ecb_host_to_be_u64 (v)); } |
|
|
|
|
|
|
|
ecb_inline void ecb_poke_le_u16_u (void *ptr, uint_fast16_t v) { ecb_poke_u16_u (ptr, ecb_host_to_le_u16 (v)); } |
|
|
|
ecb_inline void ecb_poke_le_u32_u (void *ptr, uint_fast32_t v) { ecb_poke_u32_u (ptr, ecb_host_to_le_u32 (v)); } |
|
|
|
ecb_inline void ecb_poke_le_u64_u (void *ptr, uint_fast64_t v) { ecb_poke_u64_u (ptr, ecb_host_to_le_u64 (v)); } |
|
|
|
|
|
|
|
#if ECB_CPP |
|
|
|
|
|
|
|
inline uint8_t ecb_bswap (uint8_t v) { return v; } |
|
|
|
inline uint16_t ecb_bswap (uint16_t v) { return ecb_bswap16 (v); } |
|
|
|
inline uint32_t ecb_bswap (uint32_t v) { return ecb_bswap32 (v); } |
|
|
|
inline uint64_t ecb_bswap (uint64_t v) { return ecb_bswap64 (v); } |
|
|
|
|
|
|
|
template<typename T> inline T ecb_be_to_host (T v) { return ecb_little_endian () ? ecb_bswap (v) : v; } |
|
|
|
template<typename T> inline T ecb_le_to_host (T v) { return ecb_big_endian () ? ecb_bswap (v) : v; } |
|
|
|
template<typename T> inline T ecb_peek (const void *ptr) { return *(const T *)ptr; } |
|
|
|
template<typename T> inline T ecb_peek_be (const void *ptr) { return ecb_be_to_host (ecb_peek <T> (ptr)); } |
|
|
|
template<typename T> inline T ecb_peek_le (const void *ptr) { return ecb_le_to_host (ecb_peek <T> (ptr)); } |
|
|
|
template<typename T> inline T ecb_peek_u (const void *ptr) { T v; memcpy (&v, ptr, sizeof (v)); return v; } |
|
|
|
template<typename T> inline T ecb_peek_be_u (const void *ptr) { return ecb_be_to_host (ecb_peek_u<T> (ptr)); } |
|
|
|
template<typename T> inline T ecb_peek_le_u (const void *ptr) { return ecb_le_to_host (ecb_peek_u<T> (ptr)); } |
|
|
|
|
|
|
|
template<typename T> inline T ecb_host_to_be (T v) { return ecb_little_endian () ? ecb_bswap (v) : v; } |
|
|
|
template<typename T> inline T ecb_host_to_le (T v) { return ecb_big_endian () ? ecb_bswap (v) : v; } |
|
|
|
template<typename T> inline void ecb_poke (void *ptr, T v) { *(T *)ptr = v; } |
|
|
|
template<typename T> inline void ecb_poke_be (void *ptr, T v) { return ecb_poke <T> (ptr, ecb_host_to_be (v)); } |
|
|
|
template<typename T> inline void ecb_poke_le (void *ptr, T v) { return ecb_poke <T> (ptr, ecb_host_to_le (v)); } |
|
|
|
template<typename T> inline void ecb_poke_u (void *ptr, T v) { memcpy (ptr, &v, sizeof (v)); } |
|
|
|
template<typename T> inline void ecb_poke_be_u (void *ptr, T v) { return ecb_poke_u<T> (ptr, ecb_host_to_be (v)); } |
|
|
|
template<typename T> inline void ecb_poke_le_u (void *ptr, T v) { return ecb_poke_u<T> (ptr, ecb_host_to_le (v)); } |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
/*****************************************************************************/ |
|
|
|
|
|
|
|
#if ECB_GCC_VERSION(3,0) || ECB_C99 |
|
|
|
#define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0)) |
|
|
|
#else |
|
|
@ -1311,6 +1440,8 @@ ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_he |
|
|
|
#define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) |
|
|
|
#endif |
|
|
|
|
|
|
|
/*****************************************************************************/ |
|
|
|
|
|
|
|
ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x); |
|
|
|
ecb_function_ ecb_const uint32_t |
|
|
|
ecb_binary16_to_binary32 (uint32_t x) |
|
|
@ -1428,7 +1559,6 @@ ecb_binary32_to_binary16 (uint32_t x) |
|
|
|
|| (defined __arm__ && (defined __ARM_EABI__ || defined __EABI__ || defined __VFP_FP__ || defined _WIN32_WCE || defined __ANDROID__)) \ |
|
|
|
|| defined __aarch64__ |
|
|
|
#define ECB_STDFP 1 |
|
|
|
#include <string.h> /* for memcpy */ |
|
|
|
#else |
|
|
|
#define ECB_STDFP 0 |
|
|
|
#endif |
|
|
@ -2905,10 +3035,7 @@ timerfdcb (EV_P_ ev_io *iow, int revents) |
|
|
|
{ |
|
|
|
struct itimerspec its = { 0 }; |
|
|
|
|
|
|
|
/* since we can't easily come zup with a (portable) maximum value of time_t, |
|
|
|
* we wake up once per month, which hopefully is rare enough to not |
|
|
|
* be a problem. */ |
|
|
|
its.it_value.tv_sec = ev_rt_now + 86400 * 30; |
|
|
|
its.it_value.tv_sec = ev_rt_now + (int)MAX_BLOCKTIME2; |
|
|
|
timerfd_settime (timerfd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &its, 0); |
|
|
|
|
|
|
|
ev_rt_now = ev_time (); |
|
|
@ -3965,6 +4092,12 @@ ev_run (EV_P_ int flags) |
|
|
|
{ |
|
|
|
waittime = EV_TS_CONST (MAX_BLOCKTIME); |
|
|
|
|
|
|
|
#if EV_USE_TIMERFD |
|
|
|
/* sleep a lot longer when we can reliably detect timejumps */ |
|
|
|
if (ecb_expect_true (timerfd >= 0)) |
|
|
|
waittime = EV_TS_CONST (MAX_BLOCKTIME2); |
|
|
|
#endif |
|
|
|
|
|
|
|
if (timercnt) |
|
|
|
{ |
|
|
|
ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now; |
|
|
|