From owner-p4-projects@FreeBSD.ORG Fri Aug 11 11:11:01 2006 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 E3F5116A4E5; Fri, 11 Aug 2006 11:11:00 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A310816A4E1 for ; Fri, 11 Aug 2006 11:11:00 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5AE2343D58 for ; Fri, 11 Aug 2006 11:11:00 +0000 (GMT) (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 k7BBB08m059343 for ; Fri, 11 Aug 2006 11:11:00 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k7BBAxIO059339 for perforce@freebsd.org; Fri, 11 Aug 2006 11:10:59 GMT (envelope-from rdivacky@FreeBSD.org) Date: Fri, 11 Aug 2006 11:10:59 GMT Message-Id: <200608111110.k7BBAxIO059339@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 103633 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: Fri, 11 Aug 2006 11:11:01 -0000 http://perforce.freebsd.org/chv.cgi?CH=103633 Change 103633 by rdivacky@rdivacky_witten on 2006/08/11 11:10:09 Giantify futex code - this is necessary because the futex code is expected to be atomic. I need to assure the atomicity. I am using Giant because its sleepable mutex. I hope someone will point me to some other better solution. This helps my pthread testing program reliably with with upto 37 threads (later it coredumps but I think this is userspace issue - its running out of memory for threads and starts doing wild things). Also - update comment in linux_machdep to satisfy netchild. Affected files ... .. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_futex.c#19 edit .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#39 edit Differences ... ==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_futex.c#19 (text+ko) ==== @@ -68,7 +68,7 @@ }; LIST_HEAD(futex_list, futex) futex_list; -struct mtx futex_mtx; +struct mtx futex_mtx; /* this protects the LIST of futexes */ #define FUTEX_LOCK mtx_lock(&futex_mtx) #define FUTEX_UNLOCK mtx_unlock(&futex_mtx) @@ -76,6 +76,9 @@ #define FUTEX_LOCKED 1 #define FUTEX_UNLOCKED 0 +#define FUTEX_SYSTEM_LOCK mtx_lock(&Giant) +#define FUTEX_SYSTEM_UNLOCK mtx_unlock(&Giant) + static struct futex *futex_get(void *, int); static void futex_put(struct futex *); static int futex_sleep(struct futex *, struct thread *, unsigned long); @@ -109,17 +112,25 @@ switch (args->op) { case LINUX_FUTEX_WAIT: + FUTEX_SYSTEM_LOCK; + if ((error = copyin(args->uaddr, - &val, sizeof(val))) != 0) + &val, sizeof(val))) != 0) { + FUTEX_SYSTEM_UNLOCK; return error; + } - if (val != args->val) + if (val != args->val) { + FUTEX_SYSTEM_UNLOCK; return EWOULDBLOCK; + } if (args->timeout != NULL) { if ((error = copyin(args->timeout, - &timeout, sizeof(timeout))) != 0) + &timeout, sizeof(timeout))) != 0) { + FUTEX_SYSTEM_UNLOCK; return error; + } } #ifdef DEBUG @@ -157,6 +168,7 @@ "ret = %d\n", td->td_proc->p_pid, args->uaddr, ret); #endif + FUTEX_SYSTEM_UNLOCK; switch (ret) { case EWOULDBLOCK: /* timeout */ return ETIMEDOUT; @@ -184,6 +196,8 @@ break; case LINUX_FUTEX_WAKE: + FUTEX_SYSTEM_LOCK; + /* * XXX: Linux is able cope with different addresses * corresponding to the same mapped memory in the sleeping @@ -197,24 +211,43 @@ f = futex_get(args->uaddr, FUTEX_UNLOCKED); td->td_retval[0] = futex_wake(f, args->val, NULL); futex_put(f); + + FUTEX_SYSTEM_UNLOCK; break; case LINUX_FUTEX_CMP_REQUEUE: + FUTEX_SYSTEM_LOCK; + if ((error = copyin(args->uaddr, - &val, sizeof(val))) != 0) + &val, sizeof(val))) != 0) { + FUTEX_SYSTEM_UNLOCK; return error; + } - if (val != args->val3) + if (val != args->val3) { + FUTEX_SYSTEM_UNLOCK; return EAGAIN; - /* FALLTHROUGH */ + } + + f = futex_get(args->uaddr, FUTEX_UNLOCKED); + newf = futex_get(args->uaddr2, FUTEX_UNLOCKED); + td->td_retval[0] = futex_wake(f, args->val, newf); + futex_put(f); + futex_put(newf); + + FUTEX_SYSTEM_UNLOCK; + break; case LINUX_FUTEX_REQUEUE: + FUTEX_SYSTEM_LOCK; + f = futex_get(args->uaddr, FUTEX_UNLOCKED); newf = futex_get(args->uaddr2, FUTEX_UNLOCKED); td->td_retval[0] = futex_wake(f, args->val, newf); futex_put(f); futex_put(newf); + FUTEX_SYSTEM_UNLOCK; break; case LINUX_FUTEX_FD: @@ -223,6 +256,7 @@ break; case LINUX_FUTEX_WAKE_OP: + FUTEX_SYSTEM_LOCK; #ifdef DEBUG if (ldebug(sys_futex)) printf("FUTEX_WAKE_OP: %d: uaddr = %p, op = %d, val = %d, uaddr2 = %p, val3 = %d\n", @@ -238,12 +272,14 @@ if (op_ret != -EFAULT) { futex_put(f); futex_put(f2); + FUTEX_SYSTEM_UNLOCK; return (-op_ret); } futex_put(f); futex_put(f2); + FUTEX_SYSTEM_UNLOCK; return (EFAULT); } @@ -259,6 +295,8 @@ } futex_put(f2); td->td_retval[0] = ret; + + FUTEX_SYSTEM_UNLOCK; break; default: ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#39 (text+ko) ==== @@ -1168,7 +1168,7 @@ MALLOC(em, struct linux_emuldata *, sizeof *em, M_LINUX, M_WAITOK | M_ZERO); em->pid = child; if (flags & CLONE_VM) { - /* handled later */ + /* handled later in the code */ } else { struct linux_emuldata_shared *s;