Date: Wed, 9 Jul 2003 19:52:22 -0400 From: Mike Makonnen <mtm@identd.net> To: Kai Mosebach <kai.mosebach@freshx.de> Cc: freebsd-threads@freebsd.org Subject: Re: LinuxThreads replacement Message-ID: <20030709235221.GA10504@kokeb.ambesa.net> In-Reply-To: <001b01c3463a$0f907a00$0100a8c0@alpha> References: <Pine.GSO.4.10.10307091234350.3409-100000@pcnet5.pcnet.com> <001b01c3463a$0f907a00$0100a8c0@alpha>
next in thread | previous in thread | raw e-mail | index | archive | help
--oyUTqETQ0mS9luUI Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Jul 09, 2003 at 06:49:25PM +0200, Kai Mosebach wrote: > > Would you more likely use libthr or libkse, > as kse is not complete yet, isnt it ? > Either one should work just as well. There is currently a race in the kernel code for libthr that can lead to deadlocks. I have a fix for this and I am waiting for jeff to review it before I commit it. In the mean time you can get the patch here: http://people.freebsd.org/~mtm/patches/libthr.kern.diff (also attached) Cheers. -- Mike Makonnen | GPG-KEY: http://www.identd.net/~mtm/mtm.asc mtm@identd.net | D228 1A6F C64E 120A A1C9 A3AA DAE1 E2AF DBCC 68B9 mtm@FreeBSD.Org| FreeBSD - Unleash the Daemon! --oyUTqETQ0mS9luUI Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="umtx3.diff" Index: sys/kern/kern_umtx.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_umtx.c,v retrieving revision 1.7 diff -u -r1.7 kern_umtx.c --- sys/kern/kern_umtx.c 4 Jul 2003 23:28:42 -0000 1.7 +++ sys/kern/kern_umtx.c 5 Jul 2003 05:53:02 -0000 @@ -181,7 +181,7 @@ return (EFAULT); if (owner == UMTX_CONTESTED) - return (0); + goto out; /* If this failed the lock has changed, restart. */ continue; @@ -190,7 +190,6 @@ UMTX_LOCK(); uq = umtx_insert(td, umtx); - UMTX_UNLOCK(); /* * Set the contested bit so that a release in user space @@ -203,7 +202,6 @@ /* The address was invalid. */ if (old == -1) { - UMTX_LOCK(); umtx_remove(uq, td); UMTX_UNLOCK(); return (EFAULT); @@ -213,7 +211,6 @@ * We set the contested bit, sleep. Otherwise the lock changed * and we need to retry. */ - UMTX_LOCK(); if (old == owner) error = msleep(td, &umtx_lock, td->td_priority | PCATCH, "umtx", 0); @@ -230,8 +227,37 @@ if (error) return (error); } - - return (0); +out: + /* + * We reach here only if we just acquired a contested umtx. + * + * If there are no other threads on this umtx's queue + * clear the contested bit. However, we cannot hold + * a lock across casuptr(). So after we unset it we + * have to recheck, and set it again if another thread has + * put itself on the queue in the mean time. + */ + error = 0; + UMTX_LOCK(); + uq = umtx_lookup(td, umtx); + UMTX_UNLOCK(); + if (uq == NULL) + old = casuptr((intptr_t *)&umtx->u_owner, + ((intptr_t)td | UMTX_CONTESTED), (intptr_t)td); + if (uq == NULL && old == ((intptr_t)td | UMTX_CONTESTED)) { + UMTX_LOCK(); + uq = umtx_lookup(td, umtx); + UMTX_UNLOCK(); + if (uq != NULL) { + old = casuptr((intptr_t *)&umtx->u_owner, + (intptr_t)td, ((intptr_t)td | UMTX_CONTESTED)); + if (old == -1) + error = EFAULT; + else if (old != (intptr_t)td) + error = EINVAL; + } + } + return (error); } int @@ -257,25 +283,9 @@ if ((struct thread *)(owner & ~UMTX_CONTESTED) != td) return (EPERM); - /* - * If we own it but it isn't contested then we can just release and - * return. - */ - if ((owner & UMTX_CONTESTED) == 0) { - owner = casuptr((intptr_t *)&umtx->u_owner, - (intptr_t)td, UMTX_UNOWNED); - if (owner == -1) - return (EFAULT); - /* - * If this failed someone modified the memory without going - * through this api. - */ - if (owner != (intptr_t)td) - return (EINVAL); - - return (0); - } + /* We should only ever be in here for contested locks */ + KASSERT((owner & UMTX_CONTESTED) != 0, ("contested umtx is not.")); old = casuptr((intptr_t *)&umtx->u_owner, owner, UMTX_CONTESTED); @@ -296,6 +306,7 @@ uq = umtx_lookup(td, umtx); if (uq != NULL) { blocked = TAILQ_FIRST(&uq->uq_tdq); + KASSERT(blocked != NULL, ("umtx_q with no waiting threads.")); wakeup(blocked); } --oyUTqETQ0mS9luUI--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030709235221.GA10504>