From owner-p4-projects@FreeBSD.ORG Wed Feb 21 11:13:38 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id EE38216E6F5; Wed, 21 Feb 2007 11:13:37 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id BFA3616D7F8 for ; Wed, 21 Feb 2007 11:13:37 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id AE09513C4BA for ; Wed, 21 Feb 2007 11:13:37 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id l1LBDbfd005059 for ; Wed, 21 Feb 2007 11:13:37 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id l1LBDbCg005053 for perforce@freebsd.org; Wed, 21 Feb 2007 11:13:37 GMT (envelope-from rdivacky@FreeBSD.org) Date: Wed, 21 Feb 2007 11:13:37 GMT Message-Id: <200702211113.l1LBDbCg005053@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky To: Perforce Change Reviews Cc: Subject: PERFORCE change 114791 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Feb 2007 11:13:38 -0000 http://perforce.freebsd.org/chv.cgi?CH=114791 Change 114791 by rdivacky@rdivacky_witten on 2007/02/21 11:12:41 o revert the previous change. linux wakes up N threads for all operations BUT requeue ones. mimic this by checking for newf being non-NULL and setting count accordingly. o introduce one more param to futex_wake which mimics the nr_requeue in linux thats wake up N+1 threads then requeue upto N2 on the new futex. note that the code doing the requeueing is likely to be rewritten (pending discussion with the original author). Affected files ... .. //depot/projects/linuxolator/src/sys/compat/linux/linux_futex.c#12 edit Differences ... ==== //depot/projects/linuxolator/src/sys/compat/linux/linux_futex.c#12 (text+ko) ==== @@ -88,7 +88,7 @@ static struct futex *futex_get(void *, int); static void futex_put(struct futex *); static int futex_sleep(struct futex *, struct thread *, unsigned long); -static int futex_wake(struct futex *, int, struct futex *); +static int futex_wake(struct futex *, int, struct futex *, int); static int futex_atomic_op(struct thread *td, int encoded_op, caddr_t uaddr); static int futex_orl(int oparg, caddr_t uaddr, int *oldval); static int futex_andl(int oparg, caddr_t uaddr, int *oldval); @@ -218,7 +218,7 @@ td->td_proc->p_pid, args->uaddr, args->val); #endif f = futex_get(args->uaddr, FUTEX_UNLOCKED); - td->td_retval[0] = futex_wake(f, args->val, NULL); + td->td_retval[0] = futex_wake(f, args->val, NULL, 0); futex_put(f); FUTEX_SYSTEM_UNLOCK; @@ -240,7 +240,7 @@ f = futex_get(args->uaddr, FUTEX_UNLOCKED); newf = futex_get(args->uaddr2, FUTEX_UNLOCKED); - td->td_retval[0] = futex_wake(f, args->val, newf); + td->td_retval[0] = futex_wake(f, args->val, newf, (int)(unsigned long)args->timeout); futex_put(f); futex_put(newf); @@ -252,7 +252,7 @@ f = futex_get(args->uaddr, FUTEX_UNLOCKED); newf = futex_get(args->uaddr2, FUTEX_UNLOCKED); - td->td_retval[0] = futex_wake(f, args->val, newf); + td->td_retval[0] = futex_wake(f, args->val, newf, (int)(unsigned long)args->timeout); futex_put(f); futex_put(newf); @@ -299,7 +299,7 @@ } - ret = futex_wake(f, args->val, NULL); + ret = futex_wake(f, args->val, NULL, 0); futex_put(f); if (op_ret > 0) { op_ret = 0; @@ -307,7 +307,7 @@ * Linux abuses the address of the timespec parameter * as the number of retries. */ - op_ret += futex_wake(f2, (int) (unsigned long) args->timeout, NULL); + op_ret += futex_wake(f2, (int) (unsigned long) args->timeout, NULL, 0); ret += op_ret; } futex_put(f2); @@ -406,14 +406,24 @@ } static int -futex_wake(struct futex *f, int n, struct futex *newf) +futex_wake(struct futex *f, int n, struct futex *newf, int n2) { struct waiting_proc *wp; - int count = 0; + int count; + + /* + * Linux is very strange it wakes up N threads for + * all operations BUT requeue ones where its N+1 + * mimic this. + */ + if (newf) + count = 0; + else + count = 1; FUTEX_LOCK; TAILQ_FOREACH(wp, &f->f_waiting_proc, wp_list) { - if (count < n) { + if (count <= n) { wakeup_one(wp); count++; } else { @@ -421,6 +431,8 @@ /* futex_put called after tsleep */ wp->wp_new_futex = futex_get(newf->f_uaddr, FUTEX_LOCKED); wakeup_one(wp); + if (count - n >= n2) + break; } } }