示例#1
0
static void *
_thr_rtld_lock_create(void)
{
	struct rtld_kse_lock *l;

	if ((l = malloc(sizeof(struct rtld_kse_lock))) != NULL) {
		_lock_init(&l->lck, LCK_ADAPTIVE, _kse_lock_wait,
		    _kse_lock_wakeup, calloc);
		l->owner = NULL;
		l->count = 0;
		l->write = 0;
	}
	return (l);
}
示例#2
0
文件: lock.c 项目: coyizumi/cs111
int
_lock_reinit(struct lock *lck, enum lock_type ltype,
    lock_handler_t *waitfunc, lock_handler_t *wakeupfunc)
{
	if (lck == NULL)
		return (-1);
	else if (lck->l_head == NULL)
		return (_lock_init(lck, ltype, waitfunc, wakeupfunc, calloc));
	else {
		lck->l_head->lr_locked = 0;
		lck->l_head->lr_watcher = NULL;
		lck->l_head->lr_owner = NULL;
		lck->l_head->lr_active = 1;
		lck->l_tail = lck->l_head;
	}
	return (0);
}
示例#3
0
static int
thr_mutex_init(pthread_mutex_t *mutex,
    const pthread_mutexattr_t *mutex_attr, void *(calloc_cb)(size_t, size_t))
{
	struct pthread_mutex *pmutex;
	enum pthread_mutextype type;
	int		protocol;
	int		ceiling;
	int		flags;
	int		ret = 0;

	if (mutex == NULL)
		ret = EINVAL;

	/* Check if default mutex attributes: */
	else if (mutex_attr == NULL || *mutex_attr == NULL) {
		/* Default to a (error checking) POSIX mutex: */
		type = PTHREAD_MUTEX_ERRORCHECK;
		protocol = PTHREAD_PRIO_NONE;
		ceiling = THR_MAX_PRIORITY;
		flags = 0;
	}

	/* Check mutex type: */
	else if (((*mutex_attr)->m_type < PTHREAD_MUTEX_ERRORCHECK) ||
	    ((*mutex_attr)->m_type >= PTHREAD_MUTEX_TYPE_MAX))
		/* Return an invalid argument error: */
		ret = EINVAL;

	/* Check mutex protocol: */
	else if (((*mutex_attr)->m_protocol < PTHREAD_PRIO_NONE) ||
	    ((*mutex_attr)->m_protocol > PTHREAD_MUTEX_RECURSIVE))
		/* Return an invalid argument error: */
		ret = EINVAL;

	else {
		/* Use the requested mutex type and protocol: */
		type = (*mutex_attr)->m_type;
		protocol = (*mutex_attr)->m_protocol;
		ceiling = (*mutex_attr)->m_ceiling;
		flags = (*mutex_attr)->m_flags;
	}

	/* Check no errors so far: */
	if (ret == 0) {
		if ((pmutex = (pthread_mutex_t)
		    calloc_cb(1, sizeof(struct pthread_mutex))) == NULL)
			ret = ENOMEM;
		else if (_lock_init(&pmutex->m_lock, LCK_ADAPTIVE,
		    _thr_lock_wait, _thr_lock_wakeup, calloc_cb) != 0) {
			free(pmutex);
			*mutex = NULL;
			ret = ENOMEM;
		} else {
			/* Set the mutex flags: */
			pmutex->m_flags = flags;

			/* Process according to mutex type: */
			switch (type) {
			/* case PTHREAD_MUTEX_DEFAULT: */
			case PTHREAD_MUTEX_ERRORCHECK:
			case PTHREAD_MUTEX_NORMAL:
			case PTHREAD_MUTEX_ADAPTIVE_NP:
				/* Nothing to do here. */
				break;

			/* Single UNIX Spec 2 recursive mutex: */
			case PTHREAD_MUTEX_RECURSIVE:
				/* Reset the mutex count: */
				pmutex->m_count = 0;
				break;

			/* Trap invalid mutex types: */
			default:
				/* Return an invalid argument error: */
				ret = EINVAL;
				break;
			}
			if (ret == 0) {
				/* Initialise the rest of the mutex: */
				TAILQ_INIT(&pmutex->m_queue);
				pmutex->m_flags |= MUTEX_FLAGS_INITED;
				pmutex->m_owner = NULL;
				pmutex->m_type = type;
				pmutex->m_protocol = protocol;
				pmutex->m_refcount = 0;
				if (protocol == PTHREAD_PRIO_PROTECT)
					pmutex->m_prio = ceiling;
				else
					pmutex->m_prio = -1;
				pmutex->m_saved_prio = 0;
				MUTEX_INIT_LINK(pmutex);
				*mutex = pmutex;
			} else {
				/* Free the mutex lock structure: */
				MUTEX_DESTROY(pmutex);
				*mutex = NULL;
			}
		}
	}
	/* Return the completion status: */
	return (ret);
}
示例#4
0
static void
init_private(void)
{
	struct clockinfo clockinfo;
	size_t len;
	int mib[2];

	/*
	 * Avoid reinitializing some things if they don't need to be,
	 * e.g. after a fork().
	 */
	if (init_once == 0) {
		/* Find the stack top */
		mib[0] = CTL_KERN;
		mib[1] = KERN_USRSTACK;
		len = sizeof (_usrstack);
		if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1)
			PANIC("Cannot get kern.usrstack from sysctl");
		/* Get the kernel clockrate: */
		mib[0] = CTL_KERN;
		mib[1] = KERN_CLOCKRATE;
		len = sizeof (struct clockinfo);
		if (sysctl(mib, 2, &clockinfo, &len, NULL, 0) == 0)
			_clock_res_usec = 1000000 / clockinfo.stathz;
		else
			_clock_res_usec = CLOCK_RES_USEC;

		_thr_page_size = getpagesize();
		_thr_guard_default = _thr_page_size;
		if (sizeof(void *) == 8) {
			_thr_stack_default = THR_STACK64_DEFAULT;
			_thr_stack_initial = THR_STACK64_INITIAL;
		}
		else {
			_thr_stack_default = THR_STACK32_DEFAULT;
			_thr_stack_initial = THR_STACK32_INITIAL;
		}
		_pthread_attr_default.guardsize_attr = _thr_guard_default;
		_pthread_attr_default.stacksize_attr = _thr_stack_default;
		TAILQ_INIT(&_thr_atfork_list);
		init_once = 1;	/* Don't do this again. */
	} else {
		/*
		 * Destroy the locks before creating them.  We don't
		 * know what state they are in so it is better to just
		 * recreate them.
		 */
		_lock_destroy(&_thread_signal_lock);
		_lock_destroy(&_mutex_static_lock);
		_lock_destroy(&_rwlock_static_lock);
		_lock_destroy(&_keytable_lock);
	}

	/* Initialize everything else. */
	TAILQ_INIT(&_thread_list);
	TAILQ_INIT(&_thread_gc_list);
	_pthread_mutex_init(&_thr_atfork_mutex, NULL);

	/*
	 * Initialize the lock for temporary installation of signal
	 * handlers (to support sigwait() semantics) and for the
	 * process signal mask and pending signal sets.
	 */
	if (_lock_init(&_thread_signal_lock, LCK_ADAPTIVE,
	    _kse_lock_wait, _kse_lock_wakeup, calloc) != 0)
		PANIC("Cannot initialize _thread_signal_lock");
	if (_lock_init(&_mutex_static_lock, LCK_ADAPTIVE,
	    _thr_lock_wait, _thr_lock_wakeup, calloc) != 0)
		PANIC("Cannot initialize mutex static init lock");
	if (_lock_init(&_rwlock_static_lock, LCK_ADAPTIVE,
	    _thr_lock_wait, _thr_lock_wakeup, calloc) != 0)
		PANIC("Cannot initialize rwlock static init lock");
	if (_lock_init(&_keytable_lock, LCK_ADAPTIVE,
	    _thr_lock_wait, _thr_lock_wakeup, calloc) != 0)
		PANIC("Cannot initialize thread specific keytable lock");
	_thr_spinlock_init();

	/* Clear pending signals and get the process signal mask. */
	SIGEMPTYSET(_thr_proc_sigpending);

	/* Are we in M:N mode (default) or 1:1 mode? */
#ifdef SYSTEM_SCOPE_ONLY
	_thread_scope_system = 1;
#else
	if (getenv("LIBPTHREAD_SYSTEM_SCOPE") != NULL)
		_thread_scope_system = 1;
	else if (getenv("LIBPTHREAD_PROCESS_SCOPE") != NULL)
		_thread_scope_system = -1;
#endif
	if (getenv("LIBPTHREAD_DEBUG") != NULL)
		_thr_debug_flags |= DBG_INFO_DUMP;

	/*
	 * _thread_list_lock and _kse_count are initialized
	 * by _kse_init()
	 */
}
示例#5
0
int
_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr)
{
	enum pthread_cond_type type;
	pthread_cond_t	pcond;
	int		flags;
	int             rval = 0;

	if (cond == NULL)
		rval = EINVAL;
	else {
		/*
		 * Check if a pointer to a condition variable attribute
		 * structure was passed by the caller: 
		 */
		if (cond_attr != NULL && *cond_attr != NULL) {
			/* Default to a fast condition variable: */
			type = (*cond_attr)->c_type;
			flags = (*cond_attr)->c_flags;
		} else {
			/* Default to a fast condition variable: */
			type = COND_TYPE_FAST;
			flags = 0;
		}

		/* Process according to condition variable type: */
		switch (type) {
		/* Fast condition variable: */
		case COND_TYPE_FAST:
			/* Nothing to do here. */
			break;

		/* Trap invalid condition variable types: */
		default:
			/* Return an invalid argument error: */
			rval = EINVAL;
			break;
		}

		/* Check for no errors: */
		if (rval == 0) {
			if ((pcond = (pthread_cond_t)
			    malloc(sizeof(struct pthread_cond))) == NULL) {
				rval = ENOMEM;
			} else if (_lock_init(&pcond->c_lock, LCK_ADAPTIVE,
			    _thr_lock_wait, _thr_lock_wakeup, calloc) != 0) {
				free(pcond);
				rval = ENOMEM;
			} else {
				/*
				 * Initialise the condition variable
				 * structure:
				 */
				TAILQ_INIT(&pcond->c_queue);
				pcond->c_flags = COND_FLAGS_INITED;
				pcond->c_type = type;
				pcond->c_mutex = NULL;
				pcond->c_seqno = 0;
				*cond = pcond;
			}
		}
	}
	/* Return the completion status: */
	return (rval);
}