aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linux/linux_futex.c
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2010-10-06 18:51:22 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2010-10-06 18:51:22 +0000
commit2a9479393a63e8060e2db6c4c1a634015ecb7543 (patch)
tree44b06cfdd386975f08473cb60717d19d924cbd97 /sys/compat/linux/linux_futex.c
parent584d21f69ed958033f86746a184ccab1937e1c49 (diff)
downloadsrc-2a9479393a63e8060e2db6c4c1a634015ecb7543.tar.gz
src-2a9479393a63e8060e2db6c4c1a634015ecb7543.zip
Simplify timeout check in futex_wait() using itimerfix() and return error
if the given timeout is invalid. Consistently use int type for timeout and correct a format string in futex_sleep().
Notes
Notes: svn path=/head/; revision=213490
Diffstat (limited to 'sys/compat/linux/linux_futex.c')
-rw-r--r--sys/compat/linux/linux_futex.c32
1 files changed, 10 insertions, 22 deletions
diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c
index 69bc70ca088c..01af020face6 100644
--- a/sys/compat/linux/linux_futex.c
+++ b/sys/compat/linux/linux_futex.c
@@ -238,12 +238,12 @@ futex_get(uint32_t *uaddr, struct waiting_proc **wp, struct futex **f,
}
static int
-futex_sleep(struct futex *f, struct waiting_proc *wp, unsigned long timeout)
+futex_sleep(struct futex *f, struct waiting_proc *wp, int timeout)
{
int error;
FUTEX_ASSERT_LOCKED(f);
- LINUX_CTR4(sys_futex, "futex_sleep enter uaddr %p wp %p timo %ld ref %d",
+ LINUX_CTR4(sys_futex, "futex_sleep enter uaddr %p wp %p timo %d ref %d",
f->f_uaddr, wp, timeout, f->f_refcount);
error = sx_sleep(wp, &f->f_lck, PCATCH, "futex", timeout);
if (wp->wp_flags & FUTEX_WP_REQUEUED) {
@@ -327,8 +327,8 @@ futex_requeue(struct futex *f, int n, struct futex *f2, int n2)
static int
futex_wait(struct futex *f, struct waiting_proc *wp, struct l_timespec *ts)
{
- struct l_timespec timeout = {0, 0};
- struct timeval tv = {0, 0};
+ struct l_timespec timeout;
+ struct timeval tv;
int timeout_hz;
int error;
@@ -336,26 +336,14 @@ futex_wait(struct futex *f, struct waiting_proc *wp, struct l_timespec *ts)
error = copyin(ts, &timeout, sizeof(timeout));
if (error)
return (error);
- }
-
- tv.tv_usec = timeout.tv_sec * 1000000 + timeout.tv_nsec / 1000;
- timeout_hz = tvtohz(&tv);
-
- if (timeout.tv_sec == 0 && timeout.tv_nsec == 0)
+ TIMESPEC_TO_TIMEVAL(&tv, &timeout);
+ error = itimerfix(&tv);
+ if (error)
+ return (error);
+ timeout_hz = tvtohz(&tv);
+ } else
timeout_hz = 0;
- /*
- * If the user process requests a non null timeout,
- * make sure we do not turn it into an infinite
- * timeout because timeout_hz gets null.
- *
- * We use a minimal timeout of 1/hz. Maybe it would
- * make sense to just return ETIMEDOUT without sleeping.
- */
- if (((timeout.tv_sec != 0) || (timeout.tv_nsec != 0)) &&
- (timeout_hz == 0))
- timeout_hz = 1;
-
error = futex_sleep(f, wp, timeout_hz);
if (error == EWOULDBLOCK)
error = ETIMEDOUT;