Forráskód Böngészése

[LibOS] Fix timeout resolution for epoll_wait()/epoll_pwait()

Internal LibOS and PAL interfaces use microseconds (us) for timeout
values. However, Linux epoll_wait/epoll_pwait syscalls use milliseconds
(ms) for timeout. Previously, there was a bug in timeout resolution
because epoll_wait() emulation did not convert from ms to us. This
commit fixes this bug and also adds suffixes "_ms" and "_us" to make the
time units used explicit.
Chia-Che Tsai 5 éve
szülő
commit
f2591790d7

+ 4 - 4
LibOS/shim/include/shim_table.h

@@ -460,7 +460,7 @@ int shim_do_semtimedop (int semid, struct sembuf * sops, unsigned int nsops,
 int shim_do_epoll_create (int size);
 size_t shim_do_getdents64 (int fd, struct linux_dirent64 * buf, size_t count);
 int shim_do_epoll_wait (int epfd, struct __kernel_epoll_event * events,
-                        int maxevents, int timeout);
+                        int maxevents, int timeout_ms);
 int shim_do_epoll_ctl (int epfd, int op, int fd,
                        struct __kernel_epoll_event * event);
 int shim_do_clock_gettime (clockid_t which_clock,
@@ -489,7 +489,7 @@ int shim_do_set_robust_list (struct robust_list_head * head, size_t len);
 int shim_do_get_robust_list (pid_t pid, struct robust_list_head ** head,
                              size_t * len);
 int shim_do_epoll_pwait (int epfd, struct __kernel_epoll_event * events,
-                         int maxevents, int timeout, const __sigset_t * sigmask,
+                         int maxevents, int timeout_ms, const __sigset_t * sigmask,
                          size_t sigsetsize);
 int shim_do_accept4 (int sockfd, struct sockaddr * addr, socklen_t * addrlen,
                      int flags);
@@ -770,7 +770,7 @@ int shim_clock_nanosleep (clockid_t which_clock, int flags,
                           const struct timespec * rqtp, struct timespec * rmtp);
 int shim_exit_group (int error_code);
 int shim_epoll_wait (int epfd, struct __kernel_epoll_event * events,
-                     int maxevents, int timeout);
+                     int maxevents, int timeout_ms);
 int shim_epoll_ctl (int epfd, int op, int fd,
                     struct __kernel_epoll_event * event);
 int shim_tgkill (int tgid, int pid, int sig);
@@ -840,7 +840,7 @@ int shim_move_pages (pid_t pid, unsigned long nr_pages, void ** pages,
 int shim_utimensat (int dfd, const char * filename, struct timespec *
                     utimes, int flags);
 int shim_epoll_pwait (int epfd, struct __kernel_epoll_event * events,
-                      int maxevents, int timeout, const __sigset_t * sigmask,
+                      int maxevents, int timeout_ms, const __sigset_t * sigmask,
                       size_t sigsetsize);
 int shim_signalfd (int ufd, __sigset_t * user_mask, size_t sizemask);
 int shim_timerfd_create (int clockid, int flags);

+ 2 - 2
LibOS/shim/src/shim_syscalls.c

@@ -898,7 +898,7 @@ DEFINE_SHIM_SYSCALL (exit_group, 1, shim_do_exit_group, int, int, error_code)
 
 DEFINE_SHIM_SYSCALL (epoll_wait, 4, shim_do_epoll_wait, int, int, epfd,
                           struct __kernel_epoll_event *, events,
-                          int, maxevents, int, timeout)
+                          int, maxevents, int, timeout_ms)
 
 DEFINE_SHIM_SYSCALL (epoll_ctl, 4, shim_do_epoll_ctl, int, int, epfd, int, op, int, fd,
                           struct __kernel_epoll_event *, event)
@@ -1076,7 +1076,7 @@ SHIM_SYSCALL_PASSTHROUGH (utimensat, 4, int, int, dfd, const char *, filename,
 
 DEFINE_SHIM_SYSCALL (epoll_pwait, 6, shim_do_epoll_pwait, int, int, epfd,
                           struct __kernel_epoll_event *, events, int, maxevents,
-                          int, timeout, const __sigset_t *, sigmask,
+                          int, timeout_ms, const __sigset_t *, sigmask,
                           size_t, sigsetsize)
 
 SHIM_SYSCALL_PASSTHROUGH (signalfd, 3, int, int, ufd, __sigset_t *, user_mask,

+ 5 - 4
LibOS/shim/src/sys/shim_epoll.c

@@ -287,7 +287,7 @@ out:
 }
 
 int shim_do_epoll_wait (int epfd, struct __kernel_epoll_event * events,
-                        int maxevents, int timeout)
+                        int maxevents, int timeout_ms)
 {
     int ret = 0;
     struct shim_handle * epoll_hdl = get_fd_handle(epfd, NULL, NULL);
@@ -320,8 +320,9 @@ retry:
 
     unlock(&epoll_hdl->lock);
 
+    PAL_NUM pal_timeout = timeout_ms == -1 ? NO_TIMEOUT : (PAL_NUM) timeout_ms * 1000;
     PAL_HANDLE polled = DkObjectsWaitAny(nread ? npals + 1 : npals, pal_handles,
-                                         nread ? (timeout == -1 ? NO_TIMEOUT : (PAL_NUM) timeout) : 0);
+                                         nread ? pal_timeout : 0);
 
     lock(&epoll_hdl->lock);
 
@@ -383,12 +384,12 @@ reply:
 }
 
 int shim_do_epoll_pwait (int epfd, struct __kernel_epoll_event * events,
-                         int maxevents, int timeout, const __sigset_t * sigmask,
+                         int maxevents, int timeout_ms, const __sigset_t * sigmask,
                          size_t sigsetsize)
 {
     __UNUSED(sigmask);
     __UNUSED(sigsetsize);
-    int ret = shim_do_epoll_wait (epfd, events, maxevents, timeout);
+    int ret = shim_do_epoll_wait (epfd, events, maxevents, timeout_ms);
     return ret;
 }
 

+ 13 - 23
LibOS/shim/src/sys/shim_poll.c

@@ -101,10 +101,9 @@ struct poll_handle {
     struct poll_handle * children;
 } __attribute__((packed));
 
-#define POLL_NOTIMEOUT  ((unsigned long)-1)
+#define POLL_NOTIMEOUT  ((uint64_t)-1)
 
-static int __do_poll (int npolls, struct poll_handle * polls,
-                      unsigned long timeout)
+static int __do_poll(int npolls, struct poll_handle* polls, uint64_t timeout_us)
 {
     struct shim_thread * cur = get_cur_thread();
 
@@ -306,10 +305,10 @@ done_finding:
     SAVE_PROFILE_INTERVAL(do_poll_second_loop);
 
     while (npals) {
-        int pal_timeout = (has_r && !has_known) ? timeout : 0;
-        PAL_HANDLE polled = DkObjectsWaitAny(npals, pals, pal_timeout);
+        int pal_timeout_us = (has_r && !has_known) ? timeout_us : 0;
+        PAL_HANDLE polled = DkObjectsWaitAny(npals, pals, pal_timeout_us);
 
-        if (pal_timeout)
+        if (pal_timeout_us)
             SAVE_PROFILE_INTERVAL(do_poll_wait_any);
         else
             SAVE_PROFILE_INTERVAL(do_poll_wait_any_peek);
@@ -385,7 +384,7 @@ done_polling:
     return ret;
 }
 
-int shim_do_poll (struct pollfd * fds, nfds_t nfds, int timeout)
+int shim_do_poll (struct pollfd * fds, nfds_t nfds, int timeout_ms)
 {
     struct shim_thread * cur = get_cur_thread();
 
@@ -402,7 +401,7 @@ int shim_do_poll (struct pollfd * fds, nfds_t nfds, int timeout)
     }
 
     int ret = __do_poll(nfds, polls,
-                        timeout < 0 ? POLL_NOTIMEOUT : timeout * 1000ULL);
+                        timeout_ms < 0 ? POLL_NOTIMEOUT : timeout_ms * 1000ULL);
 
     if (ret < 0)
         goto out;
@@ -448,11 +447,8 @@ int shim_do_ppoll (struct pollfd * fds, int nfds, struct timespec * tsp,
             polls[i].flags |= DO_W;
     }
 
-    unsigned long timeout = tsp ?
-                            tsp->tv_sec * 1000000ULL + tsp->tv_nsec / 1000 :
-                            POLL_NOTIMEOUT;
-
-    int ret = __do_poll(nfds, polls, timeout);
+    uint64_t timeout_us = tsp ? tsp->tv_sec * 1000000ULL + tsp->tv_nsec / 1000 : POLL_NOTIMEOUT;
+    int ret = __do_poll(nfds, polls, timeout_us);
 
     if (ret < 0)
         goto out;
@@ -552,11 +548,8 @@ int shim_do_select (int nfds, fd_set * readfds, fd_set * writefds,
 
     SAVE_PROFILE_INTERVAL(select_setup_array);
 
-    unsigned long timeout = tsv ?
-                            tsv->tv_sec * 1000000ULL + tsv->tv_usec :
-                            POLL_NOTIMEOUT;
-
-    int ret = __do_poll(npolls, polls, timeout);
+    uint64_t timeout_us = tsv ? tsv->tv_sec * 1000000ULL + tsv->tv_usec : POLL_NOTIMEOUT;
+    int ret = __do_poll(npolls, polls, timeout_us);
 
     SAVE_PROFILE_INTERVAL(select_do_poll);
 
@@ -620,11 +613,8 @@ int shim_do_pselect6 (int nfds, fd_set * readfds, fd_set * writefds,
         npolls++;
     }
 
-    unsigned long timeout = tsp ?
-                            tsp->tv_sec * 1000000ULL + tsp->tv_nsec / 1000 :
-                            POLL_NOTIMEOUT;
-
-    int ret = __do_poll(npolls, polls, timeout);
+    uint64_t timeout_us = tsp ? tsp->tv_sec * 1000000ULL + tsp->tv_nsec / 1000 : POLL_NOTIMEOUT;
+    int ret = __do_poll(npolls, polls, timeout_us);
 
     if (ret < 0)
         goto out;

+ 4 - 7
Pal/src/db_object.c

@@ -71,12 +71,10 @@ void DkObjectClose (PAL_HANDLE objectHandle)
     LEAVE_PAL_CALL();
 }
 
-/* PAL call DkObjectsWaitAny: wait for any of the handles in the handle array.
-   The wait can be timed out, unless NO_TIMEOUT is given for the timeout
-   argument. */
+// PAL call DkObjectsWaitAny: wait for any of the handles in the handle array.
+// The wait can be timed out, unless NO_TIMEOUT is given for the timeout_us argument.
 PAL_HANDLE
-DkObjectsWaitAny (PAL_NUM count, PAL_HANDLE * handleArray, PAL_NUM timeout)
-{
+DkObjectsWaitAny(PAL_NUM count, PAL_HANDLE* handleArray, PAL_NUM timeout_us) {
     ENTER_PAL_CALL(DkObjectsWaitAny);
 
     if (!count || !handleArray) {
@@ -91,8 +89,7 @@ DkObjectsWaitAny (PAL_NUM count, PAL_HANDLE * handleArray, PAL_NUM timeout)
 
     PAL_HANDLE polled = NULL;
 
-    int ret = _DkObjectsWaitAny (count, handleArray, timeout, &polled);
-
+    int ret = _DkObjectsWaitAny(count, handleArray, timeout_us, &polled);
     if (ret < 0) {
         _DkRaiseFailure(-ret);
         polled = NULL;

+ 11 - 13
Pal/src/host/Linux-SGX/db_events.c

@@ -63,7 +63,7 @@ int _DkEventSet (PAL_HANDLE event, int wakeup)
                     nwaiters = wakeup;
 
                 ret = ocall_futex((int *) &event->event.signaled->counter,
-                                  FUTEX_WAKE, nwaiters, NULL);
+                                  FUTEX_WAKE, nwaiters, -1);
 
                 if (IS_ERR(ret)) {
                     atomic_set(event->event.signaled, 0);
@@ -74,7 +74,7 @@ int _DkEventSet (PAL_HANDLE event, int wakeup)
     } else {
         // Only one thread wakes up, leave unsignaled
         ret = ocall_futex((int *) &event->event.signaled->counter,
-                          FUTEX_WAKE, 1, NULL);
+                          FUTEX_WAKE, 1, -1);
         if (IS_ERR(ret))
             return unix_to_pal_error(ERRNO(ret));
     }
@@ -82,18 +82,18 @@ int _DkEventSet (PAL_HANDLE event, int wakeup)
     return ret;
 }
 
-int _DkEventWaitTimeout (PAL_HANDLE event, PAL_NUM timeout)
-{
+int _DkEventWaitTimeout(PAL_HANDLE event, int64_t timeout_us) {
     int ret = 0;
 
-    if (!event->event.isnotification || !atomic_read(event->event.signaled)) {
-        int64_t waittime = timeout;
+    if (timeout_us < 0)
+        return _DkEventWait(event);
 
+    if (!event->event.isnotification || !atomic_read(event->event.signaled)) {
         atomic_inc(&event->event.nwaiters);
 
         do {
-            ret = ocall_futex((int *) &event->event.signaled->counter,
-                              FUTEX_WAIT, 0, timeout != NO_TIMEOUT ? &waittime : NULL);
+            ret = ocall_futex((int*)&event->event.signaled->counter, FUTEX_WAIT, 0, timeout_us);
+
             if (IS_ERR(ret)) {
                 if (ERRNO(ret) == EWOULDBLOCK) {
                     ret = 0;
@@ -120,7 +120,7 @@ int _DkEventWait (PAL_HANDLE event)
 
         do {
             ret = ocall_futex((int *) &event->event.signaled->counter,
-                              FUTEX_WAIT, 0, NULL);
+                              FUTEX_WAIT, 0, -1);
             if (IS_ERR(ret)) {
                 if (ERRNO(ret) == EWOULDBLOCK) {
                     ret = 0;
@@ -151,10 +151,8 @@ static int event_close (PAL_HANDLE handle)
     return 0;
 }
 
-static int event_wait (PAL_HANDLE handle, PAL_NUM timeout)
-{
-    return timeout == NO_TIMEOUT ? _DkEventWait(handle) :
-           _DkEventWaitTimeout(handle, timeout);
+static int event_wait(PAL_HANDLE handle, int64_t timeout_us) {
+    return _DkEventWaitTimeout(handle, timeout_us);
 }
 
 struct handle_ops event_ops = {

+ 9 - 15
Pal/src/host/Linux-SGX/db_mutex.c

@@ -60,14 +60,13 @@ _DkMutexCreate (PAL_HANDLE * handle, int initialCount)
     return 0;
 }
 
-int _DkMutexLockTimeout (struct mutex_handle * m, PAL_NUM timeout)
-{
+int _DkMutexLockTimeout(struct mutex_handle* m, int64_t timeout_us) {
     int ret = 0;
 
     if (MUTEX_UNLOCKED == cmpxchg(m->locked, MUTEX_UNLOCKED, MUTEX_LOCKED))
         goto success;
 
-    if (timeout == 0) {
+    if (timeout_us == 0) {
         ret = -PAL_ERROR_TRYAGAIN;
         goto out;
     }
@@ -81,8 +80,7 @@ int _DkMutexLockTimeout (struct mutex_handle * m, PAL_NUM timeout)
          * can be used for futex. Potentially this design may allow
          * attackers to change the mutex value and cause DoS.
          */
-        int64_t waittime = timeout;
-        ret = ocall_futex((int *) m->locked, FUTEX_WAIT, MUTEX_LOCKED, timeout == NO_TIMEOUT ? NULL : &waittime);
+        ret = ocall_futex((int*)m->locked, FUTEX_WAIT, MUTEX_LOCKED, timeout_us);
 
         if (IS_ERR(ret)) {
             if (ERRNO(ret) == EWOULDBLOCK) {
@@ -104,15 +102,12 @@ out:
     return ret;
 }
 
-int _DkMutexLock (struct mutex_handle * m)
-{
+int _DkMutexLock(struct mutex_handle* m) {
     return _DkMutexLockTimeout(m, -1);
 }
 
-int _DkMutexAcquireTimeout (PAL_HANDLE handle, PAL_NUM _timeout)
-{
-    struct mutex_handle * mut = &handle->mutex.mut;
-    return _DkMutexLockTimeout(mut, _timeout);
+int _DkMutexAcquireTimeout(PAL_HANDLE handle, int64_t timeout_us) {
+    return _DkMutexLockTimeout(&handle->mutex.mut, timeout_us);
 }
 
 int _DkMutexUnlock (struct mutex_handle * m)
@@ -130,7 +125,7 @@ int _DkMutexUnlock (struct mutex_handle * m)
 
     /* If we need to wake someone up... */
     if (need_wake)
-        ocall_futex((int *) m->locked, FUTEX_WAKE, 1, NULL);
+        ocall_futex((int *) m->locked, FUTEX_WAKE, 1, -1);
 
     return ret;
 }
@@ -144,9 +139,8 @@ void _DkMutexRelease (PAL_HANDLE handle)
     return;
 }
 
-static int mutex_wait (PAL_HANDLE handle, PAL_NUM timeout)
-{
-    return _DkMutexAcquireTimeout(handle, timeout);
+static int mutex_wait (PAL_HANDLE handle, int64_t timeout_us) {
+    return _DkMutexAcquireTimeout(handle, timeout_us);
 }
 
 static int mutex_close (PAL_HANDLE handle)

+ 8 - 12
Pal/src/host/Linux-SGX/db_object.c

@@ -39,8 +39,7 @@
 
 /* internally to wait for one object. Also used as a shortcut to wait
    on events and semaphores */
-static int _DkObjectWaitOne (PAL_HANDLE handle, PAL_NUM timeout)
-{
+static int _DkObjectWaitOne(PAL_HANDLE handle, int64_t timeout_us) {
     /* only for all these handle which has a file descriptor, or
        a eventfd. events and semaphores will skip this part */
     if (HANDLE_HDR(handle)->flags & HAS_FDS) {
@@ -71,8 +70,7 @@ static int _DkObjectWaitOne (PAL_HANDLE handle, PAL_NUM timeout)
         if (!nfds)
             return -PAL_ERROR_TRYAGAIN;
 
-        int64_t waittime = timeout;
-        int ret = ocall_poll(fds, nfds, timeout != NO_TIMEOUT ? &waittime : NULL);
+        int ret = ocall_poll(fds, nfds, timeout_us);
         if (IS_ERR(ret))
             return unix_to_pal_error(ERRNO(ret));
 
@@ -96,14 +94,13 @@ static int _DkObjectWaitOne (PAL_HANDLE handle, PAL_NUM timeout)
     if (!ops || !ops->wait)
         return -PAL_ERROR_NOTSUPPORT;
 
-    return ops->wait(handle, timeout);
+    return ops->wait(handle, timeout_us);
 }
 
 /* _DkObjectsWaitAny for internal use. The function wait for any of the handle
-   in the handle array. timeout can be set for the wait. */
-int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, PAL_NUM timeout,
-                       PAL_HANDLE * polled)
-{
+   in the handle array. timeout_us can be set for the wait. */
+int _DkObjectsWaitAny(int count, PAL_HANDLE* handleArray, int64_t timeout_us,
+                      PAL_HANDLE* polled) {
     if (count <= 0)
         return 0;
 
@@ -113,7 +110,7 @@ int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, PAL_NUM timeout,
         if (!handleArray[0])
             return -PAL_ERROR_TRYAGAIN;
 
-        int rv = _DkObjectWaitOne(handleArray[0], timeout);
+        int rv = _DkObjectWaitOne(handleArray[0], timeout_us);
         if (rv == 0)
             *polled = handleArray[0];
         return rv;
@@ -184,8 +181,7 @@ int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, PAL_NUM timeout,
     if (!nfds)
         return -PAL_ERROR_TRYAGAIN;
 
-    int64_t waittime = timeout;
-    ret = ocall_poll(fds, nfds, timeout != NO_TIMEOUT ? &waittime : NULL);
+    ret = ocall_poll(fds, nfds, timeout_us);
     if (IS_ERR(ret))
         return unix_to_pal_error(ERRNO(ret));
 

+ 1 - 2
Pal/src/host/Linux-SGX/db_pipes.c

@@ -363,8 +363,7 @@ static int pipe_attrquerybyhdl (PAL_HANDLE handle, PAL_STREAM_ATTR * attr)
     }
 
     struct pollfd pfd = { .fd = read_fd, .events = POLLIN, .revents = 0 };
-    int64_t waittime = 0;
-    int ret = ocall_poll(&pfd, 1, &waittime);
+    int ret = ocall_poll(&pfd, 1, 0);
     if (IS_ERR(ret))
         return unix_to_pal_error(ERRNO(ret));
 

+ 1 - 2
Pal/src/host/Linux-SGX/db_sockets.c

@@ -880,8 +880,7 @@ static int socket_attrquerybyhdl (PAL_HANDLE handle, PAL_STREAM_ATTR  * attr)
     }
 
     struct pollfd pfd = { .fd = fd, .events = POLLIN, .revents = 0 };
-    int64_t waittime = 0;
-    ret = ocall_poll(&pfd, 1, &waittime);
+    ret = ocall_poll(&pfd, 1, 0);
     if (IS_ERR(ret))
         return unix_to_pal_error(ERRNO(ret));
     attr->readable = (ret == 1 && pfd.revents == POLLIN);

+ 4 - 10
Pal/src/host/Linux-SGX/enclave_ocalls.c

@@ -532,9 +532,7 @@ int ocall_create_process (const char * uri,
     return retval;
 }
 
-int ocall_futex (int * futex, int op, int val,
-                 const int64_t * timeout)
-{
+int ocall_futex(int* futex, int op, int val, int64_t timeout_us) {
     int retval = 0;
     ms_ocall_futex_t * ms;
 
@@ -552,7 +550,7 @@ int ocall_futex (int * futex, int op, int val,
     ms->ms_futex = futex;
     ms->ms_op = op;
     ms->ms_val = val;
-    ms->ms_timeout = timeout ? *timeout : OCALL_NO_TIMEOUT;
+    ms->ms_timeout_us = timeout_us;
 
     retval = sgx_ocall(OCALL_FUTEX, ms);
 
@@ -1007,8 +1005,7 @@ int ocall_sleep (unsigned long * microsec)
     return retval;
 }
 
-int ocall_poll (struct pollfd * fds, int nfds, int64_t * timeout)
-{
+int ocall_poll(struct pollfd* fds, int nfds, int64_t timeout_us) {
     int retval = 0;
     unsigned int nfds_bytes = nfds * sizeof(struct pollfd);
     ms_ocall_poll_t * ms;
@@ -1020,7 +1017,7 @@ int ocall_poll (struct pollfd * fds, int nfds, int64_t * timeout)
     }
 
     ms->ms_nfds = nfds;
-    ms->ms_timeout = timeout ? *timeout : OCALL_NO_TIMEOUT;
+    ms->ms_timeout_us = timeout_us;
     ms->ms_fds = sgx_copy_to_ustack(fds, nfds_bytes);
 
     if (!ms->ms_fds) {
@@ -1030,9 +1027,6 @@ int ocall_poll (struct pollfd * fds, int nfds, int64_t * timeout)
 
     retval = sgx_ocall(OCALL_POLL, ms);
 
-    if (retval == -EINTR && timeout)
-        *timeout = ms->ms_timeout;
-
     if (retval >= 0) {
         if (!sgx_copy_to_enclave(fds, nfds_bytes, ms->ms_fds, nfds_bytes)) {
             sgx_reset_ustack();

+ 2 - 2
Pal/src/host/Linux-SGX/enclave_ocalls.h

@@ -85,7 +85,7 @@ int ocall_create_process (const char * uri,
                           int procfds[3],
                           unsigned int * pid);
 
-int ocall_futex (int * uaddr, int op, int val, const int64_t * timeout);
+int ocall_futex(int* uaddr, int op, int val, int64_t timeout_us);
 
 int ocall_gettime (unsigned long * microsec);
 
@@ -93,7 +93,7 @@ int ocall_sleep (unsigned long * microsec);
 
 int ocall_socketpair (int domain, int type, int protocol, int sockfds[2]);
 
-int ocall_poll (struct pollfd * fds, int nfds, int64_t * timeout);
+int ocall_poll(struct pollfd* fds, int nfds, int64_t timeout_us);
 
 int ocall_rename (const char * oldpath, const char * newpath);
 

+ 4 - 6
Pal/src/host/Linux-SGX/ocall_types.h

@@ -56,8 +56,6 @@ enum {
     OCALL_NR,
 };
 
-#define OCALL_NO_TIMEOUT   ((int64_t)-1)
-
 typedef struct {
     int ms_exitcode;
     int ms_is_exitgroup;
@@ -162,9 +160,9 @@ typedef struct {
 } ms_ocall_create_process_t;
 
 typedef struct {
-    int * ms_futex;
+    int* ms_futex;
     int ms_op, ms_val;
-    int64_t ms_timeout;
+    int64_t ms_timeout_us;
 } ms_ocall_futex_t;
 
 typedef struct {
@@ -249,9 +247,9 @@ typedef struct {
 } ms_ocall_sleep_t;
 
 typedef struct {
-    struct pollfd * ms_fds;
+    struct pollfd* ms_fds;
     int ms_nfds;
-    int64_t ms_timeout;
+    int64_t ms_timeout_us;
 } ms_ocall_poll_t;
 
 typedef struct {

+ 2 - 2
Pal/src/host/Linux-SGX/pal_linux.h

@@ -94,8 +94,8 @@ void pal_start_thread (void);
 int __DkMutexCreate (struct mutex_handle * mut);
 int _DkMutexAtomicCreate (struct mutex_handle * mut);
 int __DkMutexDestroy (struct mutex_handle * mut);
-int _DkMutexLock (struct mutex_handle * mut);
-int _DkMutexLockTimeout (struct mutex_handle * mut, PAL_NUM timeout);
+int _DkMutexLock(struct mutex_handle* mut);
+int _DkMutexLockTimeout(struct mutex_handle* mut, int64_t timeout_us);
 int _DkMutexUnlock (struct mutex_handle * mut);
 
 int * get_futex (void);

+ 7 - 7
Pal/src/host/Linux-SGX/sgx_enclave.c

@@ -248,11 +248,11 @@ static int sgx_ocall_futex(void * pms)
     ms_ocall_futex_t * ms = (ms_ocall_futex_t *) pms;
     int ret;
     ODEBUG(OCALL_FUTEX, ms);
-    struct timespec * ts = NULL;
-    if (ms->ms_timeout != OCALL_NO_TIMEOUT) {
+    struct timespec* ts = NULL;
+    if (ms->ms_timeout_us >= 0) {
         ts = __alloca(sizeof(struct timespec));
-        ts->tv_sec = ms->ms_timeout / 1000000;
-        ts->tv_nsec = (ms->ms_timeout - ts->tv_sec * 1000000) * 1000;
+        ts->tv_sec = ms->ms_timeout_us / 1000000;
+        ts->tv_nsec = (ms->ms_timeout_us - ts->tv_sec * 1000000) * 1000;
     }
     ret = INLINE_SYSCALL(futex, 6, ms->ms_futex, ms->ms_op, ms->ms_val,
                          ts, NULL, 0);
@@ -625,10 +625,10 @@ static int sgx_ocall_poll(void * pms)
     int ret;
     ODEBUG(OCALL_POLL, ms);
     struct timespec * ts = NULL;
-    if (ms->ms_timeout != OCALL_NO_TIMEOUT) {
+    if (ms->ms_timeout_us >= 0) {
         ts = __alloca(sizeof(struct timespec));
-        ts->tv_sec = ms->ms_timeout / 1000000;
-        ts->tv_nsec = (ms->ms_timeout - ts->tv_sec * 1000000) * 1000;
+        ts->tv_sec = ms->ms_timeout_us / 1000000;
+        ts->tv_nsec = (ms->ms_timeout_us - ts->tv_sec * 1000000) * 1000;
     }
     ret = INLINE_SYSCALL(ppoll, 4, ms->ms_fds, ms->ms_nfds, ts, NULL);
     return ret;

+ 10 - 9
Pal/src/host/Linux/db_events.c

@@ -72,14 +72,17 @@ int _DkEventSet (PAL_HANDLE event, int wakeup)
     return IS_ERR(ret) ? -PAL_ERROR_TRYAGAIN : ret;
 }
 
-int _DkEventWaitTimeout (PAL_HANDLE event, PAL_NUM timeout)
+int _DkEventWaitTimeout(PAL_HANDLE event, int64_t timeout_us)
 {
     int ret = 0;
 
+    if (timeout_us < 0)
+        return _DkEventWait(event);
+
     if (!event->event.isnotification || !atomic_read(&event->event.signaled)) {
         struct timespec waittime;
-        unsigned long sec = timeout / 1000000UL;
-        unsigned long microsec = timeout - (sec * 1000000UL);
+        int64_t sec = timeout_us / 1000000UL;
+        int64_t microsec = timeout_us - (sec * 1000000UL);
         waittime.tv_sec = sec;
         waittime.tv_nsec = microsec * 1000;
 
@@ -106,8 +109,7 @@ int _DkEventWaitTimeout (PAL_HANDLE event, PAL_NUM timeout)
     return ret;
 }
 
-int _DkEventWait (PAL_HANDLE event)
-{
+int _DkEventWait(PAL_HANDLE event) {
     int ret = 0;
 
     if (!event->event.isnotification || !atomic_read(&event->event.signaled)) {
@@ -146,11 +148,10 @@ static int event_close (PAL_HANDLE handle)
     return 0;
 }
 
-static int event_wait (PAL_HANDLE handle, PAL_NUM timeout)
-{
-    return timeout == NO_TIMEOUT ? _DkEventWait(handle) :
-           _DkEventWaitTimeout(handle, timeout);
+static int event_wait(PAL_HANDLE handle, int64_t timeout_us) {
+    return _DkEventWaitTimeout(handle, timeout_us);
 }
+
 struct handle_ops event_ops = {
         .close              = &event_close,
         .wait               = &event_wait,

+ 12 - 14
Pal/src/host/Linux/db_mutex.c

@@ -83,14 +83,14 @@ _DkMutexCreate (PAL_HANDLE * handle, int initialCount)
     return 0;
 }
 
-int _DkMutexLockTimeout (struct mutex_handle * m, PAL_NUM timeout)
+int _DkMutexLockTimeout(struct mutex_handle* m, int64_t timeout_us)
 {
     int i, ret = 0;
 #ifdef DEBUG_MUTEX
     int tid = INLINE_SYSCALL(gettid, 0);
 #endif
     /* If this is a trylock-style call, break more quickly. */
-    int iterations = (timeout == 0) ? 1 : MUTEX_SPINLOCK_TIMES;
+    int iterations = (timeout_us == 0) ? 1 : MUTEX_SPINLOCK_TIMES;
 
     /* Spin and try to take lock.  Ignore any contribution this makes toward
      * the timeout.*/
@@ -100,7 +100,7 @@ int _DkMutexLockTimeout (struct mutex_handle * m, PAL_NUM timeout)
         CPU_RELAX();
     }
 
-    if (timeout == 0) {
+    if (timeout_us == 0) {
         ret = -PAL_ERROR_TRYAGAIN;
         goto out;
     }
@@ -110,9 +110,9 @@ int _DkMutexLockTimeout (struct mutex_handle * m, PAL_NUM timeout)
 
     while (MUTEX_LOCKED == cmpxchg(&m->locked, MUTEX_UNLOCKED, MUTEX_LOCKED)) {
         struct timespec waittime, *waittimep = NULL;
-        if (timeout != NO_TIMEOUT) {
-            long sec = timeout / 1000000;
-            long microsec = timeout - (sec * 1000000);
+        if (timeout_us >= 0) {
+            int64_t sec = timeout_us / 1000000;
+            int64_t microsec = timeout_us - (sec * 1000000);
             waittime.tv_sec = sec;
             waittime.tv_nsec = microsec * 1000;
             waittimep = &waittime;
@@ -122,7 +122,7 @@ int _DkMutexLockTimeout (struct mutex_handle * m, PAL_NUM timeout)
 
         if (IS_ERR(ret)) {
             if (ERRNO(ret) == EWOULDBLOCK) {
-                if (timeout != NO_TIMEOUT) {
+                if (timeout_us >= 0) {
                     ret = -PAL_ERROR_TRYAGAIN;
                     atomic_dec(&m->nwaiters);
                     goto out;
@@ -154,14 +154,12 @@ out:
     return ret;
 }
 
-int _DkMutexLock (struct mutex_handle * m)
-{
+int _DkMutexLock(struct mutex_handle* m) {
     return _DkMutexLockTimeout(m, -1);
 }
 
-int _DkMutexAcquireTimeout (PAL_HANDLE handle, PAL_NUM timeout)
-{
-    return _DkMutexLockTimeout(&handle->mutex.mut, timeout);
+int _DkMutexAcquireTimeout(PAL_HANDLE handle, int64_t timeout_us) {
+    return _DkMutexLockTimeout(&handle->mutex.mut, timeout_us);
 }
 
 int _DkMutexUnlock (struct mutex_handle * m)
@@ -204,9 +202,9 @@ int _DkInternalUnlock (PAL_LOCK* lock) {
     return 0;
 }
 
-static int mutex_wait (PAL_HANDLE handle, PAL_NUM timeout)
+static int mutex_wait (PAL_HANDLE handle, int64_t timeout_us)
 {
-    return _DkMutexAcquireTimeout(handle, timeout);
+    return _DkMutexAcquireTimeout(handle, timeout_us);
 }
 
 struct handle_ops mutex_ops = {

+ 13 - 16
Pal/src/host/Linux/db_object.c

@@ -42,17 +42,15 @@
  *
  *  Returns 0 on success, negative value on failure (e.g., -PAL_ERROR_TRYAGAIN)
  */
-static int _DkObjectWaitOne (PAL_HANDLE handle, PAL_NUM timeout)
-{
+static int _DkObjectWaitOne(PAL_HANDLE handle, int64_t timeout_us) {
     /* only for all these handle which has a file descriptor, or
        a eventfd. events and semaphores will skip this part */
     if (HANDLE_HDR(handle)->flags & HAS_FDS) {
         struct timespec timeout_ts;
 
-        if (timeout != NO_TIMEOUT) {
-            long sec = (unsigned long) timeout / 1000000;
-            long microsec = (unsigned long) timeout - (sec * 1000000);
-
+        if (timeout_us >= 0) {
+            int64_t sec = timeout_us / 1000000;
+            int64_t microsec = timeout_us - (sec * 1000000);
             timeout_ts.tv_sec = sec;
             timeout_ts.tv_nsec = microsec * 1000;
         }
@@ -85,7 +83,7 @@ static int _DkObjectWaitOne (PAL_HANDLE handle, PAL_NUM timeout)
             return -PAL_ERROR_TRYAGAIN;
 
         int ret = INLINE_SYSCALL(ppoll, 5, &fds, nfds,
-                                 timeout != NO_TIMEOUT ? &timeout_ts : NULL,
+                                 timeout_us >= 0 ? &timeout_ts : NULL,
                                  NULL, 0);
 
         if (IS_ERR(ret))
@@ -117,14 +115,13 @@ static int _DkObjectWaitOne (PAL_HANDLE handle, PAL_NUM timeout)
     if (!ops || !ops->wait)
         return -PAL_ERROR_NOTSUPPORT;
 
-    return ops->wait(handle, timeout);
+    return ops->wait(handle, timeout_us);
 }
 
 /* _DkObjectsWaitAny for internal use. The function wait for any of the handle
    in the handle array. timeout can be set for the wait. */
-int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, PAL_NUM timeout,
-                       PAL_HANDLE * polled)
-{
+int _DkObjectsWaitAny(int count, PAL_HANDLE* handleArray, int64_t timeout_us,
+                      PAL_HANDLE* polled) {
     if (count <= 0)
         return 0;
 
@@ -134,7 +131,7 @@ int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, PAL_NUM timeout,
         if (!handleArray[0])
             return -PAL_ERROR_TRYAGAIN;
 
-        int rv = _DkObjectWaitOne(handleArray[0], timeout);
+        int rv = _DkObjectWaitOne(handleArray[0], timeout_us);
         if (rv == 0)
             *polled = handleArray[0];
         return rv;
@@ -207,15 +204,15 @@ int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, PAL_NUM timeout,
 
     struct timespec timeout_ts;
 
-    if (timeout != NO_TIMEOUT) {
-        long sec = (unsigned long) timeout / 1000000;
-        long microsec = (unsigned long) timeout - (sec * 1000000);
+    if (timeout_us >= 0) {
+        int64_t sec = timeout_us / 1000000;
+        int64_t microsec = timeout_us - (sec * 1000000);
         timeout_ts.tv_sec = sec;
         timeout_ts.tv_nsec = microsec * 1000;
     }
 
     ret = INLINE_SYSCALL(ppoll, 5, fds, nfds,
-                         timeout != NO_TIMEOUT ? &timeout_ts : NULL,
+                         timeout_us >= 0 ? &timeout_ts : NULL,
                          NULL, 0);
 
     if (IS_ERR(ret))

+ 3 - 3
Pal/src/host/Linux/pal_host.h

@@ -51,9 +51,9 @@ typedef struct mutex_handle {
 #define INIT_LOCK(lock) INIT_MUTEX_HANDLE(lock)
 
 /* Locking and unlocking of Mutexes */
-int _DkMutexLock (struct mutex_handle * mut);
-int _DkMutexLockTimeout (struct mutex_handle * mut, PAL_NUM timeout);
-int _DkMutexUnlock (struct mutex_handle * mut);
+int _DkMutexLock(struct mutex_handle* mut);
+int _DkMutexLockTimeout(struct mutex_handle* mut, int64_t timeout_us);
+int _DkMutexUnlock(struct mutex_handle* mut);
 
 typedef struct {
     PAL_HDR hdr;

+ 0 - 5
Pal/src/host/Linux/pal_linux.h

@@ -156,11 +156,6 @@ int handle_deserialize (PAL_HANDLE * handle, const void * data, int size);
 struct stat;
 bool stataccess (struct stat * stats, int acc);
 
-/* Locking and unlocking of Mutexes */
-int _DkMutexLock (struct mutex_handle * mut);
-int _DkMutexLockTimeout (struct mutex_handle * mut, PAL_NUM timeout);
-int _DkMutexUnlock (struct mutex_handle * mut);
-
 void init_child_process (PAL_HANDLE * parent, PAL_HANDLE * exec,
                          PAL_HANDLE * manifest);
 

+ 1 - 4
Pal/src/pal.h

@@ -487,12 +487,9 @@ DkEventClear (PAL_HANDLE eventHandle);
 
 #define NO_TIMEOUT ((PAL_NUM)-1)
 
-/* assuming timeout to be in microseconds
- * NO_TIMEOUT means no timeout, as the name implies.
- */
 /* Returns: NULL if the call times out, the ready handle on success */
 PAL_HANDLE
-DkObjectsWaitAny (PAL_NUM count, PAL_HANDLE * handleArray, PAL_NUM timeout);
+DkObjectsWaitAny (PAL_NUM count, PAL_HANDLE * handleArray, PAL_NUM timeout_us);
 
 /* Deprecate DkObjectReference */
 

+ 7 - 8
Pal/src/pal_internal.h

@@ -110,12 +110,12 @@ struct handle_ops {
     int (*attrsetbyhdl) (PAL_HANDLE handle, PAL_STREAM_ATTR * attr);
 
     /* 'wait' is used for synchronous wait.
-     * Time is in microseconds, NO_TIMEOUT means no timeout.
+     * The 'timeout_us' is in microseconds, NO_TIMEOUT means no timeout.
      * Returns 0 on success, a negative value on failure.
      * Timeout: -PAL_ERROR_TRYAGAIN
      * Positive return values are undefined.
      */
-    int (*wait) (PAL_HANDLE handle, PAL_NUM time);
+    int (*wait) (PAL_HANDLE handle, int64_t timeout_us);
 
     /* 'rename' is used to change name of a stream, or reset its share
        option */
@@ -306,8 +306,8 @@ noreturn void _DkProcessExit (int exitCode);
 
 /* DkMutex calls */
 int _DkMutexCreate (PAL_HANDLE * handle, int initialCount);
-int _DkMutexAcquire (PAL_HANDLE sem);
-int _DkMutexAcquireTimeout (PAL_HANDLE sem, PAL_NUM timeout);
+int _DkMutexAcquire(PAL_HANDLE sem);
+int _DkMutexAcquireTimeout(PAL_HANDLE sem, int64_t timeout_us);
 void _DkMutexRelease (PAL_HANDLE sem);
 int _DkMutexGetCurrentCount (PAL_HANDLE sem);
 
@@ -315,8 +315,8 @@ int _DkMutexGetCurrentCount (PAL_HANDLE sem);
 int _DkEventCreate (PAL_HANDLE * event, bool initialState,
                     bool isnotification);
 int _DkEventSet (PAL_HANDLE event, int wakeup);
-int _DkEventWaitTimeout (PAL_HANDLE event, PAL_NUM timeout);
-int _DkEventWait (PAL_HANDLE event);
+int _DkEventWaitTimeout(PAL_HANDLE event, int64_t timeout_us);
+int _DkEventWait(PAL_HANDLE event);
 int _DkEventClear (PAL_HANDLE event);
 
 /* DkVirtualMemory calls */
@@ -327,8 +327,7 @@ int _DkVirtualMemoryProtect (void * addr, uint64_t size, int prot);
 /* DkObject calls */
 int _DkObjectReference (PAL_HANDLE objectHandle);
 int _DkObjectClose (PAL_HANDLE objectHandle);
-int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, PAL_NUM timeout,
-                       PAL_HANDLE * polled);
+int _DkObjectsWaitAny(int count, PAL_HANDLE* handleArray, int64_t timeout_us, PAL_HANDLE* polled);
 
 /* DkException calls & structures */
 PAL_EVENT_HANDLER _DkGetExceptionHandler (PAL_NUM event_num);