Back to index

glibc  2.9
libc-lock.h
Go to the documentation of this file.
00001 /* libc-internal interface for mutex locks.  Mach cthreads version.
00002    Copyright (C) 1996,97,98,2000,01, 2002 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #ifndef _BITS_LIBC_LOCK_H
00021 #define _BITS_LIBC_LOCK_H 1
00022 
00023 #ifdef _LIBC
00024 #include <cthreads.h>
00025 #define __libc_lock_t struct mutex
00026 #else
00027 typedef struct __libc_lock_opaque__ __libc_lock_t;
00028 #endif
00029 
00030 /* Type for key of thread specific data.  */
00031 typedef cthread_key_t __libc_key_t;
00032 
00033 /* Define a lock variable NAME with storage class CLASS.  The lock must be
00034    initialized with __libc_lock_init before it can be used (or define it
00035    with __libc_lock_define_initialized, below).  Use `extern' for CLASS to
00036    declare a lock defined in another module.  In public structure
00037    definitions you must use a pointer to the lock structure (i.e., NAME
00038    begins with a `*'), because its storage size will not be known outside
00039    of libc.  */
00040 #define __libc_lock_define(CLASS,NAME) \
00041   CLASS __libc_lock_t NAME;
00042 
00043 /* Define an initialized lock variable NAME with storage class CLASS.  */
00044 #define __libc_lock_define_initialized(CLASS,NAME) \
00045   CLASS __libc_lock_t NAME = MUTEX_INITIALIZER;
00046 
00047 /* Initialize the named lock variable, leaving it in a consistent, unlocked
00048    state.  */
00049 #define __libc_lock_init(NAME) __mutex_init (&(NAME))
00050 
00051 /* Finalize the named lock variable, which must be locked.  It cannot be
00052    used again until __libc_lock_init is called again on it.  This must be
00053    called on a lock variable before the containing storage is reused.  */
00054 #define __libc_lock_fini(NAME) __mutex_unlock (&(NAME))
00055 
00056 /* Lock the named lock variable.  */
00057 #define __libc_lock_lock(NAME) __mutex_lock (&(NAME))
00058 
00059 /* Lock the named lock variable.  */
00060 #define __libc_lock_trylock(NAME) (!__mutex_trylock (&(NAME)))
00061 
00062 /* Unlock the named lock variable.  */
00063 #define __libc_lock_unlock(NAME) __mutex_unlock (&(NAME))
00064 
00065 
00066 /* XXX for now */
00067 #define __libc_rwlock_define              __libc_lock_define
00068 #define __libc_rwlock_define_initialized __libc_lock_define_initialized
00069 #define __libc_rwlock_init         __libc_lock_init
00070 #define __libc_rwlock_fini         __libc_lock_fini
00071 #define __libc_rwlock_rdlock              __libc_lock_lock
00072 #define __libc_rwlock_wrlock              __libc_lock_lock
00073 #define __libc_rwlock_tryrdlock           __libc_lock_trylock
00074 #define __libc_rwlock_trywrlock           __libc_lock_trylock
00075 #define __libc_rwlock_unlock              __libc_lock_unlock
00076 
00077 
00078 /* Start a critical region with a cleanup function */
00079 #define __libc_cleanup_region_start(DOIT, FCT, ARG)                       \
00080 {                                                                  \
00081   typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0;                     \
00082   typeof (ARG) __save_ARG = ARG;                                   \
00083   /* close brace is in __libc_cleanup_region_end below. */
00084 
00085 /* End a critical region started with __libc_cleanup_region_start. */
00086 #define __libc_cleanup_region_end(DOIT)                                   \
00087   if ((DOIT) && __save_FCT != 0)                                   \
00088     (*__save_FCT)(__save_ARG);                                            \
00089 }
00090 
00091 /* Sometimes we have to exit the block in the middle.  */
00092 #define __libc_cleanup_end(DOIT)                                   \
00093   if ((DOIT) && __save_FCT != 0)                                   \
00094     (*__save_FCT)(__save_ARG);                                            \
00095 
00096 
00097 /* Use mutexes as once control variables. */
00098 
00099 struct __libc_once
00100   {
00101     __libc_lock_t lock;
00102     int done;
00103   };
00104 
00105 #define __libc_once_define(CLASS,NAME) \
00106   CLASS struct __libc_once NAME = { MUTEX_INITIALIZER, 0 }
00107 
00108 
00109 /* Call handler iff the first call.  */
00110 #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
00111   do {                                                               \
00112     __libc_lock_lock (ONCE_CONTROL.lock);                            \
00113     if (!ONCE_CONTROL.done)                                          \
00114       (INIT_FUNCTION) ();                                            \
00115     ONCE_CONTROL.done = 1;                                           \
00116     __libc_lock_unlock (ONCE_CONTROL.lock);                                 \
00117   } while (0)
00118 
00119 #ifdef _LIBC
00120 /* We need portable names for some functions.  E.g., when they are
00121    used as argument to __libc_cleanup_region_start.  */
00122 #define __libc_mutex_unlock __mutex_unlock
00123 #endif
00124 
00125 #define __libc_key_create(KEY,DEST) cthread_keycreate (KEY)
00126 #define __libc_setspecific(KEY,VAL) cthread_setspecific (KEY, VAL)
00127 void *__libc_getspecific (__libc_key_t key);
00128 
00129 /* XXX until cthreads supports recursive locks */
00130 #define __libc_lock_define_initialized_recursive __libc_lock_define_initialized
00131 #define __libc_lock_init_recursive __libc_lock_init
00132 #define __libc_lock_fini_recursive __libc_lock_fini
00133 #define __libc_lock_trylock_recursive __libc_lock_trylock
00134 #define __libc_lock_unlock_recursive __libc_lock_unlock
00135 #define __libc_lock_lock_recursive __libc_lock_lock
00136 
00137 #define __rtld_lock_define_initialized_recursive __libc_lock_define_initialized
00138 #define __rtld_lock_init_recursive __libc_lock_init
00139 #define __rtld_lock_fini_recursive __libc_lock_fini
00140 #define __rtld_lock_trylock_recursive __libc_lock_trylock
00141 #define __rtld_lock_unlock_recursive __libc_lock_unlock
00142 #define __rtld_lock_lock_recursive __libc_lock_lock
00143 
00144 #endif /* bits/libc-lock.h */