From owner-svn-src-all@FreeBSD.ORG Wed Mar 2 06:18:22 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 72521106566B; Wed, 2 Mar 2011 06:18:22 +0000 (UTC) (envelope-from dchagin@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 280B88FC13; Wed, 2 Mar 2011 06:18:22 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p226IMLw083049; Wed, 2 Mar 2011 06:18:22 GMT (envelope-from dchagin@svn.freebsd.org) Received: (from dchagin@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p226IMkA083046; Wed, 2 Mar 2011 06:18:22 GMT (envelope-from dchagin@svn.freebsd.org) Message-Id: <201103020618.p226IMkA083046@svn.freebsd.org> From: Dmitry Chagin Date: Wed, 2 Mar 2011 06:18:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r219167 - stable/8/sys/compat/linux X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Mar 2011 06:18:22 -0000 Author: dchagin Date: Wed Mar 2 06:18:21 2011 New Revision: 219167 URL: http://svn.freebsd.org/changeset/base/219167 Log: MFC r218117: Implement a futex BITSET op. Modified: stable/8/sys/compat/linux/linux_futex.c stable/8/sys/compat/linux/linux_futex.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/compat/linux/linux_futex.c ============================================================================== --- stable/8/sys/compat/linux/linux_futex.c Wed Mar 2 06:13:03 2011 (r219166) +++ stable/8/sys/compat/linux/linux_futex.c Wed Mar 2 06:18:21 2011 (r219167) @@ -79,6 +79,7 @@ struct futex { struct sx f_lck; uint32_t *f_uaddr; uint32_t f_refcount; + uint32_t f_bitset; LIST_ENTRY(futex) f_list; TAILQ_HEAD(lf_waiting_proc, waiting_proc) f_waiting_proc; }; @@ -264,15 +265,25 @@ futex_sleep(struct futex *f, struct wait } static int -futex_wake(struct futex *f, int n) +futex_wake(struct futex *f, int n, uint32_t bitset) { struct waiting_proc *wp, *wpt; int count = 0; + if (bitset == 0) + return (EINVAL); + FUTEX_ASSERT_LOCKED(f); TAILQ_FOREACH_SAFE(wp, &f->f_waiting_proc, wp_list, wpt) { LINUX_CTR3(sys_futex, "futex_wake uaddr %p wp %p ref %d", f->f_uaddr, wp, f->f_refcount); + /* + * Unless we find a matching bit in + * the bitset, continue searching. + */ + if (!(wp->wp_futex->f_bitset & bitset)) + continue; + wp->wp_flags |= FUTEX_WP_REMOVED; TAILQ_REMOVE(&f->f_waiting_proc, wp, wp_list); wakeup_one(wp); @@ -325,13 +336,18 @@ futex_requeue(struct futex *f, int n, st } static int -futex_wait(struct futex *f, struct waiting_proc *wp, struct l_timespec *ts) +futex_wait(struct futex *f, struct waiting_proc *wp, struct l_timespec *ts, + uint32_t bitset) { struct l_timespec timeout = {0, 0}; struct timeval tv = {0, 0}; int timeout_hz; int error; + if (bitset == 0) + return (EINVAL); + f->f_bitset = bitset; + if (ts != NULL) { error = copyin(ts, &timeout, sizeof(timeout)); if (error) @@ -457,13 +473,18 @@ linux_sys_futex(struct thread *td, struc switch (args->op) { case LINUX_FUTEX_WAIT: + args->val3 = FUTEX_BITSET_MATCH_ANY; + /* FALLTHROUGH */ + + case LINUX_FUTEX_WAIT_BITSET: - LINUX_CTR2(sys_futex, "WAIT val %d uaddr %p", - args->val, args->uaddr); + LINUX_CTR3(sys_futex, "WAIT uaddr %p val %d val3 %d", + args->uaddr, args->val, args->val3); #ifdef DEBUG if (ldebug(sys_futex)) - printf(ARGS(sys_futex, "futex_wait val %d uaddr %p"), - args->val, args->uaddr); + printf(ARGS(sys_futex, + "futex_wait uaddr %p val %d val3 %d"), + args->uaddr, args->val, args->val3); #endif error = futex_get(args->uaddr, &wp, &f, FUTEX_CREATE_WP); if (error) @@ -476,19 +497,24 @@ linux_sys_futex(struct thread *td, struc return (error); } if (val != args->val) { - LINUX_CTR3(sys_futex, "WAIT uaddr %p val %d != uval %d", - args->uaddr, args->val, val); + LINUX_CTR4(sys_futex, + "WAIT uaddr %p val %d != uval %d val3 %d", + args->uaddr, args->val, val, args->val3); futex_put(f, wp); return (EWOULDBLOCK); } - error = futex_wait(f, wp, args->timeout); + error = futex_wait(f, wp, args->timeout, args->val3); break; case LINUX_FUTEX_WAKE: + args->val3 = FUTEX_BITSET_MATCH_ANY; + /* FALLTHROUGH */ + + case LINUX_FUTEX_WAKE_BITSET: - LINUX_CTR2(sys_futex, "WAKE val %d uaddr %p", - args->val, args->uaddr); + LINUX_CTR3(sys_futex, "WAKE uaddr %p val % d val3 %d", + args->uaddr, args->val, args->val3); /* * XXX: Linux is able to cope with different addresses @@ -497,8 +523,8 @@ linux_sys_futex(struct thread *td, struc */ #ifdef DEBUG if (ldebug(sys_futex)) - printf(ARGS(sys_futex, "futex_wake val %d uaddr %p"), - args->val, args->uaddr); + printf(ARGS(sys_futex, "futex_wake uaddr %p val %d val3 %d"), + args->uaddr, args->val, args->val3); #endif error = futex_get(args->uaddr, NULL, &f, FUTEX_DONTCREATE); if (error) @@ -507,7 +533,7 @@ linux_sys_futex(struct thread *td, struc td->td_retval[0] = 0; return (error); } - td->td_retval[0] = futex_wake(f, args->val); + td->td_retval[0] = futex_wake(f, args->val, args->val3); futex_put(f, NULL); break; @@ -615,16 +641,16 @@ linux_sys_futex(struct thread *td, struc return (EFAULT); } - ret = futex_wake(f, args->val); + ret = futex_wake(f, args->val, args->val3); if (op_ret > 0) { op_ret = 0; nrwake = (int)(unsigned long)args->timeout; if (f2 != NULL) - op_ret += futex_wake(f2, nrwake); + op_ret += futex_wake(f2, nrwake, args->val3); else - op_ret += futex_wake(f, nrwake); + op_ret += futex_wake(f, nrwake, args->val3); ret += op_ret; } @@ -672,13 +698,6 @@ linux_sys_futex(struct thread *td, struc } return (EINVAL); - case LINUX_FUTEX_WAIT_BITSET: - /* not yet implemented */ - linux_msg(td, - "linux_sys_futex: " - "op FUTEX_WAIT_BITSET not implemented\n"); - return (ENOSYS); - case LINUX_FUTEX_WAIT_REQUEUE_PI: /* not yet implemented */ linux_msg(td, @@ -787,7 +806,7 @@ retry: if (error) return (error); if (f != NULL) { - futex_wake(f, 1); + futex_wake(f, 1, FUTEX_BITSET_MATCH_ANY); futex_put(f, NULL); } } Modified: stable/8/sys/compat/linux/linux_futex.h ============================================================================== --- stable/8/sys/compat/linux/linux_futex.h Wed Mar 2 06:13:03 2011 (r219166) +++ stable/8/sys/compat/linux/linux_futex.h Wed Mar 2 06:18:21 2011 (r219167) @@ -49,6 +49,7 @@ extern struct mtx futex_mtx; #define LINUX_FUTEX_UNLOCK_PI 7 #define LINUX_FUTEX_TRYLOCK_PI 8 #define LINUX_FUTEX_WAIT_BITSET 9 +#define LINUX_FUTEX_WAKE_BITSET 10 #define LINUX_FUTEX_WAIT_REQUEUE_PI 11 #define LINUX_FUTEX_PRIVATE_FLAG 128 @@ -72,6 +73,7 @@ extern struct mtx futex_mtx; #define FUTEX_WAITERS 0x80000000 #define FUTEX_OWNER_DIED 0x40000000 #define FUTEX_TID_MASK 0x3fffffff +#define FUTEX_BITSET_MATCH_ANY 0xffffffff void release_futexes(struct proc *);