105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Locking in multithreaded situations. 205436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 2005-2012 Free Software Foundation, Inc. 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 405436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is free software; you can redistribute it and/or modify 505436638acc7c010349a69c3395f1a57c642dc62Ying Wang it under the terms of the GNU General Public License as published by 605436638acc7c010349a69c3395f1a57c642dc62Ying Wang the Free Software Foundation; either version 3, or (at your option) 705436638acc7c010349a69c3395f1a57c642dc62Ying Wang any later version. 805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 905436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is distributed in the hope that it will be useful, 1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang but WITHOUT ANY WARRANTY; without even the implied warranty of 1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang GNU General Public License for more details. 1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang You should have received a copy of the GNU General Public License 1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang along with this program; if not, see <http://www.gnu.org/licenses/>. */ 1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Written by Bruno Haible <bruno@clisp.org>, 2005. 1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, 1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang gthr-win32.h. */ 2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* This file contains locking primitives for use with a given thread library. 2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang It does not contain primitives for creating threads or for other 2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang synchronization primitives. 2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang Normal (non-recursive) locks: 2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang Type: gl_lock_t 2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang Declaration: gl_lock_define(extern, name) 2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang Initializer: gl_lock_define_initialized(, name) 2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang Initialization: gl_lock_init (name); 3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang Taking the lock: gl_lock_lock (name); 3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang Releasing the lock: gl_lock_unlock (name); 3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang De-initialization: gl_lock_destroy (name); 3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Equivalent functions with control of error handling: 3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang Initialization: err = glthread_lock_init (&name); 3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang Taking the lock: err = glthread_lock_lock (&name); 3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang Releasing the lock: err = glthread_lock_unlock (&name); 3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang De-initialization: err = glthread_lock_destroy (&name); 3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang Read-Write (non-recursive) locks: 4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang Type: gl_rwlock_t 4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang Declaration: gl_rwlock_define(extern, name) 4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang Initializer: gl_rwlock_define_initialized(, name) 4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Initialization: gl_rwlock_init (name); 4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang Taking the lock: gl_rwlock_rdlock (name); 4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_rwlock_wrlock (name); 4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang Releasing the lock: gl_rwlock_unlock (name); 4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang De-initialization: gl_rwlock_destroy (name); 4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang Equivalent functions with control of error handling: 4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang Initialization: err = glthread_rwlock_init (&name); 5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang Taking the lock: err = glthread_rwlock_rdlock (&name); 5105436638acc7c010349a69c3395f1a57c642dc62Ying Wang err = glthread_rwlock_wrlock (&name); 5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang Releasing the lock: err = glthread_rwlock_unlock (&name); 5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang De-initialization: err = glthread_rwlock_destroy (&name); 5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang Recursive locks: 5605436638acc7c010349a69c3395f1a57c642dc62Ying Wang Type: gl_recursive_lock_t 5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang Declaration: gl_recursive_lock_define(extern, name) 5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang Initializer: gl_recursive_lock_define_initialized(, name) 5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang Initialization: gl_recursive_lock_init (name); 6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang Taking the lock: gl_recursive_lock_lock (name); 6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang Releasing the lock: gl_recursive_lock_unlock (name); 6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang De-initialization: gl_recursive_lock_destroy (name); 6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Equivalent functions with control of error handling: 6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang Initialization: err = glthread_recursive_lock_init (&name); 6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang Taking the lock: err = glthread_recursive_lock_lock (&name); 6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang Releasing the lock: err = glthread_recursive_lock_unlock (&name); 6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang De-initialization: err = glthread_recursive_lock_destroy (&name); 6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang Once-only execution: 7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang Type: gl_once_t 7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang Initializer: gl_once_define(extern, name) 7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang Execution: gl_once (name, initfunction); 7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Equivalent functions with control of error handling: 7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang Execution: err = glthread_once (&name, initfunction); 7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang*/ 7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifndef _LOCK_H 7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define _LOCK_H 8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <errno.h> 8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <stdlib.h> 8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */ 8505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if USE_POSIX_THREADS 8705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use the POSIX threads library. */ 8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 9005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <pthread.h> 9105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 9205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus 9305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern "C" { 9405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 9605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if PTHREAD_IN_USE_DETECTION_HARD 9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The pthread_in_use() detection needs to be done at runtime. */ 9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define pthread_in_use() \ 10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_in_use () 10105436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_in_use (void); 10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 10405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if USE_POSIX_THREADS_WEAK 10605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use weak references to the POSIX threads library. */ 10805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Weak references avoid dragging in external libraries if the other parts 11005436638acc7c010349a69c3395f1a57c642dc62Ying Wang of the program don't use them. Here we use them, because we don't want 11105436638acc7c010349a69c3395f1a57c642dc62Ying Wang every program that uses libintl to depend on libpthread. This assumes 11205436638acc7c010349a69c3395f1a57c642dc62Ying Wang that libpthread would not be loaded after libintl; i.e. if libintl is 11305436638acc7c010349a69c3395f1a57c642dc62Ying Wang loaded first, by an executable that does not depend on libpthread, and 11405436638acc7c010349a69c3395f1a57c642dc62Ying Wang then a module is dynamically loaded that depends on libpthread, libintl 11505436638acc7c010349a69c3395f1a57c642dc62Ying Wang will not be multithread-safe. */ 11605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 11705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The way to test at runtime whether libpthread is present is to test 11805436638acc7c010349a69c3395f1a57c642dc62Ying Wang whether a function pointer's value, such as &pthread_mutex_init, is 11905436638acc7c010349a69c3395f1a57c642dc62Ying Wang non-NULL. However, some versions of GCC have a bug through which, in 12005436638acc7c010349a69c3395f1a57c642dc62Ying Wang PIC mode, &foo != NULL always evaluates to true if there is a direct 12105436638acc7c010349a69c3395f1a57c642dc62Ying Wang call to foo(...) in the same function. To avoid this, we test the 12205436638acc7c010349a69c3395f1a57c642dc62Ying Wang address of a function in libpthread that we don't use. */ 12305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 12405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_mutex_init 12505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_mutex_lock 12605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_mutex_unlock 12705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_mutex_destroy 12805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_rwlock_init 12905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_rwlock_rdlock 13005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_rwlock_wrlock 13105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_rwlock_unlock 13205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_rwlock_destroy 13305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_once 13405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_cond_init 13505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_cond_wait 13605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_cond_signal 13705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_cond_broadcast 13805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_cond_destroy 13905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_mutexattr_init 14005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_mutexattr_settype 14105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_mutexattr_destroy 14205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifndef pthread_self 14305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_self 14405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 14505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 14605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if !PTHREAD_IN_USE_DETECTION_HARD 14705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pthread_cancel 14805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define pthread_in_use() (pthread_cancel != NULL) 14905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 15105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else 15205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 15305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if !PTHREAD_IN_USE_DETECTION_HARD 15405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define pthread_in_use() 1 15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 15805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 15905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */ 16005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 16105436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pthread_mutex_t gl_lock_t; 16205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define(STORAGECLASS, NAME) \ 16305436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pthread_mutex_t NAME; 16405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define_initialized(STORAGECLASS, NAME) \ 16505436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer; 16605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_initializer \ 16705436638acc7c010349a69c3395f1a57c642dc62Ying Wang PTHREAD_MUTEX_INITIALIZER 16805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_init(LOCK) \ 16905436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_mutex_init (LOCK, NULL) : 0) 17005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_lock(LOCK) \ 17105436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0) 17205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_unlock(LOCK) \ 17305436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0) 17405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_destroy(LOCK) \ 17505436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0) 17605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 17705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */ 17805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 17905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if HAVE_PTHREAD_RWLOCK 18005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 18105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef PTHREAD_RWLOCK_INITIALIZER 18205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 18305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pthread_rwlock_t gl_rwlock_t; 18405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME) \ 18505436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pthread_rwlock_t NAME; 18605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ 18705436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer; 18805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_initializer \ 18905436638acc7c010349a69c3395f1a57c642dc62Ying Wang PTHREAD_RWLOCK_INITIALIZER 19005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(LOCK) \ 19105436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0) 19205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(LOCK) \ 19305436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0) 19405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(LOCK) \ 19505436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_rwlock_wrlock (LOCK) : 0) 19605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(LOCK) \ 19705436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_rwlock_unlock (LOCK) : 0) 19805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(LOCK) \ 19905436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_rwlock_destroy (LOCK) : 0) 20005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 20105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else 20205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 20305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 20405436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 20505436638acc7c010349a69c3395f1a57c642dc62Ying Wang int initialized; 20605436638acc7c010349a69c3395f1a57c642dc62Ying Wang pthread_mutex_t guard; /* protects the initialization */ 20705436638acc7c010349a69c3395f1a57c642dc62Ying Wang pthread_rwlock_t rwlock; /* read-write lock */ 20805436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 20905436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_rwlock_t; 21005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME) \ 21105436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_rwlock_t NAME; 21205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ 21305436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; 21405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_initializer \ 21505436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 0, PTHREAD_MUTEX_INITIALIZER } 21605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(LOCK) \ 21705436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0) 21805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(LOCK) \ 21905436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0) 22005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(LOCK) \ 22105436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0) 22205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(LOCK) \ 22305436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0) 22405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(LOCK) \ 22505436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0) 22605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock); 22705436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock); 22805436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock); 22905436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock); 23005436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock); 23105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 23205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 23305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 23405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else 23505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 23605436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 23705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 23805436638acc7c010349a69c3395f1a57c642dc62Ying Wang pthread_mutex_t lock; /* protects the remaining fields */ 23905436638acc7c010349a69c3395f1a57c642dc62Ying Wang pthread_cond_t waiting_readers; /* waiting readers */ 24005436638acc7c010349a69c3395f1a57c642dc62Ying Wang pthread_cond_t waiting_writers; /* waiting writers */ 24105436638acc7c010349a69c3395f1a57c642dc62Ying Wang unsigned int waiting_writers_count; /* number of waiting writers */ 24205436638acc7c010349a69c3395f1a57c642dc62Ying Wang int runcount; /* number of readers running, or -1 when a writer runs */ 24305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 24405436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_rwlock_t; 24505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME) \ 24605436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_rwlock_t NAME; 24705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ 24805436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; 24905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_initializer \ 25005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 } 25105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(LOCK) \ 25205436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0) 25305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(LOCK) \ 25405436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0) 25505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(LOCK) \ 25605436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0) 25705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(LOCK) \ 25805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0) 25905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(LOCK) \ 26005436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0) 26105436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock); 26205436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock); 26305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock); 26405436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock); 26505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock); 26605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 26705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 26805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 26905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */ 27005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 27105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if HAVE_PTHREAD_MUTEX_RECURSIVE 27205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 27305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 27405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 27505436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pthread_mutex_t gl_recursive_lock_t; 27605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define(STORAGECLASS, NAME) \ 27705436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pthread_mutex_t NAME; 27805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ 27905436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer; 28005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER 28105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_initializer \ 28205436638acc7c010349a69c3395f1a57c642dc62Ying Wang PTHREAD_RECURSIVE_MUTEX_INITIALIZER 28305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else 28405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_initializer \ 28505436638acc7c010349a69c3395f1a57c642dc62Ying Wang PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 28605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 28705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_init(LOCK) \ 28805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0) 28905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_lock(LOCK) \ 29005436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0) 29105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_unlock(LOCK) \ 29205436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0) 29305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_destroy(LOCK) \ 29405436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0) 29505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock); 29605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 29705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else 29805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 29905436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 30005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 30105436638acc7c010349a69c3395f1a57c642dc62Ying Wang pthread_mutex_t recmutex; /* recursive mutex */ 30205436638acc7c010349a69c3395f1a57c642dc62Ying Wang pthread_mutex_t guard; /* protects the initialization */ 30305436638acc7c010349a69c3395f1a57c642dc62Ying Wang int initialized; 30405436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 30505436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_recursive_lock_t; 30605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define(STORAGECLASS, NAME) \ 30705436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_recursive_lock_t NAME; 30805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ 30905436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; 31005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_initializer \ 31105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 } 31205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_init(LOCK) \ 31305436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0) 31405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_lock(LOCK) \ 31505436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0) 31605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_unlock(LOCK) \ 31705436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0) 31805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_destroy(LOCK) \ 31905436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0) 32005436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock); 32105436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock); 32205436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock); 32305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock); 32405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 32505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 32605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 32705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else 32805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 32905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Old versions of POSIX threads on Solaris did not have recursive locks. 33005436638acc7c010349a69c3395f1a57c642dc62Ying Wang We have to implement them ourselves. */ 33105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 33205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 33305436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 33405436638acc7c010349a69c3395f1a57c642dc62Ying Wang pthread_mutex_t mutex; 33505436638acc7c010349a69c3395f1a57c642dc62Ying Wang pthread_t owner; 33605436638acc7c010349a69c3395f1a57c642dc62Ying Wang unsigned long depth; 33705436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 33805436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_recursive_lock_t; 33905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define(STORAGECLASS, NAME) \ 34005436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_recursive_lock_t NAME; 34105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ 34205436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; 34305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_initializer \ 34405436638acc7c010349a69c3395f1a57c642dc62Ying Wang { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 } 34505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_init(LOCK) \ 34605436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0) 34705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_lock(LOCK) \ 34805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0) 34905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_unlock(LOCK) \ 35005436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0) 35105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_destroy(LOCK) \ 35205436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0) 35305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock); 35405436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock); 35505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock); 35605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock); 35705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 35805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 35905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 36005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */ 36105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 36205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pthread_once_t gl_once_t; 36305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_once_define(STORAGECLASS, NAME) \ 36405436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; 36505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ 36605436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pthread_in_use () \ 36705436638acc7c010349a69c3395f1a57c642dc62Ying Wang ? pthread_once (ONCE_CONTROL, INITFUNCTION) \ 36805436638acc7c010349a69c3395f1a57c642dc62Ying Wang : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) 36905436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_once_singlethreaded (pthread_once_t *once_control); 37005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 37105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus 37205436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 37305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 37405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 37505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 37605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 37705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */ 37805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 37905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if USE_PTH_THREADS 38005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 38105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use the GNU Pth threads library. */ 38205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 38305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <pth.h> 38405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 38505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus 38605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern "C" { 38705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 38805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 38905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if USE_PTH_THREADS_WEAK 39005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 39105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use weak references to the GNU Pth threads library. */ 39205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 39305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pth_mutex_init 39405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pth_mutex_acquire 39505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pth_mutex_release 39605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pth_rwlock_init 39705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pth_rwlock_acquire 39805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pth_rwlock_release 39905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pth_once 40005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 40105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak pth_cancel 40205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define pth_in_use() (pth_cancel != NULL) 40305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 40405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else 40505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 40605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define pth_in_use() 1 40705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 40805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 40905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 41005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */ 41105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 41205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pth_mutex_t gl_lock_t; 41305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define(STORAGECLASS, NAME) \ 41405436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pth_mutex_t NAME; 41505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define_initialized(STORAGECLASS, NAME) \ 41605436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pth_mutex_t NAME = gl_lock_initializer; 41705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_initializer \ 41805436638acc7c010349a69c3395f1a57c642dc62Ying Wang PTH_MUTEX_INIT 41905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_init(LOCK) \ 42005436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0) 42105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_lock(LOCK) \ 42205436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0) 42305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_unlock(LOCK) \ 42405436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0) 42505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_destroy(LOCK) \ 42605436638acc7c010349a69c3395f1a57c642dc62Ying Wang ((void)(LOCK), 0) 42705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 42805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */ 42905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 43005436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pth_rwlock_t gl_rwlock_t; 43105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME) \ 43205436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pth_rwlock_t NAME; 43305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ 43405436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer; 43505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_initializer \ 43605436638acc7c010349a69c3395f1a57c642dc62Ying Wang PTH_RWLOCK_INIT 43705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(LOCK) \ 43805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () && !pth_rwlock_init (LOCK) ? errno : 0) 43905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(LOCK) \ 44005436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RD, 0, NULL) ? errno : 0) 44105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(LOCK) \ 44205436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RW, 0, NULL) ? errno : 0) 44305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(LOCK) \ 44405436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () && !pth_rwlock_release (LOCK) ? errno : 0) 44505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(LOCK) \ 44605436638acc7c010349a69c3395f1a57c642dc62Ying Wang ((void)(LOCK), 0) 44705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 44805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */ 44905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 45005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* In Pth, mutexes are recursive by default. */ 45105436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pth_mutex_t gl_recursive_lock_t; 45205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define(STORAGECLASS, NAME) \ 45305436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pth_mutex_t NAME; 45405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ 45505436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer; 45605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_initializer \ 45705436638acc7c010349a69c3395f1a57c642dc62Ying Wang PTH_MUTEX_INIT 45805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_init(LOCK) \ 45905436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0) 46005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_lock(LOCK) \ 46105436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0) 46205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_unlock(LOCK) \ 46305436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0) 46405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_destroy(LOCK) \ 46505436638acc7c010349a69c3395f1a57c642dc62Ying Wang ((void)(LOCK), 0) 46605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 46705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */ 46805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 46905436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pth_once_t gl_once_t; 47005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_once_define(STORAGECLASS, NAME) \ 47105436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT; 47205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ 47305436638acc7c010349a69c3395f1a57c642dc62Ying Wang (pth_in_use () \ 47405436638acc7c010349a69c3395f1a57c642dc62Ying Wang ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \ 47505436638acc7c010349a69c3395f1a57c642dc62Ying Wang : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) 47605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void)); 47705436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_once_singlethreaded (pth_once_t *once_control); 47805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 47905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus 48005436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 48105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 48205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 48305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 48405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 48505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */ 48605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 48705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if USE_SOLARIS_THREADS 48805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 48905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use the old Solaris threads library. */ 49005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 49105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <thread.h> 49205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <synch.h> 49305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 49405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus 49505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern "C" { 49605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 49705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 49805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if USE_SOLARIS_THREADS_WEAK 49905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 50005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use weak references to the old Solaris threads library. */ 50105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 50205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak mutex_init 50305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak mutex_lock 50405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak mutex_unlock 50505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak mutex_destroy 50605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak rwlock_init 50705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak rw_rdlock 50805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak rw_wrlock 50905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak rw_unlock 51005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak rwlock_destroy 51105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak thr_self 51205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 51305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# pragma weak thr_suspend 51405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define thread_in_use() (thr_suspend != NULL) 51505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 51605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else 51705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 51805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define thread_in_use() 1 51905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 52005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 52105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 52205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */ 52305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 52405436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef mutex_t gl_lock_t; 52505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define(STORAGECLASS, NAME) \ 52605436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS mutex_t NAME; 52705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define_initialized(STORAGECLASS, NAME) \ 52805436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS mutex_t NAME = gl_lock_initializer; 52905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_initializer \ 53005436638acc7c010349a69c3395f1a57c642dc62Ying Wang DEFAULTMUTEX 53105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_init(LOCK) \ 53205436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? mutex_init (LOCK, USYNC_THREAD, NULL) : 0) 53305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_lock(LOCK) \ 53405436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? mutex_lock (LOCK) : 0) 53505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_unlock(LOCK) \ 53605436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? mutex_unlock (LOCK) : 0) 53705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_destroy(LOCK) \ 53805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? mutex_destroy (LOCK) : 0) 53905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 54005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */ 54105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 54205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef rwlock_t gl_rwlock_t; 54305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME) \ 54405436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS rwlock_t NAME; 54505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ 54605436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS rwlock_t NAME = gl_rwlock_initializer; 54705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_initializer \ 54805436638acc7c010349a69c3395f1a57c642dc62Ying Wang DEFAULTRWLOCK 54905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(LOCK) \ 55005436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? rwlock_init (LOCK, USYNC_THREAD, NULL) : 0) 55105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(LOCK) \ 55205436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? rw_rdlock (LOCK) : 0) 55305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(LOCK) \ 55405436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? rw_wrlock (LOCK) : 0) 55505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(LOCK) \ 55605436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? rw_unlock (LOCK) : 0) 55705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(LOCK) \ 55805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? rwlock_destroy (LOCK) : 0) 55905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 56005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */ 56105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 56205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Old Solaris threads did not have recursive locks. 56305436638acc7c010349a69c3395f1a57c642dc62Ying Wang We have to implement them ourselves. */ 56405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 56505436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 56605436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 56705436638acc7c010349a69c3395f1a57c642dc62Ying Wang mutex_t mutex; 56805436638acc7c010349a69c3395f1a57c642dc62Ying Wang thread_t owner; 56905436638acc7c010349a69c3395f1a57c642dc62Ying Wang unsigned long depth; 57005436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 57105436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_recursive_lock_t; 57205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define(STORAGECLASS, NAME) \ 57305436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_recursive_lock_t NAME; 57405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ 57505436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; 57605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_initializer \ 57705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { DEFAULTMUTEX, (thread_t) 0, 0 } 57805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_init(LOCK) \ 57905436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0) 58005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_lock(LOCK) \ 58105436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0) 58205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_unlock(LOCK) \ 58305436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0) 58405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_destroy(LOCK) \ 58505436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0) 58605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock); 58705436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock); 58805436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock); 58905436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock); 59005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 59105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */ 59205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 59305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 59405436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 59505436638acc7c010349a69c3395f1a57c642dc62Ying Wang volatile int inited; 59605436638acc7c010349a69c3395f1a57c642dc62Ying Wang mutex_t mutex; 59705436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 59805436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_once_t; 59905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_once_define(STORAGECLASS, NAME) \ 60005436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX }; 60105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ 60205436638acc7c010349a69c3395f1a57c642dc62Ying Wang (thread_in_use () \ 60305436638acc7c010349a69c3395f1a57c642dc62Ying Wang ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \ 60405436638acc7c010349a69c3395f1a57c642dc62Ying Wang : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) 60505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void)); 60605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_once_singlethreaded (gl_once_t *once_control); 60705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 60805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus 60905436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 61005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 61105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 61205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 61305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 61405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */ 61505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 61605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if USE_WINDOWS_THREADS 61705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 61805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define WIN32_LEAN_AND_MEAN /* avoid including junk */ 61905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <windows.h> 62005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 62105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus 62205436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern "C" { 62305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 62405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 62505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* We can use CRITICAL_SECTION directly, rather than the native Windows Event, 62605436638acc7c010349a69c3395f1a57c642dc62Ying Wang Mutex, Semaphore types, because 62705436638acc7c010349a69c3395f1a57c642dc62Ying Wang - we need only to synchronize inside a single process (address space), 62805436638acc7c010349a69c3395f1a57c642dc62Ying Wang not inter-process locking, 62905436638acc7c010349a69c3395f1a57c642dc62Ying Wang - we don't need to support trylock operations. (TryEnterCriticalSection 63005436638acc7c010349a69c3395f1a57c642dc62Ying Wang does not work on Windows 95/98/ME. Packages that need trylock usually 63105436638acc7c010349a69c3395f1a57c642dc62Ying Wang define their own mutex type.) */ 63205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 63305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* There is no way to statically initialize a CRITICAL_SECTION. It needs 63405436638acc7c010349a69c3395f1a57c642dc62Ying Wang to be done lazily, once only. For this we need spinlocks. */ 63505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 63605436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct { volatile int done; volatile long started; } gl_spinlock_t; 63705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 63805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */ 63905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 64005436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 64105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 64205436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_spinlock_t guard; /* protects the initialization */ 64305436638acc7c010349a69c3395f1a57c642dc62Ying Wang CRITICAL_SECTION lock; 64405436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 64505436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_lock_t; 64605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define(STORAGECLASS, NAME) \ 64705436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_lock_t NAME; 64805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define_initialized(STORAGECLASS, NAME) \ 64905436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_lock_t NAME = gl_lock_initializer; 65005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_initializer \ 65105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { { 0, -1 } } 65205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_init(LOCK) \ 65305436638acc7c010349a69c3395f1a57c642dc62Ying Wang (glthread_lock_init_func (LOCK), 0) 65405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_lock(LOCK) \ 65505436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_lock_lock_func (LOCK) 65605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_unlock(LOCK) \ 65705436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_lock_unlock_func (LOCK) 65805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_destroy(LOCK) \ 65905436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_lock_destroy_func (LOCK) 66005436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern void glthread_lock_init_func (gl_lock_t *lock); 66105436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_lock_lock_func (gl_lock_t *lock); 66205436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_lock_unlock_func (gl_lock_t *lock); 66305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_lock_destroy_func (gl_lock_t *lock); 66405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 66505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */ 66605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 66705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* It is impossible to implement read-write locks using plain locks, without 66805436638acc7c010349a69c3395f1a57c642dc62Ying Wang introducing an extra thread dedicated to managing read-write locks. 66905436638acc7c010349a69c3395f1a57c642dc62Ying Wang Therefore here we need to use the low-level Event type. */ 67005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 67105436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 67205436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 67305436638acc7c010349a69c3395f1a57c642dc62Ying Wang HANDLE *array; /* array of waiting threads, each represented by an event */ 67405436638acc7c010349a69c3395f1a57c642dc62Ying Wang unsigned int count; /* number of waiting threads */ 67505436638acc7c010349a69c3395f1a57c642dc62Ying Wang unsigned int alloc; /* length of allocated array */ 67605436638acc7c010349a69c3395f1a57c642dc62Ying Wang unsigned int offset; /* index of first waiting thread in array */ 67705436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 67805436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_carray_waitqueue_t; 67905436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 68005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 68105436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_spinlock_t guard; /* protects the initialization */ 68205436638acc7c010349a69c3395f1a57c642dc62Ying Wang CRITICAL_SECTION lock; /* protects the remaining fields */ 68305436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_carray_waitqueue_t waiting_readers; /* waiting readers */ 68405436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_carray_waitqueue_t waiting_writers; /* waiting writers */ 68505436638acc7c010349a69c3395f1a57c642dc62Ying Wang int runcount; /* number of readers running, or -1 when a writer runs */ 68605436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 68705436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_rwlock_t; 68805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME) \ 68905436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_rwlock_t NAME; 69005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ 69105436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; 69205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_initializer \ 69305436638acc7c010349a69c3395f1a57c642dc62Ying Wang { { 0, -1 } } 69405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(LOCK) \ 69505436638acc7c010349a69c3395f1a57c642dc62Ying Wang (glthread_rwlock_init_func (LOCK), 0) 69605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(LOCK) \ 69705436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_rwlock_rdlock_func (LOCK) 69805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(LOCK) \ 69905436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_rwlock_wrlock_func (LOCK) 70005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(LOCK) \ 70105436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_rwlock_unlock_func (LOCK) 70205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(LOCK) \ 70305436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_rwlock_destroy_func (LOCK) 70405436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern void glthread_rwlock_init_func (gl_rwlock_t *lock); 70505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_rdlock_func (gl_rwlock_t *lock); 70605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_wrlock_func (gl_rwlock_t *lock); 70705436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_unlock_func (gl_rwlock_t *lock); 70805436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_destroy_func (gl_rwlock_t *lock); 70905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 71005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */ 71105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 71205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The native Windows documentation says that CRITICAL_SECTION already 71305436638acc7c010349a69c3395f1a57c642dc62Ying Wang implements a recursive lock. But we need not rely on it: It's easy to 71405436638acc7c010349a69c3395f1a57c642dc62Ying Wang implement a recursive lock without this assumption. */ 71505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 71605436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 71705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 71805436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_spinlock_t guard; /* protects the initialization */ 71905436638acc7c010349a69c3395f1a57c642dc62Ying Wang DWORD owner; 72005436638acc7c010349a69c3395f1a57c642dc62Ying Wang unsigned long depth; 72105436638acc7c010349a69c3395f1a57c642dc62Ying Wang CRITICAL_SECTION lock; 72205436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 72305436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_recursive_lock_t; 72405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define(STORAGECLASS, NAME) \ 72505436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_recursive_lock_t NAME; 72605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ 72705436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; 72805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_initializer \ 72905436638acc7c010349a69c3395f1a57c642dc62Ying Wang { { 0, -1 }, 0, 0 } 73005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_init(LOCK) \ 73105436638acc7c010349a69c3395f1a57c642dc62Ying Wang (glthread_recursive_lock_init_func (LOCK), 0) 73205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_lock(LOCK) \ 73305436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_recursive_lock_lock_func (LOCK) 73405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_unlock(LOCK) \ 73505436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_recursive_lock_unlock_func (LOCK) 73605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_destroy(LOCK) \ 73705436638acc7c010349a69c3395f1a57c642dc62Ying Wang glthread_recursive_lock_destroy_func (LOCK) 73805436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern void glthread_recursive_lock_init_func (gl_recursive_lock_t *lock); 73905436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock); 74005436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock); 74105436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock); 74205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 74305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */ 74405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 74505436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 74605436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 74705436638acc7c010349a69c3395f1a57c642dc62Ying Wang volatile int inited; 74805436638acc7c010349a69c3395f1a57c642dc62Ying Wang volatile long started; 74905436638acc7c010349a69c3395f1a57c642dc62Ying Wang CRITICAL_SECTION lock; 75005436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 75105436638acc7c010349a69c3395f1a57c642dc62Ying Wang gl_once_t; 75205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_once_define(STORAGECLASS, NAME) \ 75305436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_once_t NAME = { -1, -1 }; 75405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ 75505436638acc7c010349a69c3395f1a57c642dc62Ying Wang (glthread_once_func (ONCE_CONTROL, INITFUNCTION), 0) 75605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern void glthread_once_func (gl_once_t *once_control, void (*initfunction) (void)); 75705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 75805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus 75905436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 76005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 76105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 76205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 76305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 76405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */ 76505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 76605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WINDOWS_THREADS) 76705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 76805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Provide dummy implementation if threads are not supported. */ 76905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 77005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */ 77105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 77205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef int gl_lock_t; 77305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define(STORAGECLASS, NAME) 77405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define_initialized(STORAGECLASS, NAME) 77505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_init(NAME) 0 77605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_lock(NAME) 0 77705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_unlock(NAME) 0 77805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_destroy(NAME) 0 77905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 78005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */ 78105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 78205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef int gl_rwlock_t; 78305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME) 78405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME) 78505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(NAME) 0 78605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(NAME) 0 78705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(NAME) 0 78805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(NAME) 0 78905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(NAME) 0 79005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 79105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */ 79205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 79305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef int gl_recursive_lock_t; 79405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define(STORAGECLASS, NAME) 79505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) 79605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_init(NAME) 0 79705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_lock(NAME) 0 79805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_unlock(NAME) 0 79905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_destroy(NAME) 0 80005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 80105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */ 80205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 80305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef int gl_once_t; 80405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_once_define(STORAGECLASS, NAME) \ 80505436638acc7c010349a69c3395f1a57c642dc62Ying Wang STORAGECLASS gl_once_t NAME = 0; 80605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_once(ONCE_CONTROL, INITFUNCTION) \ 80705436638acc7c010349a69c3395f1a57c642dc62Ying Wang (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0) 80805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 80905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 81005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 81105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */ 81205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 81305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Macros with built-in error handling. */ 81405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 81505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */ 81605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 81705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_lock_init(NAME) \ 81805436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 81905436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 82005436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_lock_init (&NAME)) \ 82105436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 82205436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 82305436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 82405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_lock_lock(NAME) \ 82505436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 82605436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 82705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_lock_lock (&NAME)) \ 82805436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 82905436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 83005436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 83105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_lock_unlock(NAME) \ 83205436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 83305436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 83405436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_lock_unlock (&NAME)) \ 83505436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 83605436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 83705436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 83805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_lock_destroy(NAME) \ 83905436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 84005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 84105436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_lock_destroy (&NAME)) \ 84205436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 84305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 84405436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 84505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 84605436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */ 84705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 84805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_rwlock_init(NAME) \ 84905436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 85005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 85105436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_rwlock_init (&NAME)) \ 85205436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 85305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 85405436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 85505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_rwlock_rdlock(NAME) \ 85605436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 85705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 85805436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_rwlock_rdlock (&NAME)) \ 85905436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 86005436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 86105436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 86205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_rwlock_wrlock(NAME) \ 86305436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 86405436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 86505436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_rwlock_wrlock (&NAME)) \ 86605436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 86705436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 86805436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 86905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_rwlock_unlock(NAME) \ 87005436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 87105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 87205436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_rwlock_unlock (&NAME)) \ 87305436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 87405436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 87505436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 87605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_rwlock_destroy(NAME) \ 87705436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 87805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 87905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_rwlock_destroy (&NAME)) \ 88005436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 88105436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 88205436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 88305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 88405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */ 88505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 88605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_recursive_lock_init(NAME) \ 88705436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 88805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 88905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_recursive_lock_init (&NAME)) \ 89005436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 89105436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 89205436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 89305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_recursive_lock_lock(NAME) \ 89405436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 89505436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 89605436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_recursive_lock_lock (&NAME)) \ 89705436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 89805436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 89905436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 90005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_recursive_lock_unlock(NAME) \ 90105436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 90205436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 90305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_recursive_lock_unlock (&NAME)) \ 90405436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 90505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 90605436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 90705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_recursive_lock_destroy(NAME) \ 90805436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 90905436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 91005436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_recursive_lock_destroy (&NAME)) \ 91105436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 91205436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 91305436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 91405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 91505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */ 91605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 91705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_once(NAME, INITFUNCTION) \ 91805436638acc7c010349a69c3395f1a57c642dc62Ying Wang do \ 91905436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 92005436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (glthread_once (&NAME, INITFUNCTION)) \ 92105436638acc7c010349a69c3395f1a57c642dc62Ying Wang abort (); \ 92205436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 92305436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (0) 92405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 92505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */ 92605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 92705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif /* _LOCK_H */ 928