From 9bafd166e3d4d238339e78613cbb26c8665bd052 Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Thu, 14 Jan 2016 16:18:49 +0900 Subject: [PATCH] futex: support FUTEX_CLOCK_REALTIME --- executer/user/mcexec.c | 10 +++---- kernel/syscall.c | 68 +++++++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index a03a04ad..b4b001b1 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -1714,7 +1714,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) char *fn; int sig; int term; - struct timeval tv; + struct timespec tv; char pathbuf[PATH_MAX]; char tmpbuf[PATH_MAX]; @@ -1753,13 +1753,13 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock) break; case __NR_futex: - ret = gettimeofday(&tv, NULL); + ret = clock_gettime(w.sr.args[1], &tv); SET_ERR(ret); - __dprintf("gettimeofday=%016ld,%09ld\n", + __dprintf("clock_gettime=%016ld,%09ld\n", tv.tv_sec, - tv.tv_usec); + tv.tv_nsec); do_syscall_return(fd, cpu, ret, 1, (unsigned long)&tv, - w.sr.args[0], sizeof(struct timeval)); + w.sr.args[0], sizeof(struct timespec)); break; case __NR_kill: // interrupt syscall diff --git a/kernel/syscall.c b/kernel/syscall.c index a61ed68a..be22c167 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -2084,7 +2084,7 @@ getcred(int *_buf) struct syscall_request request IHK_DMA_ALIGN; unsigned long phys; - if(((unsigned long)_buf) & ((unsigned long)(_buf + 8)) & ~4095) + if((((unsigned long)_buf) ^ ((unsigned long)(_buf + 8))) & ~4095) buf = _buf + 8; else buf = _buf; @@ -3621,6 +3621,7 @@ SYSCALL_DECLARE(futex) struct timespec *utime = (struct timespec*)ihk_mc_syscall_arg3(ctx); uint32_t *uaddr2 = (uint32_t *)ihk_mc_syscall_arg4(ctx); uint32_t val3 = (uint32_t)ihk_mc_syscall_arg5(ctx); + int flags = op; /* Cross-address space futex? */ if (op & FUTEX_PRIVATE_FLAG) { @@ -3629,7 +3630,7 @@ SYSCALL_DECLARE(futex) op = (op & FUTEX_CMD_MASK); dkprintf("futex op=[%x, %s],uaddr=%lx, val=%x, utime=%lx, uaddr2=%lx, val3=%x, []=%x, shared: %d\n", - op, + flags, (op == FUTEX_WAIT) ? "FUTEX_WAIT" : (op == FUTEX_WAIT_BITSET) ? "FUTEX_WAIT_BITSET" : (op == FUTEX_WAKE) ? "FUTEX_WAKE" : @@ -3641,38 +3642,45 @@ SYSCALL_DECLARE(futex) if (utime && (op == FUTEX_WAIT_BITSET || op == FUTEX_WAIT)) { unsigned long nsec_timeout; - struct timespec ats; - - if (!gettime_local_support) { - struct syscall_request request IHK_DMA_ALIGN; - struct timeval tv_now; - request.number = n; - unsigned long __phys; - - if (ihk_mc_pt_virt_to_phys(cpu_local_var(current)->vm->address_space->page_table, - (void *)&tv_now, &__phys)) { - return -EFAULT; - } - - request.args[0] = __phys; - - int r = do_syscall(&request, ihk_mc_get_processor_id(), 0); - - if (r < 0) { - return -EFAULT; - } - - ats.tv_sec = tv_now.tv_sec; - ats.tv_nsec = tv_now.tv_usec * 1000; - } - /* Compute timeout based on TSC/nanosec ratio */ - else { - calculate_time_from_tsc(&ats); - } /* As per the Linux implementation FUTEX_WAIT specifies the duration of * the timeout, while FUTEX_WAIT_BITSET specifies the absolute timestamp */ if (op == FUTEX_WAIT_BITSET) { + struct timespec ats; + + if (!gettime_local_support || + !(flags & FUTEX_CLOCK_REALTIME)) { + struct syscall_request request IHK_DMA_ALIGN; + struct timespec tv[2]; + struct timespec *tv_now = tv; + request.number = n; + unsigned long __phys; + + if((((unsigned long)tv) ^ ((unsigned long)(tv + 1))) & ~4095) + tv_now = tv + 1; + if (ihk_mc_pt_virt_to_phys(cpu_local_var(current)->vm->address_space->page_table, + (void *)tv_now, &__phys)) { + return -EFAULT; + } + + request.args[0] = __phys; + request.args[1] = (flags & FUTEX_CLOCK_REALTIME)? + CLOCK_REALTIME: CLOCK_MONOTONIC; + + int r = do_syscall(&request, ihk_mc_get_processor_id(), 0); + + if (r < 0) { + return -EFAULT; + } + + ats.tv_sec = tv_now->tv_sec; + ats.tv_nsec = tv_now->tv_nsec; + } + /* Compute timeout based on TSC/nanosec ratio */ + else { + calculate_time_from_tsc(&ats); + } + nsec_timeout = (utime->tv_sec * NS_PER_SEC + utime->tv_nsec) - (ats.tv_sec * NS_PER_SEC + ats.tv_nsec); }