#include "moar.h" #include "platform/time.h" #include #include #if defined(__APPLE__) && defined(__MACH__) #include #include #endif #define E9 1000000000 #define E9F 1000000000.0f MVMuint64 MVM_platform_now(void) { #if defined(__APPLE__) && defined(__MACH__) // OS X does not have clock_gettime, use clock_get_time clock_serv_t cclock; mach_timespec_t ts; host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); clock_get_time(cclock, &ts); mach_port_deallocate(mach_task_self(), cclock); return (MVMuint64)ts.tv_sec * E9 + ts.tv_nsec; #else # ifdef CLOCK_REALTIME struct timespec ts; if (clock_gettime(CLOCK_REALTIME, &ts) != 0) return 0; return (MVMuint64)ts.tv_sec * E9 + ts.tv_nsec; # else struct timeval tv; if (gettimeofday(&tv, NULL) != 0) return 0; return (MVMuint64)tv.tv_sec * E9 + tv.tv_usec * 1000; # endif #endif } void MVM_platform_sleep(MVMnum64 second) { struct timespec timeout; timeout.tv_sec = (time_t)second; timeout.tv_nsec = (long)((second - timeout.tv_sec) * E9F); while (nanosleep(&timeout, &timeout) && errno == EINTR); } void MVM_platform_nanosleep(MVMuint64 nanos) { struct timespec timeout; timeout.tv_sec = nanos / E9; timeout.tv_nsec = nanos % E9; while (nanosleep(&timeout, &timeout) && errno == EINTR); } void MVM_platform_decodelocaltime(MVMThreadContext *tc, MVMint64 time, MVMint64 decoded[]) { const time_t t = (time_t)time; struct tm tm; if (localtime_r(&t, &tm) == NULL) MVM_exception_throw_adhoc(tc, "Could not decode localtime: %s", strerror(errno)); decoded[0] = tm.tm_sec; decoded[1] = tm.tm_min; decoded[2] = tm.tm_hour; decoded[3] = tm.tm_mday; decoded[4] = tm.tm_mon + 1; decoded[5] = tm.tm_year + 1900; decoded[6] = tm.tm_wday; decoded[7] = tm.tm_yday; decoded[8] = tm.tm_isdst; }