Date: Sat, 8 Jul 2006 13:49:19 GMT From: Roman Divacky <rdivacky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 101011 for review Message-ID: <200607081349.k68DnJBt036190@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=101011 Change 101011 by rdivacky@rdivacky_witten on 2006/07/08 13:48:40 FreeBSDify the linux_futex.c code and make it compile. Its mostly SCARG removal and lwp -> thread translation. Affected files ... .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_futex.c#2 edit .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_sysvec.c#7 edit Differences ... ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_futex.c#2 (text+ko) ==== @@ -32,24 +32,26 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.5 2005/11/23 16:14:57 manu Exp $"); +/* __KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.5 2005/11/23 16:14:57 manu Exp $"); */ +#include <sys/param.h> #include <sys/types.h> #include <sys/time.h> #include <sys/systm.h> #include <sys/proc.h> -#include <sys/lwp.h> #include <sys/queue.h> #include <sys/lock.h> +#include <sys/mutex.h> #include <sys/malloc.h> -#include <compat/linux/common/linux_futex.h> -#include <compat/linux/linux_syscallargs.h> +#include <i386/linux/linux_futex.h> +#include <i386/linux/linux.h> +#include <i386/linux/linux_proto.h> struct futex; struct waiting_proc { - struct lwp *wp_l; + struct thread *wp_t; struct futex *wp_new_futex; TAILQ_ENTRY(waiting_proc) wp_list; }; @@ -60,31 +62,20 @@ TAILQ_HEAD(lf_waiting_proc, waiting_proc) f_waiting_proc; }; -static LIST_HEAD(futex_list, futex) futex_list; -static struct lock *futex_lock = NULL; +LIST_HEAD(futex_list, futex) futex_list; +struct mtx futex_mtx; -#define FUTEX_LOCK (void)lockmgr(futex_lock, LK_EXCLUSIVE, NULL) -#define FUTEX_UNLOCK (void)lockmgr(futex_lock, LK_RELEASE, NULL) +#define FUTEX_LOCK mtx_lock(&futex_mtx) +#define FUTEX_UNLOCK mtx_unlock(&futex_mtx) static struct futex *futex_get(void *); static void futex_put(struct futex *); -static int futex_sleep(struct futex *, struct lwp *, unsigned long); +static int futex_sleep(struct futex *, struct thread *, unsigned long); static int futex_wake(struct futex *, int, struct futex *); int -linux_sys_futex(l, v, retval) - struct lwp *l; - void *v; - register_t *retval; +linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) { - struct linux_sys_futex_args /* { - syscallarg(int *) uaddr; - syscallarg(int) op; - syscallarg(int) val; - syscallarg(const struct timespec *) timeout; - syscallarg(int *) uaddr2; - syscallarg(int) val3; - } */ *uap = v; int val; int ret; struct timespec timeout = { 0, 0 }; @@ -92,49 +83,42 @@ struct futex *f; struct futex *newf; int timeout_hz; + struct timeval tv = {0, 0}; - /* First time use */ - if (futex_lock == NULL) { - futex_lock = malloc(sizeof(struct lock), - M_EMULDATA, M_WAITOK); - lockinit(futex_lock, PZERO|PCATCH, "lockfutex", 0, 0); - FUTEX_LOCK; - LIST_INIT(&futex_list); - FUTEX_UNLOCK; - } - - switch (SCARG(uap, op)) { + switch (args->op) { case LINUX_FUTEX_WAIT: - if ((error = copyin(SCARG(uap, uaddr), + if ((error = copyin(args->uaddr, &val, sizeof(val))) != 0) return error; - if (val != SCARG(uap, val)) + if (val != args->val) return EWOULDBLOCK; - if (SCARG(uap, timeout) != NULL) { - if ((error = copyin(SCARG(uap, timeout), + if (args->timeout != NULL) { + if ((error = copyin(args->timeout, &timeout, sizeof(timeout))) != 0) return error; } -#ifdef DEBUG_LINUX_FUTEX - printf("FUTEX_WAIT %d.%d: val = %d, uaddr = %p, " - "*uaddr = %d, timeout = %d.%09ld\n", - l->l_proc->p_pid, l->l_lid, SCARG(uap, val), - SCARG(uap, uaddr), val, timeout.tv_sec, timeout.tv_nsec); +#ifdef DEBUG + if (ldebug(sys_futex)) + printf("FUTEX_WAIT %d.%d: val = %d, uaddr = %p, " + "*uaddr = %d, timeout = %d.%09ld\n", + l->l_proc->p_pid, l->l_lid, args->val, + args->uaddr, val, timeout.tv_sec, timeout.tv_nsec); #endif - timeout_hz = - mstohz(timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000); + tv.tv_usec = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000; + timeout_hz = tvtohz(&tv); - f = futex_get(SCARG(uap, uaddr)); - ret = futex_sleep(f, l, timeout_hz); + f = futex_get(args->uaddr); + ret = futex_sleep(f, td, timeout_hz); futex_put(f); -#ifdef DEBUG_LINUX_FUTEX - printf("FUTEX_WAIT %d.%d: uaddr = %p, " - "ret = %d\n", l->l_proc->p_pid, l->l_lid, - SCARG(uap, uaddr), ret); +#ifdef DEBUG + if (ldebug(sys_futex)) + printf("FUTEX_WAIT %d.%d: uaddr = %p, " + "ret = %d\n", l->l_proc->p_pid, l->l_lid, + args->uaddr, ret); #endif switch (ret) { @@ -145,15 +129,17 @@ return EINTR; break; case 0: /* FUTEX_WAKE received */ -#ifdef DEBUG_LINUX_FUTEX - printf("FUTEX_WAIT %d.%d: uaddr = %p, got FUTEX_WAKE\n", - l->l_proc->p_pid, l->l_lid, SCARG(uap, uaddr)); +#ifdef DEBUG + if (ldebug(sys_futex)) + printf("FUTEX_WAIT %d.%d: uaddr = %p, got FUTEX_WAKE\n", + l->l_proc->p_pid, l->l_lid, args->uaddr); #endif return 0; break; default: -#ifdef DEBUG_LINUX_FUTEX - printf("FUTEX_WAIT: unexpected ret = %d\n", ret); +#ifdef DEBUG + if (ldebug(sys_futex)) + printf("FUTEX_WAIT: unexpected ret = %d\n", ret); #endif break; } @@ -167,29 +153,30 @@ * corresponding to the same mapped memory in the sleeping * and the waker process. */ -#ifdef DEBUG_LINUX_FUTEX - printf("FUTEX_WAKE %d.%d: uaddr = %p, val = %d\n", - l->l_proc->p_pid, l->l_lid, - SCARG(uap, uaddr), SCARG(uap, val)); +#ifdef DEBUG + if (ldebug(sys_futex)) + printf("FUTEX_WAKE %d.%d: uaddr = %p, val = %d\n", + l->l_proc->p_pid, l->l_lid, + args->uaddr, args->val); #endif - f = futex_get(SCARG(uap, uaddr)); - *retval = futex_wake(f, SCARG(uap, val), NULL); + f = futex_get(args->uaddr); + td->td_retval[0] = futex_wake(f, args->val, NULL); futex_put(f); break; case LINUX_FUTEX_CMP_REQUEUE: - if ((error = copyin(SCARG(uap, uaddr), + if ((error = copyin(args->uaddr, &val, sizeof(val))) != 0) return error; - if (val != SCARG(uap, val3)) + if (val != args->val3) return EAGAIN; /* FALLTHROUGH */ case LINUX_FUTEX_REQUEUE: - f = futex_get(SCARG(uap, uaddr)); - newf = futex_get(SCARG(uap, uaddr2)); - *retval = futex_wake(f, SCARG(uap, val), newf); + f = futex_get(args->uaddr); + newf = futex_get(args->uaddr2); + td->td_retval[0] = futex_wake(f, args->val, newf); futex_put(f); futex_put(newf); @@ -197,19 +184,18 @@ case LINUX_FUTEX_FD: printf("linux_sys_futex: unimplemented op %d\n", - SCARG(uap, op)); + args->op); break; default: printf("linux_sys_futex: unkonwn op %d\n", - SCARG(uap, op)); + args->op); break; } return 0; } static struct futex * -futex_get(uaddr) - void *uaddr; +futex_get(void *uaddr) { struct futex *f; @@ -224,7 +210,7 @@ FUTEX_UNLOCK; /* Not found, create it */ - f = malloc(sizeof(*f), M_EMULDATA, M_WAITOK); + f = malloc(sizeof(*f), M_LINUX, M_WAITOK); f->f_uaddr = uaddr; f->f_refcount = 1; TAILQ_INIT(&f->f_waiting_proc); @@ -244,31 +230,29 @@ FUTEX_LOCK; LIST_REMOVE(f, f_list); FUTEX_UNLOCK; - free(f, M_EMULDATA); + free(f, M_LINUX); } return; } static int -futex_sleep(f, l, timeout) - struct futex *f; - struct lwp *l; - unsigned long timeout; +futex_sleep(struct futex *f, struct thread *td, unsigned long timeout) { struct waiting_proc *wp; int ret; - wp = malloc(sizeof(*wp), M_EMULDATA, M_WAITOK); - wp->wp_l = l; + wp = malloc(sizeof(*wp), M_LINUX, M_WAITOK); + wp->wp_t = td; wp->wp_new_futex = NULL; FUTEX_LOCK; TAILQ_INSERT_TAIL(&f->f_waiting_proc, wp, wp_list); FUTEX_UNLOCK; -#ifdef DEBUG_LINUX_FUTEX - printf("FUTEX --> %d.%d tlseep timeout = %ld\n", l->l_proc->p_pid, - l->l_lid, timeout); +#ifdef DEBUG + if (ldebug(sys_futex)) + printf("FUTEX --> %d.%d tlseep timeout = %ld\n", l->l_proc->p_pid, + l->l_lid, timeout); #endif ret = tsleep(wp, PCATCH|PZERO, "linuxfutex", timeout); @@ -277,20 +261,17 @@ FUTEX_UNLOCK; if ((ret == 0) && (wp->wp_new_futex != NULL)) { - ret = futex_sleep(wp->wp_new_futex, l, timeout); + ret = futex_sleep(wp->wp_new_futex, td, timeout); futex_put(wp->wp_new_futex); /* futex_get called in wakeup */ } - free(wp, M_EMULDATA); + free(wp, M_LINUX); return ret; } static int -futex_wake(f, n, newf) - struct futex *f; - int n; - struct futex *newf; +futex_wake(struct futex *f, int n, struct futex *newf) { struct waiting_proc *wp; int count = 0; ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_sysvec.c#7 (text+ko) ==== @@ -112,6 +112,8 @@ extern int linux_userret(struct thread *); extern int linux_proc_exit(struct thread *); extern struct rwlock emul_lock; +extern LIST_HEAD(futex_list, futex) futex_list; +extern struct mtx futex_mtx; /* * Linux syscalls return negative errno's, we do positive and map them @@ -919,6 +921,8 @@ linux_proc_exit_p = linux_proc_exit; linux_userret_p = linux_userret; rw_init(&emul_lock, "emuldata lock"); + LIST_INIT(&futex_list); + mtx_init(&futex_mtx, "futex protection lock", NULL, MTX_DEF); break; case MOD_UNLOAD: for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; @@ -943,6 +947,7 @@ linux_proc_exit_p = NULL; linux_userret_p = NULL; rw_destroy(&emul_lock); + mtx_destroy(&futex_mtx); break; default: return EOPNOTSUPP;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607081349.k68DnJBt036190>