1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * NaCl Server Runtime time abstraction layer.
9 : * This is the host-OS-dependent implementation.
10 : */
11 :
12 : #include <sys/time.h>
13 : #include <time.h>
14 :
15 : #include "native_client/src/include/nacl_macros.h"
16 : #include "native_client/src/shared/platform/nacl_log.h"
17 : #include "native_client/src/shared/platform/nacl_time.h"
18 : #include "native_client/src/shared/platform/posix/nacl_time_types.h"
19 :
20 : #include "native_client/src/trusted/service_runtime/linux/nacl_syscall_inl.h"
21 :
22 : #define NANOS_PER_UNIT (1000*1000*1000)
23 :
24 : static struct NaClTimeState gNaClTimeState;
25 :
26 : void NaClAllowLowResolutionTimeOfDay(void) {
27 : /* Always use high resolution timer. */
28 0 : }
29 :
30 333 : void NaClTimeInternalInit(struct NaClTimeState *ntsp) {
31 333 : ntsp->time_resolution_ns = NACL_NANOS_PER_MICRO;
32 333 : }
33 :
34 54 : void NaClTimeInternalFini(struct NaClTimeState *ntsp) {
35 108 : UNREFERENCED_PARAMETER(ntsp);
36 54 : }
37 :
38 2 : uint64_t NaClTimerResolutionNsInternal(struct NaClTimeState *ntsp) {
39 2 : return ntsp->time_resolution_ns;
40 : }
41 :
42 : void NaClTimeInit(void) {
43 333 : NaClTimeInternalInit(&gNaClTimeState);
44 333 : }
45 :
46 : void NaClTimeFini(void) {
47 54 : NaClTimeInternalFini(&gNaClTimeState);
48 54 : }
49 :
50 : uint64_t NaClTimerResolutionNanoseconds(void) {
51 2 : return NaClTimerResolutionNsInternal(&gNaClTimeState);
52 : }
53 :
54 5487 : int NaClGetTimeOfDay(struct nacl_abi_timeval *tv) {
55 5487 : struct timeval sys_tv;
56 5487 : int retval;
57 :
58 5487 : retval = gettimeofday(&sys_tv, NULL);
59 5487 : if (0 == retval) {
60 5487 : tv->nacl_abi_tv_sec = sys_tv.tv_sec;
61 5487 : tv->nacl_abi_tv_usec = sys_tv.tv_usec;
62 5487 : }
63 :
64 5487 : retval = NaClXlateSysRet(retval);
65 5487 : return retval;
66 : }
67 :
68 145 : int NaClNanosleep(struct nacl_abi_timespec const *req,
69 145 : struct nacl_abi_timespec *rem) {
70 145 : struct timespec host_req;
71 145 : struct timespec host_rem;
72 145 : struct timespec *host_remptr;
73 145 : int retval;
74 :
75 145 : host_req.tv_sec = req->tv_sec;
76 145 : host_req.tv_nsec = req->tv_nsec;
77 145 : if (NULL == rem) {
78 84 : host_remptr = NULL;
79 84 : } else {
80 61 : host_remptr = &host_rem;
81 : }
82 144 : NaClLog(4,
83 : "nanosleep(%"NACL_PRIxPTR", %"NACL_PRIxPTR")\n",
84 : (uintptr_t) &host_req,
85 : (uintptr_t) host_remptr);
86 144 : NaClLog(4, "nanosleep(time = %"NACL_PRId64".%09"NACL_PRId64" S)\n",
87 : (int64_t) host_req.tv_sec, (int64_t) host_req.tv_nsec);
88 144 : if (host_req.tv_nsec > NANOS_PER_UNIT) {
89 0 : NaClLog(4, "tv_nsec too large %"NACL_PRId64"\n",
90 : (int64_t) host_req.tv_nsec);
91 0 : }
92 140 : retval = nanosleep(&host_req, host_remptr);
93 140 : NaClLog(4, " returned %d\n", retval);
94 :
95 140 : if (0 != retval && EINTR == errno && NULL != rem) {
96 0 : rem->tv_sec = host_rem.tv_sec;
97 0 : rem->tv_nsec = host_rem.tv_nsec;
98 0 : }
99 140 : retval = NaClXlateSysRet(retval);
100 140 : return retval;
101 : }
|