diff options
Diffstat (limited to 'lib/glthread/lock.h')
-rw-r--r-- | lib/glthread/lock.h | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h index cf3d0d9..9db95c6 100644 --- a/lib/glthread/lock.h +++ b/lib/glthread/lock.h @@ -1,5 +1,5 @@ /* Locking in multithreaded situations. - Copyright (C) 2005-2015 Free Software Foundation, Inc. + Copyright (C) 2005-2017 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -176,7 +176,7 @@ typedef pthread_mutex_t gl_lock_t; /* ------------------------- gl_rwlock_t datatype ------------------------- */ -# if HAVE_PTHREAD_RWLOCK +# if HAVE_PTHREAD_RWLOCK && (HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER || (__GNU_LIBRARY__ > 1)) # ifdef PTHREAD_RWLOCK_INITIALIZER @@ -185,10 +185,18 @@ typedef pthread_rwlock_t gl_rwlock_t; STORAGECLASS pthread_rwlock_t NAME; # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer; -# define gl_rwlock_initializer \ - PTHREAD_RWLOCK_INITIALIZER -# define glthread_rwlock_init(LOCK) \ - (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0) +# if HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER +# define gl_rwlock_initializer \ + PTHREAD_RWLOCK_INITIALIZER +# define glthread_rwlock_init(LOCK) \ + (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0) +# else /* glibc with bug https://sourceware.org/bugzilla/show_bug.cgi?id=13701 */ +# define gl_rwlock_initializer \ + PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP +# define glthread_rwlock_init(LOCK) \ + (pthread_in_use () ? glthread_rwlock_init_for_glibc (LOCK) : 0) +extern int glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock); +# endif # define glthread_rwlock_rdlock(LOCK) \ (pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0) # define glthread_rwlock_wrlock(LOCK) \ @@ -427,6 +435,9 @@ typedef pth_mutex_t gl_lock_t; /* ------------------------- gl_rwlock_t datatype ------------------------- */ +/* Pth pth_rwlock_acquire always prefers readers. No autoconf test so far. */ +# if HAVE_PTH_RWLOCK_ACQUIRE_PREFER_WRITER + typedef pth_rwlock_t gl_rwlock_t; # define gl_rwlock_define(STORAGECLASS, NAME) \ STORAGECLASS pth_rwlock_t NAME; @@ -445,6 +456,42 @@ typedef pth_rwlock_t gl_rwlock_t; # define glthread_rwlock_destroy(LOCK) \ ((void)(LOCK), 0) +# else + +typedef struct + { + int initialized; + pth_mutex_t lock; /* protects the remaining fields */ + pth_cond_t waiting_readers; /* waiting readers */ + pth_cond_t waiting_writers; /* waiting writers */ + unsigned int waiting_writers_count; /* number of waiting writers */ + int runcount; /* number of readers running, or -1 when a writer runs */ + } + gl_rwlock_t; +# define gl_rwlock_define(STORAGECLASS, NAME) \ + STORAGECLASS gl_rwlock_t NAME; +# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ + STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; +# define gl_rwlock_initializer \ + { 0 } +# define glthread_rwlock_init(LOCK) \ + (pth_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0) +# define glthread_rwlock_rdlock(LOCK) \ + (pth_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_wrlock(LOCK) \ + (pth_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_unlock(LOCK) \ + (pth_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_destroy(LOCK) \ + (pth_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0) +extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock); + +# endif + /* --------------------- gl_recursive_lock_t datatype --------------------- */ /* In Pth, mutexes are recursive by default. */ |