futex: support FUTEX_CLOCK_REALTIME
This commit is contained in:
@ -1714,7 +1714,7 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
|||||||
char *fn;
|
char *fn;
|
||||||
int sig;
|
int sig;
|
||||||
int term;
|
int term;
|
||||||
struct timeval tv;
|
struct timespec tv;
|
||||||
char pathbuf[PATH_MAX];
|
char pathbuf[PATH_MAX];
|
||||||
char tmpbuf[PATH_MAX];
|
char tmpbuf[PATH_MAX];
|
||||||
|
|
||||||
@ -1753,13 +1753,13 @@ int main_loop(int fd, int cpu, pthread_mutex_t *lock)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case __NR_futex:
|
case __NR_futex:
|
||||||
ret = gettimeofday(&tv, NULL);
|
ret = clock_gettime(w.sr.args[1], &tv);
|
||||||
SET_ERR(ret);
|
SET_ERR(ret);
|
||||||
__dprintf("gettimeofday=%016ld,%09ld\n",
|
__dprintf("clock_gettime=%016ld,%09ld\n",
|
||||||
tv.tv_sec,
|
tv.tv_sec,
|
||||||
tv.tv_usec);
|
tv.tv_nsec);
|
||||||
do_syscall_return(fd, cpu, ret, 1, (unsigned long)&tv,
|
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;
|
break;
|
||||||
|
|
||||||
case __NR_kill: // interrupt syscall
|
case __NR_kill: // interrupt syscall
|
||||||
|
|||||||
@ -2084,7 +2084,7 @@ getcred(int *_buf)
|
|||||||
struct syscall_request request IHK_DMA_ALIGN;
|
struct syscall_request request IHK_DMA_ALIGN;
|
||||||
unsigned long phys;
|
unsigned long phys;
|
||||||
|
|
||||||
if(((unsigned long)_buf) & ((unsigned long)(_buf + 8)) & ~4095)
|
if((((unsigned long)_buf) ^ ((unsigned long)(_buf + 8))) & ~4095)
|
||||||
buf = _buf + 8;
|
buf = _buf + 8;
|
||||||
else
|
else
|
||||||
buf = _buf;
|
buf = _buf;
|
||||||
@ -3621,6 +3621,7 @@ SYSCALL_DECLARE(futex)
|
|||||||
struct timespec *utime = (struct timespec*)ihk_mc_syscall_arg3(ctx);
|
struct timespec *utime = (struct timespec*)ihk_mc_syscall_arg3(ctx);
|
||||||
uint32_t *uaddr2 = (uint32_t *)ihk_mc_syscall_arg4(ctx);
|
uint32_t *uaddr2 = (uint32_t *)ihk_mc_syscall_arg4(ctx);
|
||||||
uint32_t val3 = (uint32_t)ihk_mc_syscall_arg5(ctx);
|
uint32_t val3 = (uint32_t)ihk_mc_syscall_arg5(ctx);
|
||||||
|
int flags = op;
|
||||||
|
|
||||||
/* Cross-address space futex? */
|
/* Cross-address space futex? */
|
||||||
if (op & FUTEX_PRIVATE_FLAG) {
|
if (op & FUTEX_PRIVATE_FLAG) {
|
||||||
@ -3629,7 +3630,7 @@ SYSCALL_DECLARE(futex)
|
|||||||
op = (op & FUTEX_CMD_MASK);
|
op = (op & FUTEX_CMD_MASK);
|
||||||
|
|
||||||
dkprintf("futex op=[%x, %s],uaddr=%lx, val=%x, utime=%lx, uaddr2=%lx, val3=%x, []=%x, shared: %d\n",
|
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) ? "FUTEX_WAIT" :
|
||||||
(op == FUTEX_WAIT_BITSET) ? "FUTEX_WAIT_BITSET" :
|
(op == FUTEX_WAIT_BITSET) ? "FUTEX_WAIT_BITSET" :
|
||||||
(op == FUTEX_WAKE) ? "FUTEX_WAKE" :
|
(op == FUTEX_WAKE) ? "FUTEX_WAKE" :
|
||||||
@ -3641,20 +3642,30 @@ SYSCALL_DECLARE(futex)
|
|||||||
|
|
||||||
if (utime && (op == FUTEX_WAIT_BITSET || op == FUTEX_WAIT)) {
|
if (utime && (op == FUTEX_WAIT_BITSET || op == FUTEX_WAIT)) {
|
||||||
unsigned long nsec_timeout;
|
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;
|
struct timespec ats;
|
||||||
|
|
||||||
if (!gettime_local_support) {
|
if (!gettime_local_support ||
|
||||||
|
!(flags & FUTEX_CLOCK_REALTIME)) {
|
||||||
struct syscall_request request IHK_DMA_ALIGN;
|
struct syscall_request request IHK_DMA_ALIGN;
|
||||||
struct timeval tv_now;
|
struct timespec tv[2];
|
||||||
|
struct timespec *tv_now = tv;
|
||||||
request.number = n;
|
request.number = n;
|
||||||
unsigned long __phys;
|
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,
|
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;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
request.args[0] = __phys;
|
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);
|
int r = do_syscall(&request, ihk_mc_get_processor_id(), 0);
|
||||||
|
|
||||||
@ -3662,17 +3673,14 @@ SYSCALL_DECLARE(futex)
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ats.tv_sec = tv_now.tv_sec;
|
ats.tv_sec = tv_now->tv_sec;
|
||||||
ats.tv_nsec = tv_now.tv_usec * 1000;
|
ats.tv_nsec = tv_now->tv_nsec;
|
||||||
}
|
}
|
||||||
/* Compute timeout based on TSC/nanosec ratio */
|
/* Compute timeout based on TSC/nanosec ratio */
|
||||||
else {
|
else {
|
||||||
calculate_time_from_tsc(&ats);
|
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) -
|
nsec_timeout = (utime->tv_sec * NS_PER_SEC + utime->tv_nsec) -
|
||||||
(ats.tv_sec * NS_PER_SEC + ats.tv_nsec);
|
(ats.tv_sec * NS_PER_SEC + ats.tv_nsec);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user