diff options
| -rw-r--r-- | lib/libc_r/uthread/pthread_private.h | 11 | ||||
| -rw-r--r-- | lib/libc_r/uthread/uthread_create.c | 7 | ||||
| -rw-r--r-- | lib/libc_r/uthread/uthread_file.c | 330 | ||||
| -rw-r--r-- | lib/libc_r/uthread/uthread_info.c | 27 | ||||
| -rw-r--r-- | lib/libc_r/uthread/uthread_kern.c | 5 | ||||
| -rw-r--r-- | lib/libkse/thread/thr_create.c | 7 | ||||
| -rw-r--r-- | lib/libkse/thread/thr_info.c | 27 | ||||
| -rw-r--r-- | lib/libkse/thread/thr_kern.c | 5 | ||||
| -rw-r--r-- | lib/libkse/thread/thr_private.h | 11 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_create.c | 7 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_info.c | 27 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_kern.c | 5 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_private.h | 11 | 
13 files changed, 399 insertions, 81 deletions
| diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h index dc36d8da53f0..5ceeabaf0cc2 100644 --- a/lib/libc_r/uthread/pthread_private.h +++ b/lib/libc_r/uthread/pthread_private.h @@ -50,6 +50,7 @@   */  #include <setjmp.h>  #include <signal.h> +#include <sys/queue.h>  #include <sys/types.h>  #include <sys/time.h>  #include <sched.h> @@ -219,6 +220,7 @@ enum pthread_state {  	PS_FDLW_WAIT,  	PS_FDR_WAIT,  	PS_FDW_WAIT, +	PS_FILE_WAIT,  	PS_SELECT_WAIT,  	PS_SLEEP_WAIT,  	PS_WAIT_WAIT, @@ -283,6 +285,7 @@ struct pthread {  	 */  #define	PTHREAD_MAGIC		((u_int32_t) 0xd09ba115)  	u_int32_t		magic; +	char			*name;  	/*  	 * Pointer to the next thread in the thread linked list. @@ -387,12 +390,18 @@ struct pthread {  	 * The current thread can belong to only one queue at a time.  	 *  	 * Pointer to queue (if any) on which the current thread is waiting. +	 * +	 * XXX The queuing should be changed to use the TAILQ entry below. +	 * XXX For the time being, it's hybrid.  	 */  	struct pthread_queue	*queue;  	/* Pointer to next element in queue. */  	struct pthread	*qnxt; +	/* Queue entry for this thread: */ +	TAILQ_ENTRY(pthread) qe; +  	/* Wait data. */  	union pthread_wait_data data; @@ -634,8 +643,6 @@ ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr  /* #include <stdio.h> */  #ifdef  _STDIO_H_ -void    _thread_flockfile(FILE *fp,char *fname,int lineno); -void    _thread_funlockfile(FILE *fp);  FILE    *_thread_sys_fdopen(int, const char *);  FILE    *_thread_sys_fopen(const char *, const char *);  FILE    *_thread_sys_freopen(const char *, const char *, FILE *); diff --git a/lib/libc_r/uthread/uthread_create.c b/lib/libc_r/uthread/uthread_create.c index 3dcd944bced9..c9c6c9fb6d42 100644 --- a/lib/libc_r/uthread/uthread_create.c +++ b/lib/libc_r/uthread/uthread_create.c @@ -40,6 +40,7 @@  #include <machine/reg.h>  #include <pthread.h>  #include "pthread_private.h" +#include "libc_private.h"  int  _thread_create(pthread_t * thread, const pthread_attr_t * attr, @@ -254,6 +255,12 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,  	int             ret = 0;  	/* +	 * Locking functions in libc are required when there are +	 * threads other than the initial thread. +	 */ +	__isthreaded = 1; + +	/*  	 * Call the low level thread creation function which allows a parent  	 * thread to be specified:   	 */ diff --git a/lib/libc_r/uthread/uthread_file.c b/lib/libc_r/uthread/uthread_file.c index 0d8e9a391665..6d88c0aed93f 100644 --- a/lib/libc_r/uthread/uthread_file.c +++ b/lib/libc_r/uthread/uthread_file.c @@ -29,92 +29,326 @@   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   * SUCH DAMAGE.   * + * $Id$ + * + * POSIX stdio FILE locking functions. These assume that the locking + * is only required at FILE structure level, not at file descriptor + * level too. + *   */ -#include <signal.h>  #include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/queue.h>  #ifdef _THREAD_SAFE  #include <pthread.h>  #include "pthread_private.h" +/* + * Weak symbols for externally visible functions in this file: + */ +#pragma	weak	flockfile=_flockfile +#pragma	weak	ftrylockfile=_ftrylockfile +#pragma	weak	funlockfile=_funlockfile + +/* + * The FILE lock structure. The FILE *fp is locked if the owner is + * not NULL. If not locked, the file lock structure can be + * reassigned to a different file by setting fp. + */ +struct	file_lock { +	LIST_ENTRY(file_lock)	entry;	/* Entry if file list.       */ +	TAILQ_HEAD(lock_head, pthread) +				l_head;	/* Head of queue for threads */ +					/* waiting on this lock.     */ +	FILE		*fp;		/* The target file.          */ +	pthread_t	owner;		/* Thread that owns lock.    */ +	int		count;		/* Lock count for owner.     */ +}; + +/* + * The number of file lock lists into which the file pointer is + * hashed. Ideally, the FILE structure size would have been increased, + * but this causes incompatibility, so separate data structures are + * required. + */ +#define NUM_HEADS	128 + +/* + * This macro casts a file pointer to a long integer and right + * shifts this by the number of bytes in a pointer. The shifted + * value is then remaindered using the maximum number of hash + * entries to produce and index into the array of static lock + * structures. If there is a collision, a linear search of the + * dynamic list of locks linked to each static lock is perfomed. + */ +#define file_idx(_p)	((((long) _p) >> sizeof(void *)) % NUM_HEADS) + +/* + * Global array of file locks. The first lock for each hash bucket is + * allocated statically in the hope that there won't be too many + * collisions that require a malloc and an element added to the list. + */ +struct static_file_lock { +	LIST_HEAD(file_list_head, file_lock) head; +	struct	file_lock	fl; +} flh[NUM_HEADS]; + +/* Set to non-zero when initialisation is complete: */ +static	int	init_done	= 0; + +/* + * Find a lock structure for a FILE, return NULL if the file is + * not locked: + */ +static +struct file_lock * +find_lock(int idx, FILE *fp) +{ +	struct file_lock *p; + +	/* Check if the file is locked using the static structure: */ +	if (flh[idx].fl.fp == fp && flh[idx].fl.owner != NULL) +		/* Return a pointer to the static lock: */ +		p = &flh[idx].fl; +	else { +		/* Point to the first dynamic lock: */ +		p = flh[idx].head.lh_first; + +		/* +		 * Loop through the dynamic locks looking for the +		 * target file: +		 */ +		while (p != NULL && p->fp != fp && p->owner != NULL) +			/* Not this file, try the next: */ +			p = p->entry.le_next; +	} +	return(p); +} + +/* + * Lock a file, assuming that there is no lock structure currently1 + * assigned to it. + */ +static +struct file_lock * +do_lock(int idx, FILE *fp) +{ +	struct file_lock *p; + +	/* Check if the static structure is not being used: */ +	if (flh[idx].fl.owner == NULL) { +		/* Return a pointer to the static lock: */ +		p = &flh[idx].fl; +	} +	else { +		/* Point to the first dynamic lock: */ +		p = flh[idx].head.lh_first; + +		/* +		 * Loop through the dynamic locks looking for a +		 * lock structure that is not being used: +		 */ +		while (p != NULL && p->owner != NULL) +			/* This one is used, try the next: */ +			p = p->entry.le_next; +	} + +	/* +	 * If an existing lock structure has not been found, +	 * allocate memory for a new one: +	 */ +	if (p == NULL && (p = (struct file_lock *) +	    malloc(sizeof(struct file_lock))) != NULL) { +		/* Add the new element to the list: */ +		LIST_INSERT_HEAD(&flh[idx].head, p, entry); +	} + +	/* Check if there is a lock structure to acquire: */ +	if (p != NULL) { +		/* Acquire the lock for the running thread: */ +		p->fp		= fp; +		p->owner	= _thread_run; +		p->count	= 1; +		TAILQ_INIT(&p->l_head); +	} +	return(p); +} +  void -_thread_flockfile(FILE * fp, char *fname, int lineno) +_flockfile_debug(FILE * fp, char *fname, int lineno)  { -	int             fd, flags; -	int             status; +	int	fd, flags; +	int	status; +	int	idx = file_idx(fp); +	struct	file_lock	*p; + +	/* Check if this is a real file: */ +	if (fp->_file >= 0) { +		/* Block signals: */ +		_thread_kern_sig_block(&status); + +		/* Check if the static array has not been initialised: */ +		if (!init_done) { +			/* Initialise the global array: */ +			memset(flh,0,sizeof(flh)); + +			/* Flag the initialisation as complete: */ +			init_done = 1; +		} -	/* Block signals: */ -	_thread_kern_sig_block(&status); +		/* Get a pointer to any existing lock for the file: */ +		if ((p = find_lock(idx, fp)) == NULL) { +			/* +			 * The file is not locked, so this thread can +			 * grab the lock: +			 */ +			p = do_lock(idx, fp); -	if ((fd = fileno(fp)) >= 0) { -		if (fp->_flags & __SRW) { -			flags = FD_READ | FD_WRITE; +		/* +		 * The file is already locked, so check if the +		 * running thread is the owner: +		 */ +		} else if (p->owner == _thread_run) { +			/* +			 * The running thread is already the +			 * owner, so increment the count of +			 * the number of times it has locked +			 * the file: +			 */ +			p->count++;  		} else { -			if (fp->_flags & __SWR) { -				flags = FD_WRITE; -			} else { -				flags = FD_READ; -			} +			/* +			 * The file is locked for another thread. +			 * Append this thread to the queue of +			 * threads waiting on the lock. +			 */ +			TAILQ_INSERT_TAIL(&p->l_head,_thread_run,qe); + +			/* Wait on the FILE lock: */ +			_thread_kern_sched_state(PS_FILE_WAIT, fname, lineno); + +			/* Block signals again: */ +			_thread_kern_sig_block(NULL);  		} -		/* This might fail but POSIX doesn't give a damn. */ -		_thread_fd_lock(fd, flags, NULL, fname, lineno); +		/* Unblock signals: */ +		_thread_kern_sig_unblock(status);  	} -	/* Unblock signals: */ -	_thread_kern_sig_unblock(status); +	return; +} + +void +_flockfile(FILE * fp) +{ +	_flockfile_debug(fp, __FILE__, __LINE__);  	return;  }  int -_thread_ftrylockfile(FILE * fp) +_ftrylockfile(FILE * fp)  { -	int             fd = 0; -	int             flags; -	int             status; +	int	ret = -1; +	int	status; +	int	idx = file_idx(fp); +	struct	file_lock	*p; -	if ((fd = fileno(fp)) >= 0) { +	/* Check if this is a real file: */ +	if (fp->_file >= 0) {  		/* Block signals: */  		_thread_kern_sig_block(&status); -		if (fp->_flags & __SRW) { -			flags = FD_READ | FD_WRITE; -		} else { -			if (fp->_flags & __SWR) { -				flags = FD_WRITE; -			} else { -				flags = FD_READ; -			} -		} -		if (!(_thread_fd_table[fd]->r_owner && _thread_fd_table[fd]->w_owner)) { -			_thread_fd_lock(fd, flags, NULL, __FILE__, __LINE__); -			fd = 0; +		/* Get a pointer to any existing lock for the file: */ +		if ((p = find_lock(idx, fp)) == NULL) { +			/* +			 * The file is not locked, so this thread can +			 * grab the lock: +			 */ +			p = do_lock(idx, fp); + +		/* +		 * The file is already locked, so check if the +		 * running thread is the owner: +		 */ +		} else if (p->owner == _thread_run) { +			/* +			 * The running thread is already the +			 * owner, so increment the count of +			 * the number of times it has locked +			 * the file: +			 */ +			p->count++;  		} else { -			fd = -1; +			/* +			 * The file is locked for another thread, +			 * so this try fails. +			 */ +			p = NULL;  		} +		/* Check if the lock was obtained: */ +		if (p != NULL) +			/* Return success: */ +			ret = 0; +  		/* Unblock signals: */  		_thread_kern_sig_unblock(status);  	} -	return (fd); +	return (ret);  }  void  -_thread_funlockfile(FILE * fp) +_funlockfile(FILE * fp)  { -	int             fd, flags; -	int             status; +	int	status; +	int	idx = file_idx(fp); +	struct	file_lock	*p; -	if ((fd = fileno(fp)) >= 0) { +	/* Check if this is a real file: */ +	if (fp->_file >= 0) {  		/* Block signals: */  		_thread_kern_sig_block(&status); -		if (fp->_flags & __SRW) { -			flags = FD_READ | FD_WRITE; -		} else if (fp->_flags & __SWR) { -			flags = FD_WRITE; -		} else { -			flags = FD_READ; +		/* +		 * Get a pointer to the lock for the file and check that +		 * the running thread is the one with the lock: +		 */ +		if ((p = find_lock(idx, fp)) != NULL && +		    p->owner == _thread_run) { +			/* +			 * Check if this thread has locked the FILE +			 * more than once: +			 */ +			if (p->count > 1) +				/* +				 * Decrement the count of the number of +				 * times the running thread has locked this +				 * file: +				 */ +				p->count--; +			else { +				/* +				 * The running thread will release the +				 * lock now: +				 */ +				p->count = 0; + +				/* Get the new owner of the lock: */ +				if ((p->owner = TAILQ_FIRST(&p->l_head)) != NULL) { +					/* Pop the thread off the queue: */ +					TAILQ_REMOVE(&p->l_head,p->owner,qe); + +					/* +					 * This is the first lock for the new +					 * owner: +					 */ +					p->count = 1; + +					/* Allow the new owner to run: */ +					PTHREAD_NEW_STATE(p->owner,PS_RUNNING); +				} +			}  		} -		_thread_fd_unlock(fd, flags);  		/* Unblock signals: */  		_thread_kern_sig_unblock(status); diff --git a/lib/libc_r/uthread/uthread_info.c b/lib/libc_r/uthread/uthread_info.c index be25d45270f1..fe6565beb5e6 100644 --- a/lib/libc_r/uthread/uthread_info.c +++ b/lib/libc_r/uthread/uthread_info.c @@ -52,7 +52,8 @@ static const struct s_thread_info thread_info[] = {  	{PS_FDLR_WAIT	, "Waiting for a file read lock"},  	{PS_FDLW_WAIT	, "Waiting for a file write lock"},  	{PS_FDR_WAIT	, "Waiting for read"}, -	{PS_FDW_WAIT	, "Waitingfor write"}, +	{PS_FDW_WAIT	, "Waiting for write"}, +	{PS_FILE_WAIT	, "Waiting for FILE lock"},  	{PS_SELECT_WAIT	, "Waiting on select"},  	{PS_SLEEP_WAIT	, "Sleeping"},  	{PS_WAIT_WAIT	, "Waiting process"}, @@ -87,8 +88,8 @@ _thread_dump_info(void)  				if (thread_info[j].state == pthread->state)  					break;  			/* Output a record for the current thread: */ -			sprintf(s, "--------------------\nThread %p prio %3d state %s [%s:%d]\n", -				pthread, pthread->pthread_priority, thread_info[j].name,pthread->fname,pthread->lineno); +			sprintf(s, "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n", +				pthread, (pthread->name == NULL) ? "":pthread->name, pthread->pthread_priority, thread_info[j].name,pthread->fname,pthread->lineno);  			_thread_sys_write(fd, s, strlen(s));  			/* Check if this is the running thread: */ @@ -105,7 +106,7 @@ _thread_dump_info(void)  			}  			/* Process according to thread state: */  			switch (pthread->state) { -				/* File descriptor read lock wait: */ +			/* File descriptor read lock wait: */  			case PS_FDLR_WAIT:  			case PS_FDLW_WAIT:  			case PS_FDR_WAIT: @@ -117,10 +118,10 @@ _thread_dump_info(void)  				_thread_sys_write(fd, s, strlen(s));  				break; -				/* -				 * Trap other states that are not explicitly -				 * coded to dump information:  -				 */ +			/* +			 * Trap other states that are not explicitly +			 * coded to dump information:  +			 */  			default:  				/* Nothing to do here. */  				break; @@ -179,4 +180,14 @@ _thread_dump_info(void)  	}  	return;  } + +/* Set the thread name for debug: */ +void +pthread_set_name_np(pthread_t thread, char *name) +{ +	/* Check if the caller has specified a valid thread: */ +	if (thread != NULL && thread->magic == PTHREAD_MAGIC) +		thread->name = strdup(name); +	return; +}  #endif diff --git a/lib/libc_r/uthread/uthread_kern.c b/lib/libc_r/uthread/uthread_kern.c index eeae75cc39b1..9356c4c63e7c 100644 --- a/lib/libc_r/uthread/uthread_kern.c +++ b/lib/libc_r/uthread/uthread_kern.c @@ -29,7 +29,7 @@   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   * SUCH DAMAGE.   * - * $Id: uthread_kern.c,v 1.6 1998/02/13 01:27:33 julian Exp $ + * $Id: uthread_kern.c,v 1.7 1998/03/09 04:46:26 jb Exp $   *   */  #include <errno.h> @@ -844,6 +844,7 @@ _thread_signal(pthread_t pthread, int sig)  	case PS_DEAD:  	case PS_FDLR_WAIT:  	case PS_FDLW_WAIT: +	case PS_FILE_WAIT:  	case PS_JOIN:  	case PS_MUTEX_WAIT:  	case PS_RUNNING: @@ -1142,6 +1143,7 @@ _thread_kern_select(int wait_reqd)  		case PS_DEAD:  		case PS_FDLR_WAIT:  		case PS_FDLW_WAIT: +		case PS_FILE_WAIT:  		case PS_JOIN:  		case PS_MUTEX_WAIT:  		case PS_RUNNING: @@ -1491,6 +1493,7 @@ _thread_kern_select(int wait_reqd)  			case PS_DEAD:  			case PS_FDLR_WAIT:  			case PS_FDLW_WAIT: +			case PS_FILE_WAIT:  			case PS_JOIN:  			case PS_MUTEX_WAIT:  			case PS_SIGWAIT: diff --git a/lib/libkse/thread/thr_create.c b/lib/libkse/thread/thr_create.c index 3dcd944bced9..c9c6c9fb6d42 100644 --- a/lib/libkse/thread/thr_create.c +++ b/lib/libkse/thread/thr_create.c @@ -40,6 +40,7 @@  #include <machine/reg.h>  #include <pthread.h>  #include "pthread_private.h" +#include "libc_private.h"  int  _thread_create(pthread_t * thread, const pthread_attr_t * attr, @@ -254,6 +255,12 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,  	int             ret = 0;  	/* +	 * Locking functions in libc are required when there are +	 * threads other than the initial thread. +	 */ +	__isthreaded = 1; + +	/*  	 * Call the low level thread creation function which allows a parent  	 * thread to be specified:   	 */ diff --git a/lib/libkse/thread/thr_info.c b/lib/libkse/thread/thr_info.c index be25d45270f1..fe6565beb5e6 100644 --- a/lib/libkse/thread/thr_info.c +++ b/lib/libkse/thread/thr_info.c @@ -52,7 +52,8 @@ static const struct s_thread_info thread_info[] = {  	{PS_FDLR_WAIT	, "Waiting for a file read lock"},  	{PS_FDLW_WAIT	, "Waiting for a file write lock"},  	{PS_FDR_WAIT	, "Waiting for read"}, -	{PS_FDW_WAIT	, "Waitingfor write"}, +	{PS_FDW_WAIT	, "Waiting for write"}, +	{PS_FILE_WAIT	, "Waiting for FILE lock"},  	{PS_SELECT_WAIT	, "Waiting on select"},  	{PS_SLEEP_WAIT	, "Sleeping"},  	{PS_WAIT_WAIT	, "Waiting process"}, @@ -87,8 +88,8 @@ _thread_dump_info(void)  				if (thread_info[j].state == pthread->state)  					break;  			/* Output a record for the current thread: */ -			sprintf(s, "--------------------\nThread %p prio %3d state %s [%s:%d]\n", -				pthread, pthread->pthread_priority, thread_info[j].name,pthread->fname,pthread->lineno); +			sprintf(s, "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n", +				pthread, (pthread->name == NULL) ? "":pthread->name, pthread->pthread_priority, thread_info[j].name,pthread->fname,pthread->lineno);  			_thread_sys_write(fd, s, strlen(s));  			/* Check if this is the running thread: */ @@ -105,7 +106,7 @@ _thread_dump_info(void)  			}  			/* Process according to thread state: */  			switch (pthread->state) { -				/* File descriptor read lock wait: */ +			/* File descriptor read lock wait: */  			case PS_FDLR_WAIT:  			case PS_FDLW_WAIT:  			case PS_FDR_WAIT: @@ -117,10 +118,10 @@ _thread_dump_info(void)  				_thread_sys_write(fd, s, strlen(s));  				break; -				/* -				 * Trap other states that are not explicitly -				 * coded to dump information:  -				 */ +			/* +			 * Trap other states that are not explicitly +			 * coded to dump information:  +			 */  			default:  				/* Nothing to do here. */  				break; @@ -179,4 +180,14 @@ _thread_dump_info(void)  	}  	return;  } + +/* Set the thread name for debug: */ +void +pthread_set_name_np(pthread_t thread, char *name) +{ +	/* Check if the caller has specified a valid thread: */ +	if (thread != NULL && thread->magic == PTHREAD_MAGIC) +		thread->name = strdup(name); +	return; +}  #endif diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c index eeae75cc39b1..9356c4c63e7c 100644 --- a/lib/libkse/thread/thr_kern.c +++ b/lib/libkse/thread/thr_kern.c @@ -29,7 +29,7 @@   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   * SUCH DAMAGE.   * - * $Id: uthread_kern.c,v 1.6 1998/02/13 01:27:33 julian Exp $ + * $Id: uthread_kern.c,v 1.7 1998/03/09 04:46:26 jb Exp $   *   */  #include <errno.h> @@ -844,6 +844,7 @@ _thread_signal(pthread_t pthread, int sig)  	case PS_DEAD:  	case PS_FDLR_WAIT:  	case PS_FDLW_WAIT: +	case PS_FILE_WAIT:  	case PS_JOIN:  	case PS_MUTEX_WAIT:  	case PS_RUNNING: @@ -1142,6 +1143,7 @@ _thread_kern_select(int wait_reqd)  		case PS_DEAD:  		case PS_FDLR_WAIT:  		case PS_FDLW_WAIT: +		case PS_FILE_WAIT:  		case PS_JOIN:  		case PS_MUTEX_WAIT:  		case PS_RUNNING: @@ -1491,6 +1493,7 @@ _thread_kern_select(int wait_reqd)  			case PS_DEAD:  			case PS_FDLR_WAIT:  			case PS_FDLW_WAIT: +			case PS_FILE_WAIT:  			case PS_JOIN:  			case PS_MUTEX_WAIT:  			case PS_SIGWAIT: diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h index dc36d8da53f0..5ceeabaf0cc2 100644 --- a/lib/libkse/thread/thr_private.h +++ b/lib/libkse/thread/thr_private.h @@ -50,6 +50,7 @@   */  #include <setjmp.h>  #include <signal.h> +#include <sys/queue.h>  #include <sys/types.h>  #include <sys/time.h>  #include <sched.h> @@ -219,6 +220,7 @@ enum pthread_state {  	PS_FDLW_WAIT,  	PS_FDR_WAIT,  	PS_FDW_WAIT, +	PS_FILE_WAIT,  	PS_SELECT_WAIT,  	PS_SLEEP_WAIT,  	PS_WAIT_WAIT, @@ -283,6 +285,7 @@ struct pthread {  	 */  #define	PTHREAD_MAGIC		((u_int32_t) 0xd09ba115)  	u_int32_t		magic; +	char			*name;  	/*  	 * Pointer to the next thread in the thread linked list. @@ -387,12 +390,18 @@ struct pthread {  	 * The current thread can belong to only one queue at a time.  	 *  	 * Pointer to queue (if any) on which the current thread is waiting. +	 * +	 * XXX The queuing should be changed to use the TAILQ entry below. +	 * XXX For the time being, it's hybrid.  	 */  	struct pthread_queue	*queue;  	/* Pointer to next element in queue. */  	struct pthread	*qnxt; +	/* Queue entry for this thread: */ +	TAILQ_ENTRY(pthread) qe; +  	/* Wait data. */  	union pthread_wait_data data; @@ -634,8 +643,6 @@ ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr  /* #include <stdio.h> */  #ifdef  _STDIO_H_ -void    _thread_flockfile(FILE *fp,char *fname,int lineno); -void    _thread_funlockfile(FILE *fp);  FILE    *_thread_sys_fdopen(int, const char *);  FILE    *_thread_sys_fopen(const char *, const char *);  FILE    *_thread_sys_freopen(const char *, const char *, FILE *); diff --git a/lib/libpthread/thread/thr_create.c b/lib/libpthread/thread/thr_create.c index 3dcd944bced9..c9c6c9fb6d42 100644 --- a/lib/libpthread/thread/thr_create.c +++ b/lib/libpthread/thread/thr_create.c @@ -40,6 +40,7 @@  #include <machine/reg.h>  #include <pthread.h>  #include "pthread_private.h" +#include "libc_private.h"  int  _thread_create(pthread_t * thread, const pthread_attr_t * attr, @@ -254,6 +255,12 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,  	int             ret = 0;  	/* +	 * Locking functions in libc are required when there are +	 * threads other than the initial thread. +	 */ +	__isthreaded = 1; + +	/*  	 * Call the low level thread creation function which allows a parent  	 * thread to be specified:   	 */ diff --git a/lib/libpthread/thread/thr_info.c b/lib/libpthread/thread/thr_info.c index be25d45270f1..fe6565beb5e6 100644 --- a/lib/libpthread/thread/thr_info.c +++ b/lib/libpthread/thread/thr_info.c @@ -52,7 +52,8 @@ static const struct s_thread_info thread_info[] = {  	{PS_FDLR_WAIT	, "Waiting for a file read lock"},  	{PS_FDLW_WAIT	, "Waiting for a file write lock"},  	{PS_FDR_WAIT	, "Waiting for read"}, -	{PS_FDW_WAIT	, "Waitingfor write"}, +	{PS_FDW_WAIT	, "Waiting for write"}, +	{PS_FILE_WAIT	, "Waiting for FILE lock"},  	{PS_SELECT_WAIT	, "Waiting on select"},  	{PS_SLEEP_WAIT	, "Sleeping"},  	{PS_WAIT_WAIT	, "Waiting process"}, @@ -87,8 +88,8 @@ _thread_dump_info(void)  				if (thread_info[j].state == pthread->state)  					break;  			/* Output a record for the current thread: */ -			sprintf(s, "--------------------\nThread %p prio %3d state %s [%s:%d]\n", -				pthread, pthread->pthread_priority, thread_info[j].name,pthread->fname,pthread->lineno); +			sprintf(s, "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n", +				pthread, (pthread->name == NULL) ? "":pthread->name, pthread->pthread_priority, thread_info[j].name,pthread->fname,pthread->lineno);  			_thread_sys_write(fd, s, strlen(s));  			/* Check if this is the running thread: */ @@ -105,7 +106,7 @@ _thread_dump_info(void)  			}  			/* Process according to thread state: */  			switch (pthread->state) { -				/* File descriptor read lock wait: */ +			/* File descriptor read lock wait: */  			case PS_FDLR_WAIT:  			case PS_FDLW_WAIT:  			case PS_FDR_WAIT: @@ -117,10 +118,10 @@ _thread_dump_info(void)  				_thread_sys_write(fd, s, strlen(s));  				break; -				/* -				 * Trap other states that are not explicitly -				 * coded to dump information:  -				 */ +			/* +			 * Trap other states that are not explicitly +			 * coded to dump information:  +			 */  			default:  				/* Nothing to do here. */  				break; @@ -179,4 +180,14 @@ _thread_dump_info(void)  	}  	return;  } + +/* Set the thread name for debug: */ +void +pthread_set_name_np(pthread_t thread, char *name) +{ +	/* Check if the caller has specified a valid thread: */ +	if (thread != NULL && thread->magic == PTHREAD_MAGIC) +		thread->name = strdup(name); +	return; +}  #endif diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c index eeae75cc39b1..9356c4c63e7c 100644 --- a/lib/libpthread/thread/thr_kern.c +++ b/lib/libpthread/thread/thr_kern.c @@ -29,7 +29,7 @@   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF   * SUCH DAMAGE.   * - * $Id: uthread_kern.c,v 1.6 1998/02/13 01:27:33 julian Exp $ + * $Id: uthread_kern.c,v 1.7 1998/03/09 04:46:26 jb Exp $   *   */  #include <errno.h> @@ -844,6 +844,7 @@ _thread_signal(pthread_t pthread, int sig)  	case PS_DEAD:  	case PS_FDLR_WAIT:  	case PS_FDLW_WAIT: +	case PS_FILE_WAIT:  	case PS_JOIN:  	case PS_MUTEX_WAIT:  	case PS_RUNNING: @@ -1142,6 +1143,7 @@ _thread_kern_select(int wait_reqd)  		case PS_DEAD:  		case PS_FDLR_WAIT:  		case PS_FDLW_WAIT: +		case PS_FILE_WAIT:  		case PS_JOIN:  		case PS_MUTEX_WAIT:  		case PS_RUNNING: @@ -1491,6 +1493,7 @@ _thread_kern_select(int wait_reqd)  			case PS_DEAD:  			case PS_FDLR_WAIT:  			case PS_FDLW_WAIT: +			case PS_FILE_WAIT:  			case PS_JOIN:  			case PS_MUTEX_WAIT:  			case PS_SIGWAIT: diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h index dc36d8da53f0..5ceeabaf0cc2 100644 --- a/lib/libpthread/thread/thr_private.h +++ b/lib/libpthread/thread/thr_private.h @@ -50,6 +50,7 @@   */  #include <setjmp.h>  #include <signal.h> +#include <sys/queue.h>  #include <sys/types.h>  #include <sys/time.h>  #include <sched.h> @@ -219,6 +220,7 @@ enum pthread_state {  	PS_FDLW_WAIT,  	PS_FDR_WAIT,  	PS_FDW_WAIT, +	PS_FILE_WAIT,  	PS_SELECT_WAIT,  	PS_SLEEP_WAIT,  	PS_WAIT_WAIT, @@ -283,6 +285,7 @@ struct pthread {  	 */  #define	PTHREAD_MAGIC		((u_int32_t) 0xd09ba115)  	u_int32_t		magic; +	char			*name;  	/*  	 * Pointer to the next thread in the thread linked list. @@ -387,12 +390,18 @@ struct pthread {  	 * The current thread can belong to only one queue at a time.  	 *  	 * Pointer to queue (if any) on which the current thread is waiting. +	 * +	 * XXX The queuing should be changed to use the TAILQ entry below. +	 * XXX For the time being, it's hybrid.  	 */  	struct pthread_queue	*queue;  	/* Pointer to next element in queue. */  	struct pthread	*qnxt; +	/* Queue entry for this thread: */ +	TAILQ_ENTRY(pthread) qe; +  	/* Wait data. */  	union pthread_wait_data data; @@ -634,8 +643,6 @@ ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr  /* #include <stdio.h> */  #ifdef  _STDIO_H_ -void    _thread_flockfile(FILE *fp,char *fname,int lineno); -void    _thread_funlockfile(FILE *fp);  FILE    *_thread_sys_fdopen(int, const char *);  FILE    *_thread_sys_fopen(const char *, const char *);  FILE    *_thread_sys_freopen(const char *, const char *, FILE *); | 
