Пример #1
0
void
linux_e_lwp_exit(struct lwp *l)
{
	struct linux_emuldata *led;
	struct linux_sys_futex_args cup;
	register_t retval;
	int error, zero = 0;

	led = l->l_emuldata;
	if (led->led_clear_tid == NULL) {
		return;
	}

	/* Emulate LINUX_CLONE_CHILD_CLEARTID */
	error = copyout(&zero, led->led_clear_tid, sizeof(zero));
#ifdef DEBUG_LINUX
	if (error != 0)
		printf("%s: cannot clear TID\n", __func__);
#endif

	SCARG(&cup, uaddr) = led->led_clear_tid;
	SCARG(&cup, op) = LINUX_FUTEX_WAKE;
	SCARG(&cup, val) = 0x7fffffff; /* Awake everyone */
	SCARG(&cup, timeout) = NULL;
	SCARG(&cup, uaddr2) = NULL;
	SCARG(&cup, val3) = 0;
	if ((error = linux_sys_futex(curlwp, &cup, &retval)) != 0)
		printf("%s: linux_sys_futex failed\n", __func__);

	release_futexes(l);

	led = l->l_emuldata;
	l->l_emuldata = NULL;
	kmem_free(led, sizeof(*led));
}
Пример #2
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(thread_detach, "thread(%d)", em->em_tid);

	release_futexes(td, em);

	child_clear_tid = em->child_clear_tid;

	if (child_clear_tid != NULL) {

		LINUX_CTR2(thread_detach, "thread(%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.");
	}
}