1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
#include "./WASIPrivate.h"
#include "WAVM/Inline/BasicTypes.h"
#include "WAVM/Inline/I128.h"
#include "WAVM/Platform/Clock.h"
#include "WAVM/Runtime/Intrinsics.h"
#include "WAVM/Runtime/Runtime.h"
#include "WAVM/WASI/WASI.h"
#include "WAVM/WASI/WASIABI.h"
using namespace WAVM;
using namespace WAVM::WASI;
using namespace WAVM::Runtime;
namespace WAVM { namespace WASI {
WAVM_DEFINE_INTRINSIC_MODULE(wasiClocks)
}}
static bool getPlatformClock(__wasi_clockid_t clock, Platform::Clock& outPlatformClock)
{
switch(clock)
{
case __WASI_CLOCK_REALTIME: outPlatformClock = Platform::Clock::realtime; return true;
case __WASI_CLOCK_MONOTONIC: outPlatformClock = Platform::Clock::monotonic; return true;
case __WASI_CLOCK_PROCESS_CPUTIME_ID:
case __WASI_CLOCK_THREAD_CPUTIME_ID:
outPlatformClock = Platform::Clock::processCPUTime;
return true;
default: return false;
}
}
WAVM_DEFINE_INTRINSIC_FUNCTION(wasiClocks,
"clock_res_get",
__wasi_errno_return_t,
__wasi_clock_res_get,
__wasi_clockid_t clockId,
WASIAddress resolutionAddress)
{
TRACE_SYSCALL("clock_res_get", "(%u, " WASIADDRESS_FORMAT ")", clockId, resolutionAddress);
Platform::Clock platformClock;
if(!getPlatformClock(clockId, platformClock)) { return TRACE_SYSCALL_RETURN(__WASI_EINVAL); }
const Time clockResolution = Platform::getClockResolution(platformClock);
Process* process = getProcessFromContextRuntimeData(contextRuntimeData);
__wasi_timestamp_t wasiClockResolution = __wasi_timestamp_t(clockResolution.ns);
memoryRef<__wasi_timestamp_t>(process->memory, resolutionAddress) = wasiClockResolution;
return TRACE_SYSCALL_RETURN(__WASI_ESUCCESS, "(%" PRIu64 ")", wasiClockResolution);
}
WAVM_DEFINE_INTRINSIC_FUNCTION(wasiClocks,
"clock_time_get",
__wasi_errno_return_t,
__wasi_clock_time_get,
__wasi_clockid_t clockId,
__wasi_timestamp_t precision,
WASIAddress timeAddress)
{
TRACE_SYSCALL("clock_time_get",
"(%u, %" PRIu64 ", " WASIADDRESS_FORMAT ")",
clockId,
precision,
timeAddress);
Process* process = getProcessFromContextRuntimeData(contextRuntimeData);
Platform::Clock platformClock;
if(!getPlatformClock(clockId, platformClock)) { return TRACE_SYSCALL_RETURN(__WASI_EINVAL); }
Time clockTime = Platform::getClockTime(platformClock);
if(platformClock == Platform::Clock::processCPUTime)
{ clockTime.ns -= process->processClockOrigin.ns; }
__wasi_timestamp_t wasiClockTime = __wasi_timestamp_t(clockTime.ns);
memoryRef<__wasi_timestamp_t>(process->memory, timeAddress) = wasiClockTime;
return TRACE_SYSCALL_RETURN(__WASI_ESUCCESS, "(%" PRIu64 ")", wasiClockTime);
}
|