diff options
| author | Julian Elischer <julian@FreeBSD.org> | 1996-08-20 08:22:01 +0000 | 
|---|---|---|
| committer | Julian Elischer <julian@FreeBSD.org> | 1996-08-20 08:22:01 +0000 | 
| commit | 0f7d684755aefbcfd70b45d24efc2d39bc505c4c (patch) | |
| tree | b14348030d1048f8628b798374a8a061a990aae3 /lib/libc_r/uthread/uthread_mutex.c | |
| parent | 1bbb22c82e47dbc805e523be5e2fe3d4436761e0 (diff) | |
Notes
Diffstat (limited to 'lib/libc_r/uthread/uthread_mutex.c')
| -rw-r--r-- | lib/libc_r/uthread/uthread_mutex.c | 465 | 
1 files changed, 249 insertions, 216 deletions
| diff --git a/lib/libc_r/uthread/uthread_mutex.c b/lib/libc_r/uthread/uthread_mutex.c index 0fc9fbba3e50..dc9be3c5ff78 100644 --- a/lib/libc_r/uthread/uthread_mutex.c +++ b/lib/libc_r/uthread/uthread_mutex.c @@ -41,35 +41,95 @@ pthread_mutex_init(pthread_mutex_t * mutex,  		   const pthread_mutexattr_t * mutex_attr)  {  	enum pthread_mutextype type; +	pthread_mutex_t	pmutex;  	int             ret = 0;  	int             status; -	/* Check if the mutex attributes specify some mutex other than fast: */ -	if (mutex_attr != NULL && mutex_attr->m_type != MUTEX_TYPE_FAST) { -		/* Check if the mutex type is out of range: */ -		if (mutex_attr->m_type >= MUTEX_TYPE_MAX) { +	if (mutex == NULL) { +		errno = EINVAL; +		ret = -1; +	} else { +		/* Check if default mutex attributes: */ +		if (mutex_attr == NULL || *mutex_attr == NULL) { +			/* Default to a fast mutex: */ +			type = MUTEX_TYPE_FAST; +		} else if ((*mutex_attr)->m_type >= MUTEX_TYPE_MAX) {  			/* Return an invalid argument error: */ -			_thread_seterrno(_thread_run, EINVAL); +			errno = EINVAL;  			ret = -1;  		} else {  			/* Use the requested mutex type: */ -			type = mutex_attr->m_type; +			type = (*mutex_attr)->m_type; +		} + +		/* Check no errors so far: */ +		if (ret == 0) { +			if ((pmutex = (pthread_mutex_t) malloc(sizeof(struct pthread_mutex))) == NULL) { +				errno = ENOMEM; +				ret = -1; +			} else { +				/* Reset the mutex flags: */ +				pmutex->m_flags = 0; + +				/* Block signals: */ +				_thread_kern_sig_block(&status); + +				/* Process according to mutex type: */ +				switch (type) { +					/* Fast mutex: */ +				case MUTEX_TYPE_FAST: +					/* Nothing to do here. */ +					break; + +					/* Counting mutex: */ +				case MUTEX_TYPE_COUNTING_FAST: +					/* Reset the mutex count: */ +					pmutex->m_data.m_count = 0; +					break; + +					/* Trap invalid mutex types: */ +				default: +					/* Return an invalid argument error: */ +					errno = EINVAL; +					ret = -1; +					break; +				} +				if (ret == 0) { +					/* Initialise the rest of the mutex: */ +					_thread_queue_init(&pmutex->m_queue); +					pmutex->m_flags |= MUTEX_FLAGS_INITED; +					pmutex->m_owner = NULL; +					pmutex->m_type = type; +					*mutex = pmutex; +				} else { +					free(pmutex); +					*mutex = NULL; +				} + +				/* Unblock signals: */ +				_thread_kern_sig_unblock(status); +			}  		} -	} else { -		/* Default to a fast mutex: */ -		type = MUTEX_TYPE_FAST;  	} +	/* Return the completion status: */ +	return (ret); +} -	/* Check no errors so far: */ -	if (ret == 0) { -		/* Reset the mutex flags: */ -		mutex->m_flags = 0; +int +pthread_mutex_destroy(pthread_mutex_t * mutex) +{ +	int             ret = 0; +	int             status; +	if (mutex == NULL || *mutex == NULL) { +		errno = EINVAL; +		ret = -1; +	} else {  		/* Block signals: */  		_thread_kern_sig_block(&status);  		/* Process according to mutex type: */ -		switch (type) { +		switch ((*mutex)->m_type) {  			/* Fast mutex: */  		case MUTEX_TYPE_FAST:  			/* Nothing to do here. */ @@ -78,67 +138,25 @@ pthread_mutex_init(pthread_mutex_t * mutex,  			/* Counting mutex: */  		case MUTEX_TYPE_COUNTING_FAST:  			/* Reset the mutex count: */ -			mutex->m_data.m_count = 0; +			(*mutex)->m_data.m_count = 0;  			break; -			/* Trap invalid mutex types: */ +			/* Trap undefined mutex types: */  		default:  			/* Return an invalid argument error: */ -			_thread_seterrno(_thread_run, EINVAL); +			errno = EINVAL;  			ret = -1;  			break;  		} -		/* Initialise the rest of the mutex: */ -		_thread_queue_init(&mutex->m_queue); -		mutex->m_flags |= MUTEX_FLAGS_INITED; -		mutex->m_owner = NULL; -		mutex->m_type = type; +		/* Clean up the mutex in case that others want to use it: */ +		_thread_queue_init(&(*mutex)->m_queue); +		(*mutex)->m_owner = NULL; +		(*mutex)->m_flags = 0;  		/* Unblock signals: */  		_thread_kern_sig_unblock(status);  	} -	/* Return the completion status: */ -	return (ret); -} - -int -pthread_mutex_destroy(pthread_mutex_t * mutex) -{ -	int             ret = 0; -	int             status; - -	/* Block signals: */ -	_thread_kern_sig_block(&status); - -	/* Process according to mutex type: */ -	switch (mutex->m_type) { -		/* Fast mutex: */ -	case MUTEX_TYPE_FAST: -		/* Nothing to do here. */ -		break; - -		/* Counting mutex: */ -	case MUTEX_TYPE_COUNTING_FAST: -		/* Reset the mutex count: */ -		mutex->m_data.m_count = 0; -		break; - -		/* Trap undefined mutex types: */ -	default: -		/* Return an invalid argument error: */ -		_thread_seterrno(_thread_run, EINVAL); -		ret = -1; -		break; -	} - -	/* Clean up the mutex in case that others want to use it: */ -	_thread_queue_init(&mutex->m_queue); -	mutex->m_owner = NULL; -	mutex->m_flags = 0; - -	/* Unblock signals: */ -	_thread_kern_sig_unblock(status);  	/* Return the completion status: */  	return (ret); @@ -150,56 +168,61 @@ pthread_mutex_trylock(pthread_mutex_t * mutex)  	int             ret = 0;  	int             status; -	/* Block signals: */ -	_thread_kern_sig_block(&status); +	if (mutex == NULL || *mutex == NULL) { +		errno = EINVAL; +		ret = -1; +	} else { +		/* Block signals: */ +		_thread_kern_sig_block(&status); -	/* Process according to mutex type: */ -	switch (mutex->m_type) { +		/* Process according to mutex type: */ +		switch ((*mutex)->m_type) {  		/* Fast mutex: */ -	case MUTEX_TYPE_FAST: -		/* Check if this mutex is not locked: */ -		if (mutex->m_owner == NULL) { -			/* Lock the mutex for the running thread: */ -			mutex->m_owner = _thread_run; -		} else { -			/* Return a busy error: */ -			_thread_seterrno(_thread_run, EBUSY); -			ret = -1; -		} -		break; - -		/* Counting mutex: */ -	case MUTEX_TYPE_COUNTING_FAST: -		/* Check if this mutex is locked: */ -		if (mutex->m_owner != NULL) { -			/* -			 * Check if the mutex is locked by the running -			 * thread:  -			 */ -			if (mutex->m_owner == _thread_run) { -				/* Increment the lock count: */ -				mutex->m_data.m_count++; +		case MUTEX_TYPE_FAST: +			/* Check if this mutex is not locked: */ +			if ((*mutex)->m_owner == NULL) { +				/* Lock the mutex for the running thread: */ +				(*mutex)->m_owner = _thread_run;  			} else {  				/* Return a busy error: */ -				_thread_seterrno(_thread_run, EBUSY); +				errno = EBUSY;  				ret = -1;  			} -		} else { -			/* Lock the mutex for the running thread: */ -			mutex->m_owner = _thread_run; -		} -		break; +			break; + +		/* Counting mutex: */ +		case MUTEX_TYPE_COUNTING_FAST: +			/* Check if this mutex is locked: */ +			if ((*mutex)->m_owner != NULL) { +				/* +				 * Check if the mutex is locked by the running +				 * thread:  +				 */ +				if ((*mutex)->m_owner == _thread_run) { +					/* Increment the lock count: */ +					(*mutex)->m_data.m_count++; +				} else { +					/* Return a busy error: */ +					errno = EBUSY; +					ret = -1; +				} +			} else { +				/* Lock the mutex for the running thread: */ +				(*mutex)->m_owner = _thread_run; +			} +			break;  		/* Trap invalid mutex types: */ -	default: -		/* Return an invalid argument error: */ -		_thread_seterrno(_thread_run, EINVAL); -		ret = -1; -		break; -	} +		default: +			/* Return an invalid argument error: */ +			errno = EINVAL; +			ret = -1; +			break; +		} -	/* Unblock signals: */ -	_thread_kern_sig_unblock(status); +		/* Unblock signals: */ +		_thread_kern_sig_unblock(status); +	}  	/* Return the completion status: */  	return (ret); @@ -211,81 +234,86 @@ pthread_mutex_lock(pthread_mutex_t * mutex)  	int             ret = 0;  	int             status; -	/* Block signals: */ -	_thread_kern_sig_block(&status); +	if (mutex == NULL || *mutex == NULL) { +		errno = EINVAL; +		ret = -1; +	} else { +		/* Block signals: */ +		_thread_kern_sig_block(&status); -	/* Process according to mutex type: */ -	switch (mutex->m_type) { +		/* Process according to mutex type: */ +		switch ((*mutex)->m_type) {  		/* Fast mutexes do not check for any error conditions: */ -	case MUTEX_TYPE_FAST: -		/* -		 * Enter a loop to wait for the mutex to be locked by the -		 * current thread:  -		 */ -		while (mutex->m_owner != _thread_run) { -			/* Check if the mutex is not locked: */ -			if (mutex->m_owner == NULL) { -				/* Lock the mutex for this thread: */ -				mutex->m_owner = _thread_run; -			} else { -				/* -				 * Join the queue of threads waiting to lock -				 * the mutex:  -				 */ -				_thread_queue_enq(&mutex->m_queue, _thread_run); - -				/* Block signals: */ -				_thread_kern_sched_state(PS_MUTEX_WAIT, __FILE__, __LINE__); - -				/* Block signals: */ -				_thread_kern_sig_block(NULL); +		case MUTEX_TYPE_FAST: +			/* +			 * Enter a loop to wait for the mutex to be locked by the +			 * current thread:  +			 */ +			while ((*mutex)->m_owner != _thread_run) { +				/* Check if the mutex is not locked: */ +				if ((*mutex)->m_owner == NULL) { +					/* Lock the mutex for this thread: */ +					(*mutex)->m_owner = _thread_run; +				} else { +					/* +					 * Join the queue of threads waiting to lock +					 * the mutex:  +					 */ +					_thread_queue_enq(&(*mutex)->m_queue, _thread_run); + +					/* Block signals: */ +					_thread_kern_sched_state(PS_MUTEX_WAIT, __FILE__, __LINE__); + +					/* Block signals: */ +					_thread_kern_sig_block(NULL); +				}  			} -		} -		break; +			break;  		/* Counting mutex: */ -	case MUTEX_TYPE_COUNTING_FAST: -		/* -		 * Enter a loop to wait for the mutex to be locked by the -		 * current thread:  -		 */ -		while (mutex->m_owner != _thread_run) { -			/* Check if the mutex is not locked: */ -			if (mutex->m_owner == NULL) { -				/* Lock the mutex for this thread: */ -				mutex->m_owner = _thread_run; - -				/* Reset the lock count for this mutex: */ -				mutex->m_data.m_count = 0; -			} else { -				/* -				 * Join the queue of threads waiting to lock -				 * the mutex:  -				 */ -				_thread_queue_enq(&mutex->m_queue, _thread_run); - -				/* Block signals: */ -				_thread_kern_sched_state(PS_MUTEX_WAIT, __FILE__, __LINE__); - -				/* Block signals: */ -				_thread_kern_sig_block(NULL); +		case MUTEX_TYPE_COUNTING_FAST: +			/* +			 * Enter a loop to wait for the mutex to be locked by the +			 * current thread:  +			 */ +			while ((*mutex)->m_owner != _thread_run) { +				/* Check if the mutex is not locked: */ +				if ((*mutex)->m_owner == NULL) { +					/* Lock the mutex for this thread: */ +					(*mutex)->m_owner = _thread_run; + +					/* Reset the lock count for this mutex: */ +					(*mutex)->m_data.m_count = 0; +				} else { +					/* +					 * Join the queue of threads waiting to lock +					 * the mutex:  +					 */ +					_thread_queue_enq(&(*mutex)->m_queue, _thread_run); + +					/* Block signals: */ +					_thread_kern_sched_state(PS_MUTEX_WAIT, __FILE__, __LINE__); + +					/* Block signals: */ +					_thread_kern_sig_block(NULL); +				}  			} -		} -		/* Increment the lock count for this mutex: */ -		mutex->m_data.m_count++; -		break; +			/* Increment the lock count for this mutex: */ +			(*mutex)->m_data.m_count++; +			break;  		/* Trap invalid mutex types: */ -	default: -		/* Return an invalid argument error: */ -		_thread_seterrno(_thread_run, EINVAL); -		ret = -1; -		break; -	} +		default: +			/* Return an invalid argument error: */ +			errno = EINVAL; +			ret = -1; +			break; +		} -	/* Unblock signals: */ -	_thread_kern_sig_unblock(status); +		/* Unblock signals: */ +		_thread_kern_sig_unblock(status); +	}  	/* Return the completion status: */  	return (ret); @@ -297,63 +325,68 @@ pthread_mutex_unlock(pthread_mutex_t * mutex)  	int             ret = 0;  	int             status; -	/* Block signals: */ -	_thread_kern_sig_block(&status); +	if (mutex == NULL || *mutex == NULL) { +		errno = EINVAL; +		ret = -1; +	} else { +		/* Block signals: */ +		_thread_kern_sig_block(&status); -	/* Process according to mutex type: */ -	switch (mutex->m_type) { +		/* Process according to mutex type: */ +		switch ((*mutex)->m_type) {  		/* Fast mutexes do not check for any error conditions: */ -	case MUTEX_TYPE_FAST: -		/* Check if the running thread is not the owner of the mutex: */ -		if (mutex->m_owner != _thread_run) { -			/* Return an invalid argument error: */ -			_thread_seterrno(_thread_run, EINVAL); -			ret = -1; -		} -		/* -		 * Get the next thread from the queue of threads waiting on -		 * the mutex:  -		 */ -		else if ((mutex->m_owner = _thread_queue_deq(&mutex->m_queue)) != NULL) { -			/* Allow the new owner of the mutex to run: */ -			mutex->m_owner->state = PS_RUNNING; -		} -		break; +		case MUTEX_TYPE_FAST: +			/* Check if the running thread is not the owner of the mutex: */ +			if ((*mutex)->m_owner != _thread_run) { +				/* Return an invalid argument error: */ +				errno = EINVAL; +				ret = -1; +			} +			/* +			 * Get the next thread from the queue of threads waiting on +			 * the mutex:  +			 */ +			else if (((*mutex)->m_owner = _thread_queue_deq(&(*mutex)->m_queue)) != NULL) { +				/* Allow the new owner of the mutex to run: */ +				(*mutex)->m_owner->state = PS_RUNNING; +			} +			break;  		/* Counting mutex: */ -	case MUTEX_TYPE_COUNTING_FAST: -		/* Check if the running thread is not the owner of the mutex: */ -		if (mutex->m_owner != _thread_run) { +		case MUTEX_TYPE_COUNTING_FAST: +			/* Check if the running thread is not the owner of the mutex: */ +			if ((*mutex)->m_owner != _thread_run) { +				/* Return an invalid argument error: */ +				errno = EINVAL; +				ret = -1; +			} +			/* Check if there are still counts: */ +			else if ((*mutex)->m_data.m_count) { +				/* Decrement the count: */ +				(*mutex)->m_data.m_count--; +			} +			/* +			 * Get the next thread from the queue of threads waiting on +			 * the mutex:  +			 */ +			else if (((*mutex)->m_owner = _thread_queue_deq(&(*mutex)->m_queue)) != NULL) { +				/* Allow the new owner of the mutex to run: */ +				(*mutex)->m_owner->state = PS_RUNNING; +			} +			break; + +		/* Trap invalid mutex types: */ +		default:  			/* Return an invalid argument error: */ -			_thread_seterrno(_thread_run, EINVAL); +			errno = EINVAL;  			ret = -1; +			break;  		} -		/* Check if there are still counts: */ -		else if (mutex->m_data.m_count) { -			/* Decrement the count: */ -			mutex->m_data.m_count--; -		} -		/* -		 * Get the next thread from the queue of threads waiting on -		 * the mutex:  -		 */ -		else if ((mutex->m_owner = _thread_queue_deq(&mutex->m_queue)) != NULL) { -			/* Allow the new owner of the mutex to run: */ -			mutex->m_owner->state = PS_RUNNING; -		} -		break; -		/* Trap invalid mutex types: */ -	default: -		/* Return an invalid argument error: */ -		_thread_seterrno(_thread_run, EINVAL); -		ret = -1; -		break; +		/* Unblock signals: */ +		_thread_kern_sig_unblock(status);  	} -	/* Unblock signals: */ -	_thread_kern_sig_unblock(status); -  	/* Return the completion status: */  	return (ret);  } | 
