123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- #include <pthread.h>
- int pthread_rwlockattr_init (pthread_rwlockattr_t * attr)
- {
- if (!attr) return EINVAL;
- *attr = PTHREAD_PROCESS_PRIVATE;
- return 0;
- }
- RTM_EXPORT(pthread_rwlockattr_init);
- int pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr)
- {
- if (!attr) return EINVAL;
- return 0;
- }
- RTM_EXPORT(pthread_rwlockattr_destroy);
- int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, int *pshared)
- {
- if (!attr || !pshared) return EINVAL;
- *pshared = PTHREAD_PROCESS_PRIVATE;
- return 0;
- }
- RTM_EXPORT(pthread_rwlockattr_getpshared);
- int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, int pshared)
- {
- if (!attr || pshared != PTHREAD_PROCESS_PRIVATE) return EINVAL;
- return 0;
- }
- RTM_EXPORT(pthread_rwlockattr_setpshared);
- int pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t * attr)
- {
- if (!rwlock) return EINVAL;
- rwlock->attr = PTHREAD_PROCESS_PRIVATE;
- pthread_mutex_init(&(rwlock->rw_mutex), NULL);
- pthread_cond_init(&(rwlock->rw_condreaders), NULL);
- pthread_cond_init(&(rwlock->rw_condwriters), NULL);
-
- rwlock->rw_nwaitwriters = 0;
- rwlock->rw_nwaitreaders = 0;
- rwlock->rw_refcount = 0;
- return 0;
- }
- RTM_EXPORT(pthread_rwlock_init);
- int pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
- {
- int result;
- if (!rwlock) return EINVAL;
- if (rwlock->attr == -1) return 0; /* rwlock is not initialized */
- if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
- return(result);
- if (rwlock->rw_refcount != 0 ||
- rwlock->rw_nwaitreaders != 0 || rwlock->rw_nwaitwriters != 0)
- {
- result = EBUSY;
- return(EBUSY);
- }
- else
- {
- /* check whether busy */
- result = rt_sem_trytake(&(rwlock->rw_condreaders.sem));
- if (result == RT_EOK)
- {
- result = rt_sem_trytake(&(rwlock->rw_condwriters.sem));
- if (result == RT_EOK)
- {
- rt_sem_release(&(rwlock->rw_condreaders.sem));
- rt_sem_release(&(rwlock->rw_condwriters.sem));
- pthread_cond_destroy(&rwlock->rw_condreaders);
- pthread_cond_destroy(&rwlock->rw_condwriters);
- }
- else
- {
- rt_sem_release(&(rwlock->rw_condreaders.sem));
- result = EBUSY;
- }
- }
- else result = EBUSY;
- }
- pthread_mutex_unlock(&rwlock->rw_mutex);
- if (result == 0) pthread_mutex_destroy(&rwlock->rw_mutex);
-
- return result;
- }
- RTM_EXPORT(pthread_rwlock_destroy);
- int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
- {
- int result;
- if (!rwlock) return EINVAL;
- if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
- if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
- return(result);
- /* give preference to waiting writers */
- while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
- {
- rwlock->rw_nwaitreaders++;
- result = pthread_cond_wait(&rwlock->rw_condreaders, &rwlock->rw_mutex);
- rwlock->rw_nwaitreaders--;
- if (result != 0)
- break;
- }
- /* another reader has a read lock */
- if (result == 0) rwlock->rw_refcount++;
- pthread_mutex_unlock(&rwlock->rw_mutex);
- return (result);
- }
- RTM_EXPORT(pthread_rwlock_rdlock);
- int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
- {
- int result;
- if (!rwlock) return EINVAL;
- if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
- if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
- return(result);
- if (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
- result = EBUSY; /* held by a writer or waiting writers */
- else
- rwlock->rw_refcount++; /* increment count of reader locks */
- pthread_mutex_unlock(&rwlock->rw_mutex);
- return(result);
- }
- RTM_EXPORT(pthread_rwlock_tryrdlock);
- int pthread_rwlock_timedrdlock (pthread_rwlock_t * rwlock, const struct timespec *abstime)
- {
- int result;
- if (!rwlock) return EINVAL;
- if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
- if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
- return(result);
- /* give preference to waiting writers */
- while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0)
- {
- rwlock->rw_nwaitreaders++;
- result = pthread_cond_timedwait(&rwlock->rw_condreaders, &rwlock->rw_mutex, abstime);
- rwlock->rw_nwaitreaders--;
- if (result != 0)
- break;
- }
- /* another reader has a read lock */
- if (result == 0) rwlock->rw_refcount++;
- pthread_mutex_unlock(&rwlock->rw_mutex);
- return (result);
- }
- RTM_EXPORT(pthread_rwlock_timedrdlock);
- int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, const struct timespec *abstime)
- {
- int result;
- if (!rwlock) return EINVAL;
- if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
- if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
- return(result);
- while (rwlock->rw_refcount != 0)
- {
- rwlock->rw_nwaitwriters++;
- result = pthread_cond_timedwait(&rwlock->rw_condwriters, &rwlock->rw_mutex, abstime);
- rwlock->rw_nwaitwriters--;
-
- if (result != 0) break;
- }
- if (result == 0) rwlock->rw_refcount = -1;
- pthread_mutex_unlock(&rwlock->rw_mutex);
- return(result);
- }
- RTM_EXPORT(pthread_rwlock_timedwrlock);
- int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
- {
- int result;
- if (!rwlock) return EINVAL;
- if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
- if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
- return(result);
- if (rwlock->rw_refcount != 0)
- result = EBUSY; /* held by either writer or reader(s) */
- else
- rwlock->rw_refcount = -1; /* available, indicate a writer has it */
- pthread_mutex_unlock(&rwlock->rw_mutex);
- return(result);
- }
- RTM_EXPORT(pthread_rwlock_trywrlock);
- int pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
- {
- int result;
- if (!rwlock) return EINVAL;
- if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
- if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
- return(result);
- if (rwlock->rw_refcount > 0)
- rwlock->rw_refcount--; /* releasing a reader */
- else if (rwlock->rw_refcount == -1)
- rwlock->rw_refcount = 0; /* releasing a reader */
- /* give preference to waiting writers over waiting readers */
- if (rwlock->rw_nwaitwriters > 0)
- {
- if (rwlock->rw_refcount == 0)
- result = pthread_cond_signal(&rwlock->rw_condwriters);
- }
- else if (rwlock->rw_nwaitreaders > 0)
- {
- result = pthread_cond_broadcast(&rwlock->rw_condreaders);
- }
- pthread_mutex_unlock(&rwlock->rw_mutex);
- return(result);
- }
- RTM_EXPORT(pthread_rwlock_unlock);
- int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
- {
- int result;
- if (!rwlock) return EINVAL;
- if (rwlock->attr == -1) pthread_rwlock_init(rwlock, NULL);
- if ( (result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0)
- return(result);
- while (rwlock->rw_refcount != 0)
- {
- rwlock->rw_nwaitwriters++;
- result = pthread_cond_wait(&rwlock->rw_condwriters, &rwlock->rw_mutex);
- rwlock->rw_nwaitwriters--;
-
- if (result != 0) break;
- }
- if (result == 0) rwlock->rw_refcount = -1;
- pthread_mutex_unlock(&rwlock->rw_mutex);
- return(result);
- }
- RTM_EXPORT(pthread_rwlock_wrlock);
|