12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
/* Defines to make different thread packages compatible */
18
#ifndef DRIZZLED_INTERNAL_MY_PTHREAD_H
19
#define DRIZZLED_INTERNAL_MY_PTHREAD_H
21
22
#include <unistd.h>
23
#include <boost/date_time.hpp>
25
#if !defined(__cplusplus)
26
30
#define ETIME ETIMEDOUT /* For FreeBSD */
34
#define EXTERNC extern "C"
38
#endif /* __cplusplus */
29
40
#include <pthread.h>
45
51
#define pthread_key(T,V) pthread_key_t V
46
52
#define pthread_handler_t void *
47
53
typedef void *(* pthread_handler)(void *);
55
#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
56
#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
61
We define my_sigset() and use that instead of the system sigset() so that
62
we can favor an implementation based on sigaction(). On some systems, such
63
as Mac OS X, sigset() results in flags such as SA_RESTART being set, and
64
we want to make sure that no such flags are set.
66
#if defined(HAVE_SIGACTION) && !defined(my_sigset)
67
#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \
69
sigemptyset(&l_set); \
70
l_s.sa_handler = (B); \
71
l_s.sa_mask = l_set; \
73
l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\
76
#elif defined(HAVE_SIGSET) && !defined(my_sigset)
77
#define my_sigset(A,B) sigset((A),(B))
78
#elif !defined(my_sigset)
79
#define my_sigset(A,B) signal((A),(B))
82
#ifndef my_pthread_attr_setprio
83
#ifdef HAVE_PTHREAD_ATTR_SETPRIO
84
#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B))
86
extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
49
90
#if !defined(HAVE_PTHREAD_YIELD_ONE_ARG) && !defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
50
91
/* no pthread_yield() available */
51
92
#ifdef HAVE_SCHED_YIELD
60
101
for calculating an absolute time at which
61
102
pthread_cond_timedwait should timeout
104
#ifdef HAVE_TIMESPEC_TS_SEC
106
#define set_timespec(ABSTIME,SEC) \
108
(ABSTIME).ts_sec=time(0) + (time_t) (SEC); \
109
(ABSTIME).ts_nsec=0; \
111
#endif /* !set_timespec */
112
#ifndef set_timespec_nsec
113
#define set_timespec_nsec(ABSTIME,NSEC) \
115
uint64_t now= my_getsystime() + (NSEC/100); \
116
(ABSTIME).ts_sec= (now / 10000000UL); \
117
(ABSTIME).ts_nsec= (now % 10000000UL * 100 + ((NSEC) % 100)); \
119
#endif /* !set_timespec_nsec */
63
121
#ifndef set_timespec
64
122
#define set_timespec(ABSTIME,SEC) \
72
130
#ifndef set_timespec_nsec
73
131
#define set_timespec_nsec(ABSTIME,NSEC) \
75
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());\
76
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));\
77
uint64_t t_mark= (mytime-epoch).total_microseconds();\
78
uint64_t now= t_mark + (NSEC/100); \
133
uint64_t now= my_getsystime() + (NSEC/100); \
79
134
(ABSTIME).tv_sec= (time_t) (now / 10000000UL); \
80
135
(ABSTIME).tv_nsec= (long) (now % 10000000UL * 100 + ((NSEC) % 100)); \
82
137
#endif /* !set_timespec_nsec */
138
#endif /* HAVE_TIMESPEC_TS_SEC */
140
/* safe_mutex adds checking to mutex for easier debugging */
142
typedef struct st_safe_mutex_t
144
pthread_mutex_t global,mutex;
150
int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
151
const char *file, uint32_t line);
152
int safe_mutex_lock(safe_mutex_t *mp, bool try_lock, const char *file, uint32_t line);
153
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint32_t line);
154
int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint32_t line);
155
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
157
int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
158
struct timespec *abstime, const char *file, uint32_t line);
159
void safe_mutex_global_init(void);
160
void safe_mutex_end(void);
84
162
/* Wrappers if safe mutex is actually used */
85
163
#define safe_mutex_assert_owner(mp)
88
166
/* READ-WRITE thread locking */
168
#ifndef HAVE_THR_SETCONCURRENCY
169
#define thr_setconcurrency(A) pthread_dummy(0)
90
171
#if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize)
91
172
#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
94
175
/* Define mutex types, see my_thr_init.c */
95
#ifdef THREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
176
#define MY_MUTEX_INIT_SLOW NULL
177
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
96
178
extern pthread_mutexattr_t my_fast_mutexattr;
97
179
#define MY_MUTEX_INIT_FAST &my_fast_mutexattr
99
181
#define MY_MUTEX_INIT_FAST NULL
183
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
184
extern pthread_mutexattr_t my_errorcheck_mutexattr;
185
#define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
187
#define MY_MUTEX_INIT_ERRCHK NULL
103
191
/* Define it to something */
195
typedef uint64_t my_thread_id;
107
197
extern bool my_thread_global_init(void);
108
198
extern void my_thread_global_end(void);
109
199
extern bool my_thread_init(void);
110
200
extern void my_thread_end(void);
111
201
extern const char *my_thread_name(void);
202
extern my_thread_id my_thread_dbug_id(void);
113
204
/* All thread specific variables are in the following struct */
116
A default thread stack size of zero means that we are going to use
117
the OS defined thread stack size (this varies from OS to OS).
119
#define DEFAULT_THREAD_STACK 0
121
} /* namespace internal */
122
} /* namespace drizzled */
124
#endif /* DRIZZLED_INTERNAL_MY_PTHREAD_H */
206
#define THREAD_NAME_SIZE 10
208
Drizzle can survive with 32K, but some glibc libraries require > 128K stack
209
to resolve hostnames. Also recursive stored procedures needs stack.
211
#define DEFAULT_THREAD_STACK (256*INT32_C(1024))
213
struct st_my_thread_var
215
pthread_cond_t suspend;
216
pthread_mutex_t mutex;
217
pthread_mutex_t * volatile current_mutex;
218
pthread_cond_t * volatile current_cond;
219
pthread_t pthread_self;
224
struct st_my_thread_var *next,**prev;
228
extern struct st_my_thread_var *_my_thread_var(void);
229
extern uint32_t my_thread_end_wait_time;
230
#define my_thread_var (_my_thread_var())
232
Keep track of shutdown,signal, and main threads so that my_end() will not
233
report errors with them
236
/* Which kind of thread library is in use */
238
#define THD_LIB_OTHER 1
239
#define THD_LIB_NPTL 2
242
extern uint32_t thd_lib_detected;
245
thread_safe_xxx functions are for critical statistic or counters.
246
The implementation is guaranteed to be thread safe, on all platforms.
247
Note that the calling code should *not* assume the counter is protected
248
by the mutex given, as the implementation of these helpers may change
249
to use my_atomic operations instead.
252
#ifndef thread_safe_increment
253
#define thread_safe_increment(V,L) \
254
(pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L)))
255
#define thread_safe_decrement(V,L) \
256
(pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L)))
259
#ifndef thread_safe_add
260
#define thread_safe_add(V,C,L) \
261
(pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L)))
262
#define thread_safe_sub(V,C,L) \
263
(pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L)))
267
statistics_xxx functions are for non critical statistic,
268
maintained in global variables.
269
- race conditions can occur, making the result slightly inaccurate.
270
- the lock given is not honored.
272
#define statistic_decrement(V,L) (V)--
273
#define statistic_increment(V,L) (V)++
274
#define statistic_add(V,C,L) (V)+=(C)
275
#define statistic_sub(V,C,L) (V)-=(C)
278
No locking needed, the counter is owned by the thread
280
#define status_var_increment(V) (V)++
281
#define status_var_decrement(V) (V)--
282
#define status_var_add(V,C) (V)+=(C)
283
#define status_var_sub(V,C) (V)-=(C)
288
#endif /* _my_ptread_h */