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