~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_pthread.h

  • Committer: Stewart Smith
  • Date: 2009-03-04 22:49:53 UTC
  • mto: (910.4.2 sparc) (908.3.6 work)
  • mto: This revision was merged to the branch mainline in revision 912.
  • Revision ID: stewart@flamingspork.com-20090304224953-b2ow237kc1bkp0o0
for getopt, replace GET_ULONG with GET_UINT32.

Don't replace for sql variables (yet). instead just indicated the intense source of fail with GET_ULONG_IS_FAIL.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
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 */
15
15
 
16
16
/* Defines to make different thread packages compatible */
17
17
 
18
 
#ifndef DRIZZLED_INTERNAL_MY_PTHREAD_H
19
 
#define DRIZZLED_INTERNAL_MY_PTHREAD_H
 
18
#ifndef _my_pthread_h
 
19
#define _my_pthread_h
20
20
 
 
21
#include <stdint.h>
21
22
#include <unistd.h>
 
23
#include <signal.h>
22
24
 
23
 
#include <boost/date_time.hpp>
 
25
#if !defined(__cplusplus)
 
26
# include <stdbool.h>
 
27
#endif
24
28
 
25
29
#ifndef ETIME
26
30
#define ETIME ETIMEDOUT                         /* For FreeBSD */
27
31
#endif
28
32
 
 
33
#ifdef  __cplusplus
 
34
#define EXTERNC extern "C"
 
35
extern "C" {
 
36
#else
 
37
#define EXTERNC
 
38
#endif /* __cplusplus */
 
39
 
29
40
#include <pthread.h>
30
41
#ifndef _REENTRANT
31
42
#define _REENTRANT
37
48
#include <synch.h>
38
49
#endif
39
50
 
40
 
namespace drizzled
41
 
{
42
 
namespace internal
43
 
{
44
 
 
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 *);
48
54
 
 
55
#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
 
56
#define pthread_sigmask(A,B,C) sigthreadmask((A),(B),(C))
 
57
#endif
 
58
 
 
59
 
 
60
/*
 
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.
 
65
*/
 
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; \
 
68
                            assert((A) != 0);                          \
 
69
                            sigemptyset(&l_set);                            \
 
70
                            l_s.sa_handler = (B);                           \
 
71
                            l_s.sa_mask   = l_set;                          \
 
72
                            l_s.sa_flags   = 0;                             \
 
73
                            l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\
 
74
                            assert(l_rc == 0);                         \
 
75
                          } while (0)
 
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))
 
80
#endif
 
81
 
 
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))
 
85
#else
 
86
extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
 
87
#endif
 
88
#endif
 
89
 
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
62
103
*/
 
104
#ifdef HAVE_TIMESPEC_TS_SEC
 
105
#ifndef set_timespec
 
106
#define set_timespec(ABSTIME,SEC) \
 
107
{ \
 
108
  (ABSTIME).ts_sec=time(0) + (time_t) (SEC); \
 
109
  (ABSTIME).ts_nsec=0; \
 
110
}
 
111
#endif /* !set_timespec */
 
112
#ifndef set_timespec_nsec
 
113
#define set_timespec_nsec(ABSTIME,NSEC) \
 
114
{ \
 
115
  uint64_t now= my_getsystime() + (NSEC/100); \
 
116
  (ABSTIME).ts_sec=  (now / 10000000UL); \
 
117
  (ABSTIME).ts_nsec= (now % 10000000UL * 100 + ((NSEC) % 100)); \
 
118
}
 
119
#endif /* !set_timespec_nsec */
 
120
#else
63
121
#ifndef set_timespec
64
122
#define set_timespec(ABSTIME,SEC) \
65
123
{\
72
130
#ifndef set_timespec_nsec
73
131
#define set_timespec_nsec(ABSTIME,NSEC) \
74
132
{\
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)); \
81
136
}
82
137
#endif /* !set_timespec_nsec */
 
138
#endif /* HAVE_TIMESPEC_TS_SEC */
 
139
 
 
140
        /* safe_mutex adds checking to mutex for easier debugging */
 
141
 
 
142
typedef struct st_safe_mutex_t
 
143
{
 
144
  pthread_mutex_t global,mutex;
 
145
  const char *file;
 
146
  uint32_t line,count;
 
147
  pthread_t thread;
 
148
} safe_mutex_t;
 
149
 
 
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,
 
156
                   uint32_t line);
 
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);
83
161
 
84
162
        /* Wrappers if safe mutex is actually used */
85
163
#define safe_mutex_assert_owner(mp)
87
165
 
88
166
        /* READ-WRITE thread locking */
89
167
 
 
168
#ifndef HAVE_THR_SETCONCURRENCY
 
169
#define thr_setconcurrency(A) pthread_dummy(0)
 
170
#endif
90
171
#if !defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && ! defined(pthread_attr_setstacksize)
91
172
#define pthread_attr_setstacksize(A,B) pthread_dummy(0)
92
173
#endif
93
174
 
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
98
180
#else
99
181
#define MY_MUTEX_INIT_FAST   NULL
100
182
#endif
 
183
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
 
184
extern pthread_mutexattr_t my_errorcheck_mutexattr;
 
185
#define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
 
186
#else
 
187
#define MY_MUTEX_INIT_ERRCHK   NULL
 
188
#endif
101
189
 
102
190
#ifndef ESRCH
103
191
/* Define it to something */
104
192
#define ESRCH 1
105
193
#endif
106
194
 
 
195
typedef uint64_t my_thread_id;
 
196
 
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);
112
203
 
113
204
/* All thread specific variables are in the following struct */
114
205
 
115
 
/**
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).
118
 
 */
119
 
#define DEFAULT_THREAD_STACK    0
120
 
 
121
 
} /* namespace internal */
122
 
} /* namespace drizzled */
123
 
 
124
 
#endif /* DRIZZLED_INTERNAL_MY_PTHREAD_H */
 
206
#define THREAD_NAME_SIZE 10
 
207
/*
 
208
  Drizzle can survive with 32K, but some glibc libraries require > 128K stack
 
209
  to resolve hostnames. Also recursive stored procedures needs stack.
 
210
*/
 
211
#define DEFAULT_THREAD_STACK    (256*INT32_C(1024))
 
212
 
 
213
struct st_my_thread_var
 
214
{
 
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;
 
220
  my_thread_id id;
 
221
  int cmp_length;
 
222
  int volatile abort;
 
223
  bool init;
 
224
  struct st_my_thread_var *next,**prev;
 
225
  void *opt_info;
 
226
};
 
227
 
 
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())
 
231
/*
 
232
  Keep track of shutdown,signal, and main threads so that my_end() will not
 
233
  report errors with them
 
234
*/
 
235
 
 
236
/* Which kind of thread library is in use */
 
237
 
 
238
#define THD_LIB_OTHER 1
 
239
#define THD_LIB_NPTL  2
 
240
#define THD_LIB_LT    4
 
241
 
 
242
extern uint32_t thd_lib_detected;
 
243
 
 
244
/*
 
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.
 
250
*/
 
251
 
 
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)))
 
257
#endif
 
258
 
 
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)))
 
264
#endif
 
265
 
 
266
/*
 
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.
 
271
*/
 
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)
 
276
 
 
277
/*
 
278
  No locking needed, the counter is owned by the thread
 
279
*/
 
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)
 
284
 
 
285
#ifdef  __cplusplus
 
286
}
 
287
#endif
 
288
#endif /* _my_ptread_h */