From e7609e6478a135a0520880b7e7e342df010c3d3f Mon Sep 17 00:00:00 2001 From: manu Date: Fri, 4 Nov 2005 16:54:11 +0000 Subject: [PATCH] Implement Linux futex ang gettid --- sys/compat/linux/common/linux_exec.c | 20 ++-- sys/compat/linux/common/linux_futex.c | 147 ++++++++++++++++++++++++++ sys/compat/linux/common/linux_futex.h | 43 ++++++++ sys/compat/linux/common/linux_sched.c | 15 ++- 4 files changed, 217 insertions(+), 8 deletions(-) create mode 100644 sys/compat/linux/common/linux_futex.c create mode 100644 sys/compat/linux/common/linux_futex.h diff --git a/sys/compat/linux/common/linux_exec.c b/sys/compat/linux/common/linux_exec.c index 67892d02dc1b..d55ea201b49b 100644 --- a/sys/compat/linux/common/linux_exec.c +++ b/sys/compat/linux/common/linux_exec.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux_exec.c,v 1.77 2005/06/22 15:10:51 manu Exp $ */ +/* $NetBSD: linux_exec.c,v 1.78 2005/11/04 16:54:11 manu Exp $ */ /*- * Copyright (c) 1994, 1995, 1998, 2000 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: linux_exec.c,v 1.77 2005/06/22 15:10:51 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_exec.c,v 1.78 2005/11/04 16:54:11 manu Exp $"); #include #include @@ -65,6 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_exec.c,v 1.77 2005/06/22 15:10:51 manu Exp $") #include #include #include +#include #include #include @@ -261,17 +262,24 @@ linux_e_proc_exit(p) if (e->clear_tid != NULL) { int error; int null = 0; + struct linux_sys_futex_args cup; + register_t retval; + struct lwp *l; if ((error = copyout(&null, e->clear_tid, sizeof(null))) != 0) printf("linux_e_proc_exit: cannot clear TID\n"); -#ifdef notyet /* Not yet implemented */ - if ((error = linux_sys_futex(e->clear_tid, - LINUX_FUTEX_WAKE, 1, NULL, NULL, 0)) != 0) + l = proc_representative_lwp(p); + SCARG(&cup, uaddr) = e->clear_tid; + SCARG(&cup, op) = LINUX_FUTEX_WAKE; + SCARG(&cup, val) = 0; + SCARG(&cup, timeout) = NULL; + SCARG(&cup, uaddr2) = NULL; + SCARG(&cup, val3) = 0; + if ((error = linux_sys_futex(l, &cup, &retval)) != 0) printf("linux_e_proc_exit: linux_sys_futex failed\n"); -#endif } /* free Linux emuldata and set the pointer to null */ diff --git a/sys/compat/linux/common/linux_futex.c b/sys/compat/linux/common/linux_futex.c new file mode 100644 index 000000000000..7612451d7d7b --- /dev/null +++ b/sys/compat/linux/common/linux_futex.c @@ -0,0 +1,147 @@ +/* $NetBSD: linux_futex.c,v 1.1 2005/11/04 16:54:11 manu Exp $ */ + +/*- + * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Emmanuel Dreyfus + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.1 2005/11/04 16:54:11 manu Exp $"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +int +linux_sys_futex(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; +{ + 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 }; + int error = 0; + + switch (SCARG(uap, op)) { + case LINUX_FUTEX_WAIT: + if ((error = copyin(SCARG(uap, uaddr), + &val, sizeof(val))) != 0) + return error; + + if (val != SCARG(uap, val)) + return EWOULDBLOCK; + + if (SCARG(uap, timeout) != NULL) { + if ((error = copyin(SCARG(uap, timeout), + &timeout, sizeof(timeout))) != 0) + return error; + } + +#ifdef DEBUG_LINUX + 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); +#endif + ret = tsleep(SCARG(uap, uaddr), PCATCH|PZERO, + "linuxfutex", timeout.tv_sec * hz); +#ifdef DEBUG_LINUX + printf("FUTEX_WAIT %d.%d: uaddr = %p, " + "ret = %d\n", l->l_proc->p_pid, l->l_lid, + SCARG(uap, uaddr), ret); +#endif + + switch (ret) { + case EWOULDBLOCK: /* timeout */ + return ETIMEDOUT; + break; + case EINTR: /* signal */ + return EINTR; + break; + case 0: /* FUTEX_WAKE received */ +#ifdef DEBUG_LINUX + printf("FUTEX_WAIT %d.%d: uaddr = %p, got FUTEX_WAKE\n", + l->l_proc->p_pid, l->l_lid, SCARG(uap, uaddr)); +#endif + return 0; + break; + default: + printf("FUTEX_WAIT: unexpected ret = %d\n", ret); + break; + } + + /* NOTREACHED */ + break; + + case LINUX_FUTEX_WAKE: + /* + * XXX We should only wake up SCARG(uap, val) processes + * waiting on the futex, not all of them. + * More XXX: Linux is able cope with different addresses + * corresponding to the same mapped memory in the sleeping + * and the waker process. + */ +#ifdef DEBUG_LINUX + printf("FUTEX_WAKE %d.%d: uaddr = %p, val = %d\n", + l->l_proc->p_pid, l->l_lid, + SCARG(uap, uaddr), SCARG(uap, val)); +#endif + wakeup(SCARG(uap, uaddr)); + + *retval = 1; /* XXX should be number of processes */ + break; + + case LINUX_FUTEX_FD: + case LINUX_FUTEX_REQUEUE: + case LINUX_FUTEX_CMP_REQUEUE: + printf("linux_sys_futex: unimplemented op %d\n", + SCARG(uap, op)); + break; + default: + printf("linux_sys_futex: unkonwn op %d\n", + SCARG(uap, op)); + break; + } + return 0; +} diff --git a/sys/compat/linux/common/linux_futex.h b/sys/compat/linux/common/linux_futex.h new file mode 100644 index 000000000000..b538e334e3e4 --- /dev/null +++ b/sys/compat/linux/common/linux_futex.h @@ -0,0 +1,43 @@ +/* $NetBSD: linux_futex.h,v 1.1 2005/11/04 16:54:11 manu Exp $ */ + +/*- + * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Emmanuel Dreyfus + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LINUX_FUTEX_H +#define _LINUX_FUTEX_H + +#define LINUX_FUTEX_WAIT 0 +#define LINUX_FUTEX_WAKE 1 +#define LINUX_FUTEX_FD 2 +#define LINUX_FUTEX_REQUEUE 3 +#define LINUX_FUTEX_CMP_REQUEUE 4 + +#endif /* !_LINUX_FUTEX_H */ diff --git a/sys/compat/linux/common/linux_sched.c b/sys/compat/linux/common/linux_sched.c index f7d5c6701044..48eeaed6493b 100644 --- a/sys/compat/linux/common/linux_sched.c +++ b/sys/compat/linux/common/linux_sched.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux_sched.c,v 1.19 2005/06/22 15:10:51 manu Exp $ */ +/* $NetBSD: linux_sched.c,v 1.20 2005/11/04 16:54:11 manu Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -42,7 +42,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: linux_sched.c,v 1.19 2005/06/22 15:10:51 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_sched.c,v 1.20 2005/11/04 16:54:11 manu Exp $"); #include #include @@ -426,4 +426,15 @@ linux_sys_set_tid_address(l, v, retval) return 0; } + +/* ARGUSED1 */ +int +linux_sys_gettid(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; +{ + *retval = l->l_proc->p_pid; + return 0; +} #endif /* __amd64__ */