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 */
20
18
#ifndef DRIZZLED_INTERNAL_MY_PTHREAD_H
21
19
#define DRIZZLED_INTERNAL_MY_PTHREAD_H
23
21
#include <unistd.h>
25
#include <boost/date_time.hpp>
28
25
#define ETIME ETIMEDOUT /* For FreeBSD */
50
45
#define pthread_handler_t void *
51
46
typedef void *(* pthread_handler)(void *);
50
We define my_sigset() and use that instead of the system sigset() so that
51
we can favor an implementation based on sigaction(). On some systems, such
52
as Mac OS X, sigset() results in flags such as SA_RESTART being set, and
53
we want to make sure that no such flags are set.
55
#if !defined(my_sigset)
56
#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \
58
sigemptyset(&l_set); \
59
l_s.sa_handler = (B); \
60
l_s.sa_mask = l_set; \
62
l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\
65
#elif defined(HAVE_SIGSET) && !defined(my_sigset)
66
#define my_sigset(A,B) sigset((A),(B))
67
#elif !defined(my_sigset)
68
#define my_sigset(A,B) signal((A),(B))
71
#ifndef my_pthread_attr_setprio
72
#ifdef HAVE_PTHREAD_ATTR_SETPRIO
73
#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B))
75
extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
53
79
#if !defined(HAVE_PTHREAD_YIELD_ONE_ARG) && !defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
54
80
/* no pthread_yield() available */
55
81
#ifdef HAVE_SCHED_YIELD
76
102
#ifndef set_timespec_nsec
77
103
#define set_timespec_nsec(ABSTIME,NSEC) \
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); \
105
uint64_t now= my_getsystime() + (NSEC/100); \
83
106
(ABSTIME).tv_sec= (time_t) (now / 10000000UL); \
84
107
(ABSTIME).tv_nsec= (long) (now % 10000000UL * 100 + ((NSEC) % 100)); \
86
109
#endif /* !set_timespec_nsec */
111
/* safe_mutex adds checking to mutex for easier debugging */
113
typedef struct st_safe_mutex_t
115
pthread_mutex_t global,mutex;
121
int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
122
const char *file, uint32_t line);
123
int safe_mutex_lock(safe_mutex_t *mp, bool try_lock, const char *file, uint32_t line);
124
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint32_t line);
125
int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint32_t line);
126
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
128
int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
129
struct timespec *abstime, const char *file, uint32_t line);
130
void safe_mutex_global_init(void);
131
void safe_mutex_end(void);
88
133
/* Wrappers if safe mutex is actually used */
89
134
#define safe_mutex_assert_owner(mp)
90
135
#define safe_mutex_assert_not_owner(mp)
111
156
extern bool my_thread_global_init(void);
112
157
extern void my_thread_global_end(void);
113
DRIZZLED_API bool my_thread_init(void);
114
DRIZZLED_API void my_thread_end(void);
158
extern bool my_thread_init(void);
159
extern void my_thread_end(void);
115
160
extern const char *my_thread_name(void);
117
162
/* All thread specific variables are in the following struct */
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
165
Drizzle can survive with 32K, but some glibc libraries require > 128K stack
166
to resolve hostnames. Also recursive stored procedures needs stack.
168
#define DEFAULT_THREAD_STACK (256*INT32_C(1024))
170
struct st_my_thread_var
172
pthread_cond_t suspend;
173
pthread_mutex_t mutex;
174
pthread_mutex_t * volatile current_mutex;
175
pthread_cond_t * volatile current_cond;
176
pthread_t pthread_self;
180
struct st_my_thread_var *next,**prev;
184
extern struct st_my_thread_var *_my_thread_var(void);
185
#define my_thread_var (::drizzled::internal::_my_thread_var())
187
Keep track of shutdown,signal, and main threads so that my_end() will not
188
report errors with them
191
/* Which kind of thread library is in use */
193
#define THD_LIB_OTHER 1
194
#define THD_LIB_NPTL 2
197
extern uint32_t thd_lib_detected;
200
thread_safe_xxx functions are for critical statistic or counters.
201
The implementation is guaranteed to be thread safe, on all platforms.
202
Note that the calling code should *not* assume the counter is protected
203
by the mutex given, as the implementation of these helpers may change
204
to use my_atomic operations instead.
207
#ifndef thread_safe_increment
208
#define thread_safe_increment(V,L) \
209
(pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L)))
210
#define thread_safe_decrement(V,L) \
211
(pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L)))
214
#ifndef thread_safe_add
215
#define thread_safe_add(V,C,L) \
216
(pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L)))
217
#define thread_safe_sub(V,C,L) \
218
(pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L)))
222
statistics_xxx functions are for non critical statistic,
223
maintained in global variables.
224
- race conditions can occur, making the result slightly inaccurate.
225
- the lock given is not honored.
227
#define statistic_decrement(V,L) (V)--
228
#define statistic_increment(V,L) (V)++
229
#define statistic_add(V,C,L) (V)+=(C)
230
#define statistic_sub(V,C,L) (V)-=(C)
233
No locking needed, the counter is owned by the thread
235
#define status_var_increment(V) (V)++
236
#define status_var_decrement(V) (V)--
237
#define status_var_add(V,C) (V)+=(C)
238
#define status_var_sub(V,C) (V)-=(C)
125
240
} /* namespace internal */
126
241
} /* namespace drizzled */