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 */
17
17
Functions to handle initializating and allocationg of all mysys & debug
23
#include "drizzled/internal/my_sys.h"
24
#include "drizzled/internal/thread_var.h"
25
#include "drizzled/internal/m_string.h"
21
#include "mysys_priv.h"
22
#include <mysys/my_pthread.h>
23
#include <mystrings/m_string.h>
28
26
#include <signal.h>
30
28
#if TIME_WITH_SYS_TIME
41
#include <boost/thread/thread.hpp>
42
#include <boost/thread/mutex.hpp>
43
#include <boost/thread/tss.hpp>
50
boost::thread_specific_ptr<st_my_thread_var> THR_KEY_mysys;
51
boost::mutex THR_LOCK_threads;
39
uint32_t thd_lib_detected= 0;
42
pthread_key_t THR_KEY_mysys;
44
pthread_key_t THR_KEY_mysys;
46
pthread_mutex_t THR_LOCK_open;
47
pthread_mutex_t THR_LOCK_lock;
48
pthread_mutex_t THR_LOCK_charset;
49
pthread_mutex_t THR_LOCK_threads;
50
pthread_mutex_t THR_LOCK_time;
51
pthread_cond_t THR_COND_threads;
52
uint32_t THR_thread_count= 0;
53
uint32_t my_thread_end_wait_time= 5;
54
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
55
pthread_mutexattr_t my_fast_mutexattr;
57
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
58
pthread_mutexattr_t my_errorcheck_mutexattr;
61
#ifdef TARGET_OS_LINUX
64
Dummy thread spawned in my_thread_global_init() below to avoid
65
race conditions in NPTL pthread_exit code.
70
nptl_pthread_exit_hack_handler(void *arg __attribute((unused)))
77
#endif /* TARGET_OS_LINUX */
80
static uint32_t get_thread_lib(void);
54
83
initialize thread environment
64
93
bool my_thread_global_init(void)
96
thd_lib_detected= get_thread_lib();
98
if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0)
100
fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret);
104
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
106
Set mutex type to "fast" a.k.a "adaptive"
108
In this case the thread may steal the mutex from some other thread
109
that is waiting for the same mutex. This will save us some
110
context switches but may cause a thread to 'starve forever' while
111
waiting for the mutex (not likely if the code within the mutex is
114
pthread_mutexattr_init(&my_fast_mutexattr);
115
pthread_mutexattr_settype(&my_fast_mutexattr,
116
PTHREAD_MUTEX_ADAPTIVE_NP);
118
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
120
Set mutex type to "errorcheck"
122
pthread_mutexattr_init(&my_errorcheck_mutexattr);
123
pthread_mutexattr_settype(&my_errorcheck_mutexattr,
124
PTHREAD_MUTEX_ERRORCHECK);
127
pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST);
128
pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
129
pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST);
130
pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST);
131
pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST);
132
pthread_cond_init(&THR_COND_threads, NULL);
66
133
if (my_thread_init())
68
135
my_thread_global_end(); /* Clean up */
75
142
void my_thread_global_end(void)
144
struct timespec abstime;
145
bool all_threads_killed= 1;
147
set_timespec(abstime, my_thread_end_wait_time);
148
pthread_mutex_lock(&THR_LOCK_threads);
149
while (THR_thread_count > 0)
151
int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
153
if (error == ETIMEDOUT || error == ETIME)
155
#ifdef HAVE_PTHREAD_KILL
157
We shouldn't give an error here, because if we don't have
158
pthread_kill(), programs like mysqld can't ensure that all threads
159
are killed when we enter here.
161
if (THR_thread_count)
163
"Error in my_thread_global_end(): %d threads didn't exit\n",
166
all_threads_killed= 0;
170
pthread_mutex_unlock(&THR_LOCK_threads);
172
pthread_key_delete(THR_KEY_mysys);
173
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
174
pthread_mutexattr_destroy(&my_fast_mutexattr);
176
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
177
pthread_mutexattr_destroy(&my_errorcheck_mutexattr);
179
pthread_mutex_destroy(&THR_LOCK_open);
180
pthread_mutex_destroy(&THR_LOCK_lock);
181
pthread_mutex_destroy(&THR_LOCK_time);
182
pthread_mutex_destroy(&THR_LOCK_charset);
183
if (all_threads_killed)
185
pthread_mutex_destroy(&THR_LOCK_threads);
186
pthread_cond_destroy(&THR_COND_threads);
79
static uint64_t thread_id= 0;
190
static my_thread_id thread_id= 0;
82
193
Allocate thread specific memory for the thread, used by mysys
92
209
bool my_thread_init(void)
94
// We should mever see my_thread_init() called twice
95
if (THR_KEY_mysys.get())
98
st_my_thread_var *tmp= new st_my_thread_var;
103
THR_KEY_mysys.reset(tmp);
105
boost::mutex::scoped_lock scopedLock(THR_LOCK_threads);
211
struct st_my_thread_var *tmp;
214
#ifdef EXTRA_DEBUG_THREADS
215
fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n",
216
(uint32_t) pthread_self());
219
if (pthread_getspecific(THR_KEY_mysys))
221
#ifdef EXTRA_DEBUG_THREADS
222
fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
223
(long) pthread_self());
227
if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
232
pthread_setspecific(THR_KEY_mysys,tmp);
233
tmp->pthread_self= pthread_self();
234
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
235
pthread_cond_init(&tmp->suspend, NULL);
238
pthread_mutex_lock(&THR_LOCK_threads);
106
239
tmp->id= ++thread_id;
241
pthread_mutex_unlock(&THR_LOCK_threads);
119
255
This may be called multiple times for a thread.
120
This happens for example when one calls 'server_init()'
121
server_end() and then ends with a end().
256
This happens for example when one calls 'mysql_server_init()'
257
mysql_server_end() and then ends with a mysql_end().
124
260
void my_thread_end(void)
262
struct st_my_thread_var *tmp;
263
tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
265
#ifdef EXTRA_DEBUG_THREADS
266
fprintf(stderr,"my_thread_end(): tmp: 0x%lx pthread_self: 0x%lx thread_id: %ld\n",
267
(long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L);
269
if (tmp && tmp->init)
271
#if !defined(__bsdi__) && !defined(__OpenBSD__)
272
/* bsdi and openbsd 3.5 dumps core here */
273
pthread_cond_destroy(&tmp->suspend);
275
pthread_mutex_destroy(&tmp->mutex);
283
Decrement counter for number of running threads. We are using this
284
in my_thread_global_end() to wait until all threads have called
285
my_thread_end and thus freed all memory they have allocated in
288
pthread_mutex_lock(&THR_LOCK_threads);
289
assert(THR_thread_count != 0);
290
if (--THR_thread_count == 0)
291
pthread_cond_signal(&THR_COND_threads);
292
pthread_mutex_unlock(&THR_LOCK_threads);
294
/* The following free has to be done, even if my_thread_var() is 0 */
296
pthread_setspecific(THR_KEY_mysys,0);
128
300
struct st_my_thread_var *_my_thread_var(void)
130
return THR_KEY_mysys.get();
133
} /* namespace internal */
134
} /* namespace drizzled */
302
struct st_my_thread_var *tmp= (struct st_my_thread_var*)pthread_getspecific(THR_KEY_mysys);
304
/* This can only happen in a .DLL */
308
tmp=(struct st_my_thread_var*)pthread_getspecific(THR_KEY_mysys);
315
/****************************************************************************
316
Get name of current thread.
317
****************************************************************************/
319
my_thread_id my_thread_dbug_id()
321
return my_thread_var->id;
324
static uint32_t get_thread_lib(void)
326
#ifdef _CS_GNU_LIBPTHREAD_VERSION
329
confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
331
if (!strncasecmp(buff, "NPTL", 4))
333
if (!strncasecmp(buff, "linuxthreads", 12))
336
return THD_LIB_OTHER;