diff --git a/LibOS/shim/src/sys/shim_sleep.c b/LibOS/shim/src/sys/shim_sleep.c index e582051f..920be101 100644 --- a/LibOS/shim/src/sys/shim_sleep.c +++ b/LibOS/shim/src/sys/shim_sleep.c @@ -34,18 +34,11 @@ #include -#define SHIM_DEFAULT_SLEEP 1000 - int shim_do_pause (void) { - while (1) { - unsigned long ret = DkThreadDelayExecution(SHIM_DEFAULT_SLEEP); - - if (!ret) - break; - } - - return 0; + /* ~0ULL micro sec ~= 805675 years */ + DkThreadDelayExecution(~((PAL_NUM)0)); + return -EINTR; } int shim_do_nanosleep (const struct __kernel_timespec * rqtp, diff --git a/LibOS/shim/test/native/pause.c b/LibOS/shim/test/native/pause.c new file mode 100644 index 00000000..145ab63f --- /dev/null +++ b/LibOS/shim/test/native/pause.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include + +void handler(int signal) +{ + printf("hello world\n"); +} + +int main(int argc, char ** argv) +{ + if (signal(SIGALRM, &handler) < 0) + return EXIT_FAILURE; + + if (alarm(1) < 0) + return EXIT_FAILURE; + + int ret = pause(); + assert(ret == -1); + assert(errno == EINTR); + + printf("good bye\n"); + return 0; +} diff --git a/Pal/src/host/FreeBSD/db_threading.c b/Pal/src/host/FreeBSD/db_threading.c index 77a62e4b..71da3a2c 100644 --- a/Pal/src/host/FreeBSD/db_threading.c +++ b/Pal/src/host/FreeBSD/db_threading.c @@ -85,11 +85,15 @@ int _DkThreadDelayExecution (unsigned long * duration) struct timespec sleeptime; struct timespec remainingtime; - long sec = (unsigned long) *duration / 1000000; - long microsec = (unsigned long) *duration - (sec * 1000000); - - sleeptime.tv_sec = sec; - sleeptime.tv_nsec = microsec * 1000; +#define VERY_LONG_TIME_IN_US (1000000L * 60 * 60 * 24 * 365 * 128) + if (*duration > VERY_LONG_TIME_IN_US) { + /* avoid overflow with time_t */ + sleeptime.tv_sec = VERY_LONG_TIME_IN_US / 1000000; + sleeptime.tv_nsec = 0; + } else { + sleeptime.tv_sec = *duration / 1000000; + sleeptime.tv_nsec = (*duration - sleeptime.tv_sec * 1000000) * 1000; + } int ret = INLINE_SYSCALL(nanosleep, 2, &sleeptime, &remainingtime); diff --git a/Pal/src/host/Linux-SGX/sgx_enclave.c b/Pal/src/host/Linux-SGX/sgx_enclave.c index f0867d2f..e0db25ce 100644 --- a/Pal/src/host/Linux-SGX/sgx_enclave.c +++ b/Pal/src/host/Linux-SGX/sgx_enclave.c @@ -593,11 +593,20 @@ static int sgx_ocall_sleep(void * pms) return 0; } struct timespec req, rem; - req.tv_sec = ms->ms_microsec / 1000000; - req.tv_nsec = (ms->ms_microsec - req.tv_sec * 1000000) * 1000; + unsigned long microsec = ms->ms_microsec; +#define VERY_LONG_TIME_IN_US (1000000L * 60 * 60 * 24 * 365 * 128) + if (ms->ms_microsec > VERY_LONG_TIME_IN_US) { + /* avoid overflow with time_t */ + req.tv_sec = VERY_LONG_TIME_IN_US / 1000000; + req.tv_nsec = 0; + } else { + req.tv_sec = ms->ms_microsec / 1000000; + req.tv_nsec = (microsec - req.tv_sec * 1000000) * 1000; + } + ret = INLINE_SYSCALL(nanosleep, 2, &req, &rem); if (IS_ERR(ret) && ERRNO(ret) == EINTR) - ms->ms_microsec = rem.tv_sec * 1000000 + rem.tv_nsec / 1000; + ms->ms_microsec = rem.tv_sec * 1000000UL + rem.tv_nsec / 1000UL; return ret; } diff --git a/Pal/src/host/Linux/db_threading.c b/Pal/src/host/Linux/db_threading.c index 3958c6dc..f25aac1c 100644 --- a/Pal/src/host/Linux/db_threading.c +++ b/Pal/src/host/Linux/db_threading.c @@ -139,11 +139,15 @@ int _DkThreadDelayExecution (unsigned long * duration) struct timespec sleeptime; struct timespec remainingtime; - long sec = (unsigned long) *duration / 1000000; - long microsec = (unsigned long) *duration - (sec * 1000000); - - sleeptime.tv_sec = sec; - sleeptime.tv_nsec = microsec * 1000; +#define VERY_LONG_TIME_IN_US (1000000L * 60 * 60 * 24 * 365 * 128) + if (*duration > VERY_LONG_TIME_IN_US) { + /* avoid overflow with time_t */ + sleeptime.tv_sec = VERY_LONG_TIME_IN_US / 1000000; + sleeptime.tv_nsec = 0; + } else { + sleeptime.tv_sec = *duration / 1000000; + sleeptime.tv_nsec = (*duration - sleeptime.tv_sec * 1000000) * 1000; + } int ret = INLINE_SYSCALL(nanosleep, 2, &sleeptime, &remainingtime);