11cb0ef41Sopenharmony_ci#ifndef _WIN32 21cb0ef41Sopenharmony_ci# include <errno.h> 31cb0ef41Sopenharmony_ci# include <sys/time.h> 41cb0ef41Sopenharmony_ci# include <sys/resource.h> 51cb0ef41Sopenharmony_ci# include <time.h> 61cb0ef41Sopenharmony_ci#endif /* _WIN32 */ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "uv.h" 91cb0ef41Sopenharmony_ci#include "clocks.h" 101cb0ef41Sopenharmony_ci#include "wasi_types.h" 111cb0ef41Sopenharmony_ci#include "uv_mapping.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci#define UVWASI__WIN_TIME_AND_RETURN(handle, get_times, time) \ 151cb0ef41Sopenharmony_ci do { \ 161cb0ef41Sopenharmony_ci FILETIME create; \ 171cb0ef41Sopenharmony_ci FILETIME exit; \ 181cb0ef41Sopenharmony_ci FILETIME system; \ 191cb0ef41Sopenharmony_ci FILETIME user; \ 201cb0ef41Sopenharmony_ci if (0 == get_times((handle), &create, &exit, &system, &user)) { \ 211cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error( \ 221cb0ef41Sopenharmony_ci uv_translate_sys_error(GetLastError()) \ 231cb0ef41Sopenharmony_ci ); \ 241cb0ef41Sopenharmony_ci } \ 251cb0ef41Sopenharmony_ci \ 261cb0ef41Sopenharmony_ci /* FILETIME times are in units of 100 nanoseconds */ \ 271cb0ef41Sopenharmony_ci (time) = (((uvwasi_timestamp_t) \ 281cb0ef41Sopenharmony_ci system.dwHighDateTime << 32 | system.dwLowDateTime) * 100 + \ 291cb0ef41Sopenharmony_ci ((uvwasi_timestamp_t) \ 301cb0ef41Sopenharmony_ci user.dwHighDateTime << 32 | user.dwLowDateTime) * 100); \ 311cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; \ 321cb0ef41Sopenharmony_ci } while (0) 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci#define UVWASI__CLOCK_GETTIME_AND_RETURN(clk, time) \ 361cb0ef41Sopenharmony_ci do { \ 371cb0ef41Sopenharmony_ci struct timespec ts; \ 381cb0ef41Sopenharmony_ci if (0 != clock_gettime((clk), &ts)) \ 391cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(uv_translate_sys_error(errno)); \ 401cb0ef41Sopenharmony_ci (time) = ((uvwasi_timestamp_t)(ts.tv_sec) * NANOS_PER_SEC) + ts.tv_nsec; \ 411cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; \ 421cb0ef41Sopenharmony_ci } while (0) 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci#define UVWASI__GETRUSAGE_AND_RETURN(who, time) \ 461cb0ef41Sopenharmony_ci do { \ 471cb0ef41Sopenharmony_ci struct rusage ru; \ 481cb0ef41Sopenharmony_ci if (0 != getrusage((who), &ru)) \ 491cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(uv_translate_sys_error(errno)); \ 501cb0ef41Sopenharmony_ci (time) = ((uvwasi_timestamp_t)(ru.ru_utime.tv_sec) * NANOS_PER_SEC) + \ 511cb0ef41Sopenharmony_ci (ru.ru_utime.tv_usec * 1000) + \ 521cb0ef41Sopenharmony_ci ((uvwasi_timestamp_t)(ru.ru_stime.tv_sec) * NANOS_PER_SEC) + \ 531cb0ef41Sopenharmony_ci (ru.ru_stime.tv_usec * 1000); \ 541cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; \ 551cb0ef41Sopenharmony_ci } while (0) 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci#define UVWASI__OSX_THREADTIME_AND_RETURN(time) \ 591cb0ef41Sopenharmony_ci do { \ 601cb0ef41Sopenharmony_ci mach_port_t thread; \ 611cb0ef41Sopenharmony_ci thread_basic_info_data_t info; \ 621cb0ef41Sopenharmony_ci mach_msg_type_number_t count; \ 631cb0ef41Sopenharmony_ci count = THREAD_BASIC_INFO_COUNT; \ 641cb0ef41Sopenharmony_ci thread = pthread_mach_thread_np(pthread_self()); \ 651cb0ef41Sopenharmony_ci if (KERN_SUCCESS != thread_info(thread, \ 661cb0ef41Sopenharmony_ci THREAD_BASIC_INFO, \ 671cb0ef41Sopenharmony_ci (thread_info_t) &info, \ 681cb0ef41Sopenharmony_ci &count)) { \ 691cb0ef41Sopenharmony_ci return UVWASI_ENOSYS; \ 701cb0ef41Sopenharmony_ci } \ 711cb0ef41Sopenharmony_ci (time) = ((uvwasi_timestamp_t)(info.user_time.seconds) * NANOS_PER_SEC) + \ 721cb0ef41Sopenharmony_ci (info.user_time.microseconds * 1000) + \ 731cb0ef41Sopenharmony_ci ((uvwasi_timestamp_t)(info.system_time.seconds) * NANOS_PER_SEC) + \ 741cb0ef41Sopenharmony_ci (info.system_time.microseconds * 1000); \ 751cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; \ 761cb0ef41Sopenharmony_ci } while (0) 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci#define UVWASI__WIN_GETRES_AND_RETURN(time) \ 801cb0ef41Sopenharmony_ci do { \ 811cb0ef41Sopenharmony_ci /* The GetProcessTimes() docs claim a resolution of 100 ns. */ \ 821cb0ef41Sopenharmony_ci (time) = 100; \ 831cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; \ 841cb0ef41Sopenharmony_ci } while (0) 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci#define UVWASI__CLOCK_GETRES_AND_RETURN(clk, time) \ 881cb0ef41Sopenharmony_ci do { \ 891cb0ef41Sopenharmony_ci struct timespec ts; \ 901cb0ef41Sopenharmony_ci /* Try calling clock_getres(). If it doesn't succeed, then default to \ 911cb0ef41Sopenharmony_ci 1000000. We implement all of the clocks, and some platforms (such as \ 921cb0ef41Sopenharmony_ci SmartOS) don't support all of the clocks, even though they define \ 931cb0ef41Sopenharmony_ci the constants for them. */ \ 941cb0ef41Sopenharmony_ci if (0 != clock_getres((clk), &ts)) \ 951cb0ef41Sopenharmony_ci (time) = 1000000; \ 961cb0ef41Sopenharmony_ci else \ 971cb0ef41Sopenharmony_ci (time) = ((uvwasi_timestamp_t)(ts.tv_sec) * NANOS_PER_SEC) + ts.tv_nsec; \ 981cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; \ 991cb0ef41Sopenharmony_ci } while (0) 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci#define UVWASI__SLOW_GETRES_AND_RETURN(time) \ 1031cb0ef41Sopenharmony_ci do { \ 1041cb0ef41Sopenharmony_ci /* Assume a "worst case" of 1000000 ns resolution. */ \ 1051cb0ef41Sopenharmony_ci (time) = 1000000; \ 1061cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; \ 1071cb0ef41Sopenharmony_ci } while (0) 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi__clock_gettime_realtime(uvwasi_timestamp_t* time) { 1111cb0ef41Sopenharmony_ci uv_timeval64_t tv; 1121cb0ef41Sopenharmony_ci int r; 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci r = uv_gettimeofday(&tv); 1151cb0ef41Sopenharmony_ci if (r != 0) 1161cb0ef41Sopenharmony_ci return uvwasi__translate_uv_error(r); 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci *time = (tv.tv_sec * NANOS_PER_SEC) + (tv.tv_usec * 1000); 1191cb0ef41Sopenharmony_ci return UVWASI_ESUCCESS; 1201cb0ef41Sopenharmony_ci} 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi__clock_gettime_process_cputime(uvwasi_timestamp_t* time) { 1241cb0ef41Sopenharmony_ci#if defined(_WIN32) 1251cb0ef41Sopenharmony_ci UVWASI__WIN_TIME_AND_RETURN(GetCurrentProcess(), GetProcessTimes, *time); 1261cb0ef41Sopenharmony_ci#elif defined(CLOCK_PROCESS_CPUTIME_ID) && \ 1271cb0ef41Sopenharmony_ci !defined(__APPLE__) && \ 1281cb0ef41Sopenharmony_ci !defined(__sun) 1291cb0ef41Sopenharmony_ci UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_PROCESS_CPUTIME_ID, *time); 1301cb0ef41Sopenharmony_ci#else 1311cb0ef41Sopenharmony_ci UVWASI__GETRUSAGE_AND_RETURN(RUSAGE_SELF, *time); 1321cb0ef41Sopenharmony_ci#endif 1331cb0ef41Sopenharmony_ci} 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi__clock_gettime_thread_cputime(uvwasi_timestamp_t* time) { 1371cb0ef41Sopenharmony_ci#if defined(_WIN32) 1381cb0ef41Sopenharmony_ci UVWASI__WIN_TIME_AND_RETURN(GetCurrentThread(), GetThreadTimes, *time); 1391cb0ef41Sopenharmony_ci#elif defined(__APPLE__) 1401cb0ef41Sopenharmony_ci UVWASI__OSX_THREADTIME_AND_RETURN(*time); 1411cb0ef41Sopenharmony_ci#elif defined(CLOCK_THREAD_CPUTIME_ID) && !defined(__sun) && !defined(__PASE__) 1421cb0ef41Sopenharmony_ci UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_THREAD_CPUTIME_ID, *time); 1431cb0ef41Sopenharmony_ci#else 1441cb0ef41Sopenharmony_ci# if defined(RUSAGE_LWP) 1451cb0ef41Sopenharmony_ci UVWASI__GETRUSAGE_AND_RETURN(RUSAGE_LWP, *time); 1461cb0ef41Sopenharmony_ci# elif defined(RUSAGE_THREAD) 1471cb0ef41Sopenharmony_ci UVWASI__GETRUSAGE_AND_RETURN(RUSAGE_THREAD, *time); 1481cb0ef41Sopenharmony_ci# else 1491cb0ef41Sopenharmony_ci return UVWASI_ENOSYS; 1501cb0ef41Sopenharmony_ci# endif /* RUSAGE_LWP */ 1511cb0ef41Sopenharmony_ci#endif 1521cb0ef41Sopenharmony_ci} 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi__clock_getres_process_cputime(uvwasi_timestamp_t* time) { 1561cb0ef41Sopenharmony_ci#if defined(_WIN32) 1571cb0ef41Sopenharmony_ci UVWASI__WIN_GETRES_AND_RETURN(*time); 1581cb0ef41Sopenharmony_ci#elif defined(CLOCK_PROCESS_CPUTIME_ID) && \ 1591cb0ef41Sopenharmony_ci !defined(__APPLE__) && \ 1601cb0ef41Sopenharmony_ci !defined(__sun) 1611cb0ef41Sopenharmony_ci UVWASI__CLOCK_GETRES_AND_RETURN(CLOCK_PROCESS_CPUTIME_ID, *time); 1621cb0ef41Sopenharmony_ci#else 1631cb0ef41Sopenharmony_ci UVWASI__SLOW_GETRES_AND_RETURN(*time); 1641cb0ef41Sopenharmony_ci#endif 1651cb0ef41Sopenharmony_ci} 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ciuvwasi_errno_t uvwasi__clock_getres_thread_cputime(uvwasi_timestamp_t* time) { 1691cb0ef41Sopenharmony_ci#if defined(_WIN32) 1701cb0ef41Sopenharmony_ci UVWASI__WIN_GETRES_AND_RETURN(*time); 1711cb0ef41Sopenharmony_ci#elif defined(__APPLE__) 1721cb0ef41Sopenharmony_ci UVWASI__SLOW_GETRES_AND_RETURN(*time); 1731cb0ef41Sopenharmony_ci#elif defined(CLOCK_THREAD_CPUTIME_ID) && !defined(__sun) && !defined(__PASE__) 1741cb0ef41Sopenharmony_ci UVWASI__CLOCK_GETTIME_AND_RETURN(CLOCK_THREAD_CPUTIME_ID, *time); 1751cb0ef41Sopenharmony_ci#elif defined(RUSAGE_THREAD) || defined(RUSAGE_LWP) 1761cb0ef41Sopenharmony_ci UVWASI__SLOW_GETRES_AND_RETURN(*time); 1771cb0ef41Sopenharmony_ci#else 1781cb0ef41Sopenharmony_ci return UVWASI_ENOSYS; 1791cb0ef41Sopenharmony_ci#endif 1801cb0ef41Sopenharmony_ci} 181