Date: Fri, 11 Aug 2006 11:10:59 GMT From: Roman Divacky <rdivacky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 103633 for review Message-ID: <200608111110.k7BBAxIO059339@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608111110.k7BBAxIO059339>