diff options
author | dchagin <dchagin@FreeBSD.org> | 2016-01-09 16:11:09 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2016-01-09 16:11:09 +0000 |
commit | 6c12e20ac1e5ea5573246049365409feabb20095 (patch) | |
tree | faa5068ff72fa5ba5e4a549a627a6eb1509ad298 /sys/compat/linux/linux_fork.c | |
parent | d30e84112a87337209ea45237f3d9b12e29abaa9 (diff) | |
download | FreeBSD-src-6c12e20ac1e5ea5573246049365409feabb20095.zip FreeBSD-src-6c12e20ac1e5ea5573246049365409feabb20095.tar.gz |
MFC r283422:
Refund the proc emuldata struct for future use. For now move flags from
thread emuldata to proc emuldata as it was originally intended.
As we can have both 64 & 32 bit Linuxulator running any eventhandler
can be called twice for us. To prevent this move eventhandlers code
from linux_emul.c to the linux_common.ko module.
Diffstat (limited to 'sys/compat/linux/linux_fork.c')
-rw-r--r-- | sys/compat/linux/linux_fork.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c index bffe468..f74c9a2 100644 --- a/sys/compat/linux/linux_fork.c +++ b/sys/compat/linux/linux_fork.c @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #endif #include <compat/linux/linux_signal.h> #include <compat/linux/linux_emul.h> +#include <compat/linux/linux_futex.h> #include <compat/linux/linux_misc.h> #include <compat/linux/linux_util.h> @@ -405,3 +406,63 @@ linux_exit(struct thread *td, struct linux_exit_args *args) exit1(td, W_EXITCODE(args->rval, 0)); /* NOTREACHED */ } + +int +linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args) +{ + struct linux_emuldata *em; + + em = em_find(td); + KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n")); + + em->child_clear_tid = args->tidptr; + + td->td_retval[0] = em->em_tid; + + LINUX_CTR3(set_tid_address, "tidptr(%d) %p, returns %d", + em->em_tid, args->tidptr, td->td_retval[0]); + + return (0); +} + +void +linux_thread_detach(struct thread *td) +{ + struct linux_sys_futex_args cup; + struct linux_emuldata *em; + int *child_clear_tid; + int error; + + em = em_find(td); + KASSERT(em != NULL, ("thread_detach: emuldata not found.\n")); + + LINUX_CTR1(exit, "thread detach(%d)", em->em_tid); + + release_futexes(td, em); + + child_clear_tid = em->child_clear_tid; + + if (child_clear_tid != NULL) { + + LINUX_CTR2(exit, "thread detach(%d) %p", + em->em_tid, child_clear_tid); + + error = suword32(child_clear_tid, 0); + if (error != 0) + return; + + cup.uaddr = child_clear_tid; + cup.op = LINUX_FUTEX_WAKE; + cup.val = 1; /* wake one */ + cup.timeout = NULL; + cup.uaddr2 = NULL; + cup.val3 = 0; + error = linux_sys_futex(td, &cup); + /* + * this cannot happen at the moment and if this happens it + * probably means there is a user space bug + */ + if (error != 0) + linux_msg(td, "futex stuff in thread_detach failed."); + } +} |