// // Copyright 2020 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this // file was obtained (LICENSE.txt). A copy of the license may also be // found online at https://opensource.org/licenses/MIT. // #define TEST_NO_MAIN #ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #include // order counts #include #define poll WSAPoll #include #else #include #include #include #include #include #include #endif #include #include #include #include #include #if !defined(_WIN32) && !defined(CLOCK_MONOTONIC) #include #endif #include "nuts.h" uint64_t nuts_clock(void) { #ifdef _WIN32 return (GetTickCount64()); #elif defined(CLOCK_MONTONIC) struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); uint64_t val; val = ts.tv_sec; val *= 1000; val += ts.tv_nsec / 1000000; return (val); #else static time_t epoch; struct timeval tv; if (epoch == 0) { epoch = time(NULL); } gettimeofday(&tv, NULL); if (tv.tv_sec < epoch) { // Broken clock. // This will force all other timing tests to fail return (0); } tv.tv_sec -= epoch; return ( ((uint64_t)(tv.tv_sec) * 1000) + (uint64_t)(tv.tv_usec / 1000)); #endif #ifdef _WIN32 #else #include #include #endif } bool nuts_poll_fd(int fd) { #ifdef _WIN32 struct pollfd pfd; pfd.fd = (SOCKET) fd; pfd.events = POLLRDNORM; pfd.revents = 0; switch (WSAPoll(&pfd, 1, 0)) { case 0: return (false); case 1: return (true); } #else struct pollfd pfd; pfd.fd = fd; pfd.events = POLLRDNORM; pfd.revents = 0; switch (poll(&pfd, 1, 0)) { case 0: return (false); case 1: return (true); } #endif return (false); } static bool is_little_endian(void) { uint16_t num = 0x1; uint8_t *ptr = (uint8_t *) (void *) (&num); return (ptr[0] == 1); } uint16_t nuts_be16(uint16_t in) { if (is_little_endian()) { in = ((in / 0x100) + ((in % 0x100) * 0x100)); } return (in); } uint32_t nuts_be32(uint32_t in) { if (is_little_endian()) { in = ((in >> 24u) & 0xffu) | ((in >> 8u) & 0xff00u) | ((in << 8u) & 0xff0000u) | ((in << 24u) & 0xff000000u); } return (in); } void nuts_sleep(int msec) { #ifdef _WIN32 Sleep(msec); #elif defined(CLOCK_MONOTONIC) struct timespec ts; ts.tv_sec = msec / 1000; ts.tv_nsec = (msec % 1000) * 1000000; // Do this in a loop, so that interrupts don't actually wake us. while (ts.tv_sec || ts.tv_nsec) { if (nanosleep(&ts, &ts) == 0) { break; } } #else poll(NULL, 0, msec); #endif }