mirror of
https://github.com/clearlinux/graphene.git
synced 2026-10-03 15:39:36 +00:00
[LibOS] Emulate pause() by sleeping for a very long time
Before, pause() was emulated by sleeping for 1s in a loop until signal interrupted it. If signal arrived in-between these invocations then pause() could never return. Also, pause() incorrectly returned 0 instead of -1 and errno=EINTR. This patch emulates pause() by sleeping for a very long time (years). Also, it correctly returns EINTR.
This commit is contained in:
committed by
Dmitrii Kuvaiskii
parent
382a1ec394
commit
f72cd48ee5
@@ -34,18 +34,11 @@
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#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,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user