diff options
author | julian <julian@FreeBSD.org> | 1996-08-20 08:22:01 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 1996-08-20 08:22:01 +0000 |
commit | 7350d1d3b2ec940c89a2b20f9d09985d9fd9e9d7 (patch) | |
tree | b14348030d1048f8628b798374a8a061a990aae3 /lib/libpthread/thread/thr_cond.c | |
parent | 60125bd1a9e42a8b02f15396ba886b417c95bbc1 (diff) | |
download | FreeBSD-src-7350d1d3b2ec940c89a2b20f9d09985d9fd9e9d7.zip FreeBSD-src-7350d1d3b2ec940c89a2b20f9d09985d9fd9e9d7.tar.gz |
Submitted by: John Birrell <cimaxp1!jb@werple.net.au>
Here are the diffs for libc_r to get it one step closer to P1003.1c
These make most of the thread/mutex/condvar structures opaque to the
user. There are three functions which have been renamed with _np
suffixes because they are extensions to P1003.1c (I did them for JAVA,
which needs to suspend/resume threads and also start threads suspended).
I've created a new header (pthread_np.h) for the non-POSIX stuff.
The egrep tags stuff in /usr/src/lib/libc_r/Makefile that I uncommented
doesn't work. I think its best to delete it. I don't think libc_r needs
tags anyway, 'cause most of the source is in libc which does have tags.
also:
Here's the first batch of man pages for the thread functions.
The diff to /usr/src/lib/libc_r/Makefile removes some stuff that was
inherited from /usr/src/lib/libc/Makefile that should only be done with
libc.
also:
I should have sent this diff with the pthread(3) man page.
It allows people to type
make -DWANT_LIBC_R world
to get libc_r built with the rest of the world. I put this in the
pthread(3) man page. The default is still not to build libc_r.
also:
The diff attached adds a pthread(3) man page to /usr/src/share/man/man3.
The idea is that without libc_r installed, this man page will give people
enough info to know that they have to build libc_r.
Diffstat (limited to 'lib/libpthread/thread/thr_cond.c')
-rw-r--r-- | lib/libpthread/thread/thr_cond.c | 334 |
1 files changed, 188 insertions, 146 deletions
diff --git a/lib/libpthread/thread/thr_cond.c b/lib/libpthread/thread/thr_cond.c index 930f31a..0f9f302 100644 --- a/lib/libpthread/thread/thr_cond.c +++ b/lib/libpthread/thread/thr_cond.c @@ -40,41 +40,56 @@ int pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * cond_attr) { enum pthread_cond_type type; + pthread_cond_t pcond; int rval = 0; - /* - * Check if a pointer to a condition variable attribute structure was - * passed by the caller: - */ - if (cond_attr != NULL) { - /* Default to a fast condition variable: */ - type = cond_attr->c_type; + if (cond == NULL) { + errno = EINVAL; + rval = -1; } else { - /* Default to a fast condition variable: */ - type = COND_TYPE_FAST; - } - - /* Process according to condition variable type: */ - switch (type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Nothing to do here. */ - break; + /* + * 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; + } else { + /* Default to a fast condition variable: */ + type = COND_TYPE_FAST; + } - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - _thread_seterrno(_thread_run, EINVAL); - rval = -1; - break; - } + /* 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: */ + errno = EINVAL; + rval = -1; + break; + } - /* Check for no errors: */ - if (rval == 0) { - /* Initialise the condition variable structure: */ - _thread_queue_init(&cond->c_queue); - cond->c_flags |= COND_FLAGS_INITED; - cond->c_type = type; + /* Check for no errors: */ + if (rval == 0) { + if ((pcond = (pthread_cond_t) malloc(sizeof(struct pthread_cond))) == NULL) { + errno = ENOMEM; + rval = -1; + } else { + /* + * Initialise the condition variable + * structure: + */ + _thread_queue_init(&pcond->c_queue); + pcond->c_flags |= COND_FLAGS_INITED; + pcond->c_type = type; + *cond = pcond; + } + } } /* Return the completion status: */ return (rval); @@ -85,26 +100,33 @@ pthread_cond_destroy(pthread_cond_t * cond) { int rval = 0; - /* Process according to condition variable type: */ - switch (cond->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Nothing to do here. */ - break; - - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - _thread_seterrno(_thread_run, EINVAL); + if (cond == NULL || *cond == NULL) { + errno = EINVAL; rval = -1; - break; - } + } else { + /* Process according to condition variable type: */ + switch ((*cond)->c_type) { + /* Fast condition variable: */ + case COND_TYPE_FAST: + /* Nothing to do here. */ + break; + + /* Trap invalid condition variable types: */ + default: + /* Return an invalid argument error: */ + errno = EINVAL; + rval = -1; + break; + } - /* Check for errors: */ - if (rval == 0) { - /* Destroy the contents of the condition structure: */ - _thread_queue_init(&cond->c_queue); - cond->c_flags = 0; + /* Check for errors: */ + if (rval == 0) { + /* Destroy the contents of the condition structure: */ + _thread_queue_init(&(*cond)->c_queue); + (*cond)->c_flags = 0; + free(*cond); + *cond = NULL; + } } /* Return the completion status: */ return (rval); @@ -116,40 +138,45 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex) int rval = 0; int status; - /* Block signals: */ - _thread_kern_sig_block(&status); + if (cond == NULL || *cond == NULL) { + errno = EINVAL; + rval = -1; + } else { + /* Block signals: */ + _thread_kern_sig_block(&status); - /* Process according to condition variable type: */ - switch (cond->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Queue the running thread for the condition variable: */ - _thread_queue_enq(&cond->c_queue, _thread_run); + /* Process according to condition variable type: */ + switch ((*cond)->c_type) { + /* Fast condition variable: */ + case COND_TYPE_FAST: + /* Queue the running thread for the condition variable: */ + _thread_queue_enq(&(*cond)->c_queue, _thread_run); - /* Unlock the mutex: */ - pthread_mutex_unlock(mutex); + /* Unlock the mutex: */ + pthread_mutex_unlock(mutex); - /* Schedule the next thread: */ - _thread_kern_sched_state(PS_COND_WAIT, __FILE__, __LINE__); + /* Schedule the next thread: */ + _thread_kern_sched_state(PS_COND_WAIT, __FILE__, __LINE__); - /* Block signals: */ - _thread_kern_sig_block(NULL); + /* Block signals: */ + _thread_kern_sig_block(NULL); - /* Lock the mutex: */ - rval = pthread_mutex_lock(mutex); - break; + /* Lock the mutex: */ + rval = pthread_mutex_lock(mutex); + break; + + /* Trap invalid condition variable types: */ + default: + /* Return an invalid argument error: */ + errno = EINVAL; + rval = -1; + break; + } - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - _thread_seterrno(_thread_run, EINVAL); - rval = -1; - break; + /* Unblock signals: */ + _thread_kern_sig_unblock(status); } - /* Unblock signals: */ - _thread_kern_sig_unblock(status); - /* Return the completion status: */ return (rval); } @@ -161,60 +188,70 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, int rval = 0; int status; - /* Block signals: */ - _thread_kern_sig_block(&status); - - /* Process according to condition variable type: */ - switch (cond->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Set the wakeup time: */ - _thread_run->wakeup_time.ts_sec = abstime->ts_sec; - _thread_run->wakeup_time.ts_nsec = abstime->ts_nsec; - - /* Reset the timeout flag: */ - _thread_run->timeout = 0; - - /* Queue the running thread for the condition variable: */ - _thread_queue_enq(&cond->c_queue, _thread_run); - - /* Unlock the mutex: */ - if ((rval = pthread_mutex_unlock(mutex)) != 0) { - /* - * Cannot unlock the mutex, so remove the running - * thread from the condition variable queue: - */ - _thread_queue_deq(&cond->c_queue); - } else { - /* Schedule the next thread: */ - _thread_kern_sched_state(PS_COND_WAIT, __FILE__, __LINE__); - - /* Block signals: */ - _thread_kern_sig_block(NULL); + if (cond == NULL || *cond == NULL) { + errno = EINVAL; + rval = -1; + } else { + /* Block signals: */ + _thread_kern_sig_block(&status); + + /* Process according to condition variable type: */ + switch ((*cond)->c_type) { + /* Fast condition variable: */ + case COND_TYPE_FAST: + /* Set the wakeup time: */ +#if defined(__FreeBSD__) + _thread_run->wakeup_time.ts_sec = abstime->ts_sec; + _thread_run->wakeup_time.ts_nsec = abstime->ts_nsec; +#else + _thread_run->wakeup_time.tv_sec = abstime->tv_sec; + _thread_run->wakeup_time.tv_nsec = abstime->tv_nsec; +#endif - /* Lock the mutex: */ - if ((rval = pthread_mutex_lock(mutex)) != 0) { - } - /* Check if the wait timed out: */ - else if (_thread_run->timeout) { - /* Return a timeout error: */ - _thread_seterrno(_thread_run, EAGAIN); - rval = -1; + /* Reset the timeout flag: */ + _thread_run->timeout = 0; + + /* Queue the running thread for the condition variable: */ + _thread_queue_enq(&(*cond)->c_queue, _thread_run); + + /* Unlock the mutex: */ + if ((rval = pthread_mutex_unlock(mutex)) != 0) { + /* + * Cannot unlock the mutex, so remove the running + * thread from the condition variable queue: + */ + _thread_queue_deq(&(*cond)->c_queue); + } else { + /* Schedule the next thread: */ + _thread_kern_sched_state(PS_COND_WAIT, __FILE__, __LINE__); + + /* Block signals: */ + _thread_kern_sig_block(NULL); + + /* Lock the mutex: */ + if ((rval = pthread_mutex_lock(mutex)) != 0) { + } + /* Check if the wait timed out: */ + else if (_thread_run->timeout) { + /* Return a timeout error: */ + errno = EAGAIN; + rval = -1; + } } + break; + + /* Trap invalid condition variable types: */ + default: + /* Return an invalid argument error: */ + errno = EINVAL; + rval = -1; + break; } - break; - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - _thread_seterrno(_thread_run, EINVAL); - rval = -1; - break; + /* Unblock signals: */ + _thread_kern_sig_unblock(status); } - /* Unblock signals: */ - _thread_kern_sig_unblock(status); - /* Return the completion status: */ return (rval); } @@ -226,31 +263,36 @@ pthread_cond_signal(pthread_cond_t * cond) int status; pthread_t pthread; - /* Block signals: */ - _thread_kern_sig_block(&status); - - /* Process according to condition variable type: */ - switch (cond->c_type) { - /* Fast condition variable: */ - case COND_TYPE_FAST: - /* Bring the next thread off the condition queue: */ - if ((pthread = _thread_queue_deq(&cond->c_queue)) != NULL) { - /* Allow the thread to run: */ - pthread->state = PS_RUNNING; + if (cond == NULL || *cond == NULL) { + errno = EINVAL; + rval = -1; + } else { + /* Block signals: */ + _thread_kern_sig_block(&status); + + /* Process according to condition variable type: */ + switch ((*cond)->c_type) { + /* Fast condition variable: */ + case COND_TYPE_FAST: + /* Bring the next thread off the condition queue: */ + if ((pthread = _thread_queue_deq(&(*cond)->c_queue)) != NULL) { + /* Allow the thread to run: */ + pthread->state = PS_RUNNING; + } + break; + + /* Trap invalid condition variable types: */ + default: + /* Return an invalid argument error: */ + errno = EINVAL; + rval = -1; + break; } - break; - /* Trap invalid condition variable types: */ - default: - /* Return an invalid argument error: */ - _thread_seterrno(_thread_run, EINVAL); - rval = -1; - break; + /* Unblock signals: */ + _thread_kern_sig_unblock(status); } - /* Unblock signals: */ - _thread_kern_sig_unblock(status); - /* Return the completion status: */ return (rval); } @@ -266,11 +308,11 @@ pthread_cond_broadcast(pthread_cond_t * cond) _thread_kern_sig_block(&status); /* Process according to condition variable type: */ - switch (cond->c_type) { + switch ((*cond)->c_type) { /* Fast condition variable: */ case COND_TYPE_FAST: /* Enter a loop to bring all threads off the condition queue: */ - while ((pthread = _thread_queue_deq(&cond->c_queue)) != NULL) { + while ((pthread = _thread_queue_deq(&(*cond)->c_queue)) != NULL) { /* Allow the thread to run: */ pthread->state = PS_RUNNING; } @@ -279,7 +321,7 @@ pthread_cond_broadcast(pthread_cond_t * cond) /* Trap invalid condition variable types: */ default: /* Return an invalid argument error: */ - _thread_seterrno(_thread_run, EINVAL); + errno = EINVAL; rval = -1; break; } |