Esempio n. 1
0
static void
free_stack(struct pthread_attr *pattr)
{
	struct kse *curkse;
	kse_critical_t crit;

	if ((pattr->flags & THR_STACK_USER) == 0) {
		crit = _kse_critical_enter();
		curkse = _get_curkse();
		KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock);
		/* Stack routines don't use malloc/free. */
		_thr_stack_free(pattr);
		KSE_LOCK_RELEASE(curkse, &_thread_list_lock);
		_kse_critical_leave(crit);
	}
}
Esempio n. 2
0
void
_thr_gc(struct pthread *curthread)
{
	struct pthread *td, *td_next;
	TAILQ_HEAD(, pthread) worklist;

	TAILQ_INIT(&worklist);
	THREAD_LIST_LOCK(curthread);

	/* Check the threads waiting for GC. */
	for (td = TAILQ_FIRST(&_thread_gc_list); td != NULL; td = td_next) {
		td_next = TAILQ_NEXT(td, gcle);
		if (td->terminated == 0) {
			/* make sure we are not still in userland */
			continue;
		}
		_thr_stack_free(&td->attr);
		if (((td->tlflags & TLFLAGS_DETACHED) != 0) &&
		    (td->refcount == 0)) {
			THR_GCLIST_REMOVE(td);
			/*
			 * The thread has detached and is no longer
			 * referenced.  It is safe to remove all
			 * remnants of the thread.
			 */
			THR_LIST_REMOVE(td);
			TAILQ_INSERT_HEAD(&worklist, td, gcle);
		}
	}
	THREAD_LIST_UNLOCK(curthread);

	while ((td = TAILQ_FIRST(&worklist)) != NULL) {
		TAILQ_REMOVE(&worklist, td, gcle);
		/*
		 * XXX we don't free initial thread, because there might
		 * have some code referencing initial thread.
		 */
		if (td == _thr_initial) {
			DBG_MSG("Initial thread won't be freed\n");
			continue;
		}

		_thr_free(curthread, td);
	}
}