C Standard Library Extensions  1.2
cxthread.h
1 /* $Id$
2  *
3  * This file is part of the ESO C Extension Library
4  * Copyright (C) 2001-2011 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * $Author$
23  * $Date$
24  * $Revision$
25  * $Name$
26  */
27 
28 #ifndef CXTHREAD_H_
29 #define CXTHREAD_H_
30 
31 #if HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34 
35 #ifdef HAVE_PTHREAD_H
36 # include <pthread.h>
37 #endif
38 
39 #include <cxtypes.h>
40 
41 
42 /*
43  * Map local types and functions to the POSIX thread model implementation
44  */
45 
46 #if defined(CX_THREADS_ENABLED)
47 
48 #if defined(HAVE_PTHREAD_H)
49 
50 #define CX_STATIC_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
51 #define CX_STATIC_ONCE_INIT PTHREAD_ONCE_INIT
52 
53 #define CX_MUTEX_TYPE_DEFAULT PTHREAD_MUTEX_DEFAULT
54 #define CX_MUTEX_TYPE_NORMAL PTHREAD_MUTEX_NORMAL
55 #define CX_MUTEX_TYPE_RECURSIVE PTHREAD_MUTEX_RECURSIVE
56 
57 typedef pthread_mutex_t cx_mutex;
58 typedef pthread_once_t cx_once;
59 typedef pthread_key_t cx_private;
60 
61 #define cx_mutex_init(mutex, type) \
62  do { \
63  pthread_mutexattr_t attr; \
64  \
65  pthread_mutexattr_init(&attr); \
66  pthread_mutexattr_settype(&attr, (type)); \
67  \
68  pthread_mutex_init(mutex, &attr); \
69  \
70  pthread_mutexattr_destroy(&attr); \
71  } \
72  while (0)
73 
74 #define cx_mutex_lock(mutex) pthread_mutex_lock((mutex))
75 #define cx_mutex_trylock(mutex) pthread_mutex_trylock((mutex))
76 #define cx_mutex_unlock(mutex) pthread_mutex_unlock((mutex))
77 
78 #define cx_thread_once(name, func, args) pthread_once(&(name), (func))
79 
80 #define cx_private_init(name, func) pthread_key_create(&(name), (func))
81 #define cx_private_set(name, data) pthread_setspecific((name), (data))
82 #define cx_private_get(name) pthread_getspecific((name))
83 
84 #else /* !HAVE_PTHREAD_H */
85 # error "Thread support is requested, but POSIX thread model is not present!"
86 #endif /* !HAVE_PTHREAD_H */
87 
88 #else /* !CX_THREADS_ENABLED */
89 
90 typedef struct cx_private cx_private;
91 
92 #define cx_mutex_init(mutex, type) /* empty */
93 
94 #define cx_mutex_lock(mutex) /* empty */
95 #define cx_mutex_trylock(mutex) /* empty */
96 #define cx_mutex_unlock(mutex) /* empty */
97 
98 #define cx_thread_once(name, func, args) (func)()
99 
100 #define cx_private_init(name, func) /* empty */
101 #define cx_private_set(name, data) ((name) = (data))
102 #define cx_private_get(name) (name)
103 
104 #endif /* !CX_THREADS_ENABLED */
105 
106 
107 /*
108  * Convenience macros to setup locks for global variables.
109  * These macros expand to nothing, if thread support was not enabled.
110  */
111 
112 #define CX_LOCK_NAME(name) _cx__ ## name ## _lock
113 
114 #if defined(CX_THREADS_ENABLED)
115 
116 # define CX_LOCK_DEFINE_STATIC(name) static CX_LOCK_DEFINE(name)
117 # define CX_LOCK_DEFINE(name) cx_mutex CX_LOCK_NAME(name)
118 # define CX_LOCK_EXTERN(name) extern cx_mutex CX_LOCK_NAME(name)
119 
120 # define CX_LOCK_DEFINE_INITIALIZED_STATIC(name) \
121  static CX_LOCK_DEFINE_INITIALIZED(name)
122 # define CX_LOCK_DEFINE_INITIALIZED(name) \
123  CX_LOCK_DEFINE(name) = CX_STATIC_MUTEX_INIT
124 
125 # define CX_INITLOCK(name, type) cx_mutex_init(&CX_LOCK_NAME(name), (type))
126 
127 # define CX_LOCK(name) cx_mutex_lock(&CX_LOCK_NAME(name))
128 # define CX_TRYLOCK(name) cx_mutex_trylock(&CX_LOCK_NAME(name))
129 # define CX_UNLOCK(name) cx_mutex_unlock(&CX_LOCK_NAME(name))
130 
131 #else /* !CX_THREADS_ENABLED */
132 
133 # define CX_LOCK_DEFINE_STATIC(name) /* empty */
134 # define CX_LOCK_DEFINE(name) /* empty */
135 # define CX_LOCK_EXTERN(name) /* empty */
136 
137 # define CX_LOCK_DEFINE_INITIALIZED_STATIC(name) /* empty */
138 # define CX_LOCK_DEFINE_INITIALIZED(name) /* empty */
139 
140 # define CX_INITLOCK(name, type) /* empty */
141 
142 # define CX_LOCK(name) /* empty */
143 # define CX_TRYLOCK(name) (TRUE)
144 # define CX_UNLOCK(name) /* empty */
145 
146 #endif /* !CX_THREADS_ENABLED */
147 
148 
149 /*
150  * Convenience macros for setting up mutexes for one time initalizations
151  */
152 
153 #if defined(CX_THREADS_ENABLED)
154 
155 # define CX_ONCE_DEFINE_STATIC(name) static CX_ONCE_DEFINE(name)
156 # define CX_ONCE_DEFINE(name) cx_once (name)
157 
158 # define CX_ONCE_DEFINE_INITIALIZED_STATIC(name) \
159  static CX_ONCE_DEFINE_INITIALIZED(name)
160 # define CX_ONCE_DEFINE_INITIALIZED(name) \
161  cx_once (name) = CX_STATIC_ONCE_INIT
162 
163 #else /* !CX_THREADS_ENABLED */
164 
165 # define CX_ONCE_DEFINE_STATIC(name) /* empty */
166 # define CX_ONCE_DEFINE(name) /* empty */
167 
168 # define CX_ONCE_DEFINE_INITIALIZED_STATIC(name) /* empty */
169 # define CX_ONCE_DEFINE_INITIALIZED(name) /* empty */
170 
171 #endif /* !CX_THREADS_ENABLED */
172 
173 
174 /*
175  * Convenience macros for setting up thread-specific data
176  */
177 
178 #if defined(CX_THREADS_ENABLED)
179 
180 # define CX_PRIVATE_DEFINE_STATIC(name) cx_private (name)
181 
182 #else /* !CX_THREADS_ENABLED */
183 
184 # define CX_PRIVATE_DEFINE_STATIC(name) static cx_private *(name)
185 
186 #endif /* !CX_THREADS_ENABLED */
187 
188 #endif /* CXTHREAD_H_ */