From owner-svn-src-user@FreeBSD.ORG Wed Mar 21 07:07:00 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id DF34D106566C; Wed, 21 Mar 2012 07:07:00 +0000 (UTC) (envelope-from davidxu@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CACD48FC0A; Wed, 21 Mar 2012 07:07:00 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q2L770kb058893; Wed, 21 Mar 2012 07:07:00 GMT (envelope-from davidxu@svn.freebsd.org) Received: (from davidxu@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q2L770Zk058890; Wed, 21 Mar 2012 07:07:00 GMT (envelope-from davidxu@svn.freebsd.org) Message-Id: <201203210707.q2L770Zk058890@svn.freebsd.org> From: David Xu Date: Wed, 21 Mar 2012 07:07:00 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r233260 - in user/davidxu/pth_objdestroy/sys: kern sys X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Mar 2012 07:07:01 -0000 Author: davidxu Date: Wed Mar 21 07:07:00 2012 New Revision: 233260 URL: http://svn.freebsd.org/changeset/base/233260 Log: Change semaphore to merge waiter bit and count in same word, this allows us gracefully to destroy semaphore, also remove rmb() ambiguity. Modified: user/davidxu/pth_objdestroy/sys/kern/kern_umtx.c user/davidxu/pth_objdestroy/sys/sys/umtx.h Modified: user/davidxu/pth_objdestroy/sys/kern/kern_umtx.c ============================================================================== --- user/davidxu/pth_objdestroy/sys/kern/kern_umtx.c Wed Mar 21 07:05:29 2012 (r233259) +++ user/davidxu/pth_objdestroy/sys/kern/kern_umtx.c Wed Mar 21 07:07:00 2012 (r233260) @@ -2870,16 +2870,38 @@ do_sem_wait(struct thread *td, struct _u umtxq_insert(uq); umtxq_unlock(&uq->uq_key); - casuword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters), 0, 1); - rmb(); - count = fuword32(__DEVOLATILE(uint32_t *, &sem->_count)); - if (count != 0) { - umtxq_lock(&uq->uq_key); - umtxq_unbusy(&uq->uq_key); - umtxq_remove(uq); - umtxq_unlock(&uq->uq_key); - umtx_key_release(&uq->uq_key); - return (0); + if (__predict_false((flags & SEM_VER2) == 0)) { + casuword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters), 0, 1); + rmb(); + count = fuword32(__DEVOLATILE(uint32_t *, &sem->_count)); + if (count != 0) { + umtxq_lock(&uq->uq_key); + umtxq_unbusy(&uq->uq_key); + umtxq_remove(uq); + umtxq_unlock(&uq->uq_key); + umtx_key_release(&uq->uq_key); + return (0); + } + } else { + count = fuword32(__DEVOLATILE(uint32_t *, &sem->_count)); + for (;;) { + if ((count & ~SEM_WAITERS) != 0) { + umtxq_lock(&uq->uq_key); + umtxq_unbusy(&uq->uq_key); + umtxq_remove(uq); + umtxq_unlock(&uq->uq_key); + umtx_key_release(&uq->uq_key); + return (0); + } + if ((count & SEM_WAITERS) == 0) { + int old = casuword32(__DEVOLATILE(uint32_t *, + &sem->_count), count, count | SEM_WAITERS); + if (old == count) + break; + count = old; + } else + break; + } } umtxq_lock(&uq->uq_key); @@ -2932,22 +2954,42 @@ static int do_sem_wake(struct thread *td, struct _usem *sem) { struct umtx_key key; - int error, cnt, nwake; - uint32_t flags; + int error, nwait; + uint32_t flags, count; flags = fuword32(&sem->_flags); if ((error = umtx_key_get(sem, TYPE_SEM, GET_SHARE(flags), &key)) != 0) return (error); umtxq_lock(&key); umtxq_busy(&key); - cnt = umtxq_count(&key); - nwake = umtxq_signal(&key, 1); - if (cnt <= nwake) { - umtxq_unlock(&key); - error = suword32( - __DEVOLATILE(uint32_t *, &sem->_has_waiters), 0); - umtxq_lock(&key); + nwait = umtxq_count(&key); + umtxq_unlock(&key); + if ((flags & SEM_VER2) != 0) { + error = 0; + count = fuword32(__DEVOLATILE(uint32_t *, &sem->_count)); + for (;;) { + if (__predict_false((count & ~SEM_WAITERS) == __INT_MAX)) { + umtxq_lock(&key); + umtxq_unbusy(&key); + umtxq_unlock(&key); + return (ERANGE); + } + int new = count + 1; + if (nwait <= 1) + new &= ~SEM_WAITERS; + int old = casuword32(__DEVOLATILE(uint32_t *, + &sem->_count), count, new); + if (old == count) + break; + count = old; + } + } else { + if (nwait <= 1) + error = suword32( + __DEVOLATILE(uint32_t *, &sem->_has_waiters), 0); } + umtxq_lock(&key); + umtxq_signal(&key, 1); umtxq_unbusy(&key); umtxq_unlock(&key); umtx_key_release(&key); Modified: user/davidxu/pth_objdestroy/sys/sys/umtx.h ============================================================================== --- user/davidxu/pth_objdestroy/sys/sys/umtx.h Wed Mar 21 07:05:29 2012 (r233259) +++ user/davidxu/pth_objdestroy/sys/sys/umtx.h Wed Mar 21 07:07:00 2012 (r233260) @@ -55,7 +55,9 @@ #define URWLOCK_READER_COUNT(c) ((c) & URWLOCK_MAX_READERS) /* _usem flags */ -#define SEM_NAMED 0x0002 +#define SEM_NAMED 0x00000002 +#define SEM_VER2 0x00000004 +#define SEM_WAITERS 0x80000000 /* op code for _umtx_op */ #define UMTX_OP_LOCK 0