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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
16
/* Defines to make different thread packages compatible */
20
#ifndef DRIZZLED_INTERNAL_MY_PTHREAD_H
21
#define DRIZZLED_INTERNAL_MY_PTHREAD_H
22
23
#include <unistd.h>
25
#include <boost/date_time.hpp>
26
28
#define ETIME ETIMEDOUT /* For FreeBSD */
30
#define EXTERNC extern "C"
34
#endif /* __cplusplus */
36
31
#include <pthread.h>
42
#include "drizzled/visibility.h"
47
49
#define pthread_key(T,V) pthread_key_t V
48
50
#define pthread_handler_t void *
49
51
typedef void *(* pthread_handler)(void *);
51
#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
52
#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
57
We define my_sigset() and use that instead of the system sigset() so that
58
we can favor an implementation based on sigaction(). On some systems, such
59
as Mac OS X, sigset() results in flags such as SA_RESTART being set, and
60
we want to make sure that no such flags are set.
62
#if defined(HAVE_SIGACTION) && !defined(my_sigset)
63
#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \
65
sigemptyset(&l_set); \
66
l_s.sa_handler = (B); \
67
l_s.sa_mask = l_set; \
69
l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\
72
#elif defined(HAVE_SIGSET) && !defined(my_sigset)
73
#define my_sigset(A,B) sigset((A),(B))
74
#elif !defined(my_sigset)
75
#define my_sigset(A,B) signal((A),(B))
78
#ifndef my_pthread_attr_setprio
79
#ifdef HAVE_PTHREAD_ATTR_SETPRIO
80
#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B))
82
extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
86
53
#if !defined(HAVE_PTHREAD_YIELD_ONE_ARG) && !defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
87
54
/* no pthread_yield() available */
88
55
#ifdef HAVE_SCHED_YIELD
109
76
#ifndef set_timespec_nsec
110
77
#define set_timespec_nsec(ABSTIME,NSEC) \
112
uint64_t now= my_getsystime() + (NSEC/100); \
79
boost::posix_time::ptime mytime(boost::posix_time::microsec_clock::local_time());\
80
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));\
81
uint64_t t_mark= (mytime-epoch).total_microseconds();\
82
uint64_t now= t_mark + (NSEC/100); \
113
83
(ABSTIME).tv_sec= (time_t) (now / 10000000UL); \
114
84
(ABSTIME).tv_nsec= (long) (now % 10000000UL * 100 + ((NSEC) % 100)); \
116
86
#endif /* !set_timespec_nsec */
118
/* safe_mutex adds checking to mutex for easier debugging */
120
typedef struct st_safe_mutex_t
122
pthread_mutex_t global,mutex;
128
int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
129
const char *file, uint32_t line);
130
int safe_mutex_lock(safe_mutex_t *mp, bool try_lock, const char *file, uint32_t line);
131
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint32_t line);
132
int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint32_t line);
133
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
135
int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
136
struct timespec *abstime, const char *file, uint32_t line);
137
void safe_mutex_global_init(void);
138
void safe_mutex_end(void);
140
88
/* Wrappers if safe mutex is actually used */
141
89
#define safe_mutex_assert_owner(mp)
142
90
#define safe_mutex_assert_not_owner(mp)
144
92
/* READ-WRITE thread locking */
146
#ifndef HAVE_THR_SETCONCURRENCY
147
#define thr_setconcurrency(A) pthread_dummy(0)
149
94
#if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize)
150
95
#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
158
103
#define MY_MUTEX_INIT_FAST NULL
160
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
161
extern pthread_mutexattr_t my_errorcheck_mutexattr;
162
#define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
164
#define MY_MUTEX_INIT_ERRCHK NULL
168
107
/* Define it to something */
172
typedef uint64_t my_thread_id;
174
111
extern bool my_thread_global_init(void);
175
112
extern void my_thread_global_end(void);
176
extern bool my_thread_init(void);
177
extern void my_thread_end(void);
113
DRIZZLED_API bool my_thread_init(void);
114
DRIZZLED_API void my_thread_end(void);
178
115
extern const char *my_thread_name(void);
179
extern my_thread_id my_thread_dbug_id(void);
181
117
/* All thread specific variables are in the following struct */
183
#define THREAD_NAME_SIZE 10
185
Drizzle can survive with 32K, but some glibc libraries require > 128K stack
186
to resolve hostnames. Also recursive stored procedures needs stack.
188
#define DEFAULT_THREAD_STACK (256*INT32_C(1024))
190
struct st_my_thread_var
192
pthread_cond_t suspend;
193
pthread_mutex_t mutex;
194
pthread_mutex_t * volatile current_mutex;
195
pthread_cond_t * volatile current_cond;
196
pthread_t pthread_self;
200
struct st_my_thread_var *next,**prev;
204
extern struct st_my_thread_var *_my_thread_var(void);
205
extern uint32_t my_thread_end_wait_time;
206
#define my_thread_var (_my_thread_var())
208
Keep track of shutdown,signal, and main threads so that my_end() will not
209
report errors with them
212
/* Which kind of thread library is in use */
214
#define THD_LIB_OTHER 1
215
#define THD_LIB_NPTL 2
218
extern uint32_t thd_lib_detected;
221
thread_safe_xxx functions are for critical statistic or counters.
222
The implementation is guaranteed to be thread safe, on all platforms.
223
Note that the calling code should *not* assume the counter is protected
224
by the mutex given, as the implementation of these helpers may change
225
to use my_atomic operations instead.
228
#ifndef thread_safe_increment
229
#define thread_safe_increment(V,L) \
230
(pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L)))
231
#define thread_safe_decrement(V,L) \
232
(pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L)))
235
#ifndef thread_safe_add
236
#define thread_safe_add(V,C,L) \
237
(pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L)))
238
#define thread_safe_sub(V,C,L) \
239
(pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L)))
243
statistics_xxx functions are for non critical statistic,
244
maintained in global variables.
245
- race conditions can occur, making the result slightly inaccurate.
246
- the lock given is not honored.
248
#define statistic_decrement(V,L) (V)--
249
#define statistic_increment(V,L) (V)++
250
#define statistic_add(V,C,L) (V)+=(C)
251
#define statistic_sub(V,C,L) (V)-=(C)
254
No locking needed, the counter is owned by the thread
256
#define status_var_increment(V) (V)++
257
#define status_var_decrement(V) (V)--
258
#define status_var_add(V,C) (V)+=(C)
259
#define status_var_sub(V,C) (V)-=(C)
264
#endif /* _my_ptread_h */
120
A default thread stack size of zero means that we are going to use
121
the OS defined thread stack size (this varies from OS to OS).
123
#define DEFAULT_THREAD_STACK 0
125
} /* namespace internal */
126
} /* namespace drizzled */
128
#endif /* DRIZZLED_INTERNAL_MY_PTHREAD_H */