futex: support FUTEX_CLOCK_REALTIME

This commit is contained in:
Tomoki Shirasawa
2016-01-14 16:18:49 +09:00
parent 2e31b8abd1
commit 9bafd166e3
2 changed files with 43 additions and 35 deletions

View File

@ -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

View File

@ -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,20 +3642,30 @@ SYSCALL_DECLARE(futex)
if (utime && (op == FUTEX_WAIT_BITSET || op == FUTEX_WAIT)) {
unsigned long nsec_timeout;
/* 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) {
if (!gettime_local_support ||
!(flags & FUTEX_CLOCK_REALTIME)) {
struct syscall_request request IHK_DMA_ALIGN;
struct timeval tv_now;
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)) {
(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);
@ -3662,17 +3673,14 @@ SYSCALL_DECLARE(futex)
return -EFAULT;
}
ats.tv_sec = tv_now.tv_sec;
ats.tv_nsec = tv_now.tv_usec * 1000;
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);
}
/* 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) {
nsec_timeout = (utime->tv_sec * NS_PER_SEC + utime->tv_nsec) -
(ats.tv_sec * NS_PER_SEC + ats.tv_nsec);
}