コード例 #1
0
ファイル: lock.c プロジェクト: coyizumi/cs111
int
_lock_init(struct lock *lck, enum lock_type ltype,
    lock_handler_t *waitfunc, lock_handler_t *wakeupfunc,
    void *(calloc_cb)(size_t, size_t))
{
	if (lck == NULL)
		return (-1);
	else if ((lck->l_head = calloc_cb(1, sizeof(struct lockreq))) == NULL)
		return (-1);
	else {
		lck->l_type = ltype;
		lck->l_wait = waitfunc;
		lck->l_wakeup = wakeupfunc;
		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);
}
コード例 #2
0
ファイル: thr_mutex.c プロジェクト: MattDooner/freebsd-west
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);
}