21 #include "mysys_priv.h"
27 THR_LOCK_lock, THR_LOCK_myisam, THR_LOCK_heap,
28 THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads,
32 uint THR_thread_count= 0;
33 uint my_thread_end_wait_time= 5;
34 #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
37 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
38 pthread_mutexattr_t my_fast_mutexattr;
40 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
41 pthread_mutexattr_t my_errorcheck_mutexattr;
44 static void install_sigabrt_handler();
46 #ifdef TARGET_OS_LINUX
53 static pthread_handler_t
54 nptl_pthread_exit_hack_handler(
void *arg __attribute((unused)))
64 static uint get_thread_lib(
void);
67 static my_bool my_thread_global_init_done= 0;
78 void my_thread_global_reinit(
void)
82 DBUG_ASSERT(my_thread_global_init_done);
84 #ifdef HAVE_PSI_INTERFACE
85 my_init_mysys_psi_keys();
104 mysql_mutex_init(key_THR_LOCK_charset, &THR_LOCK_charset, MY_MUTEX_INIT_FAST);
107 mysql_mutex_init(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST);
133 my_bool my_thread_global_init(
void)
137 if (my_thread_global_init_done)
139 my_thread_global_init_done= 1;
141 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
151 pthread_mutexattr_init(&my_fast_mutexattr);
152 pthread_mutexattr_settype(&my_fast_mutexattr,
153 PTHREAD_MUTEX_ADAPTIVE_NP);
156 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
160 pthread_mutexattr_init(&my_errorcheck_mutexattr);
161 pthread_mutexattr_settype(&my_errorcheck_mutexattr,
162 PTHREAD_MUTEX_ERRORCHECK);
165 if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0)
167 fprintf(stderr,
"Can't initialize threads: error %d\n", pth_ret);
171 mysql_mutex_init(key_THR_LOCK_malloc, &THR_LOCK_malloc, MY_MUTEX_INIT_FAST);
173 mysql_mutex_init(key_THR_LOCK_charset, &THR_LOCK_charset, MY_MUTEX_INIT_FAST);
174 mysql_mutex_init(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST);
176 if (my_thread_init())
179 thd_lib_detected= get_thread_lib();
181 #ifdef TARGET_OS_LINUX
194 if (thd_lib_detected == THD_LIB_NPTL)
196 pthread_t dummy_thread;
197 pthread_attr_t dummy_thread_attr;
199 pthread_attr_init(&dummy_thread_attr);
200 pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_JOINABLE);
202 if (pthread_create(&dummy_thread,&dummy_thread_attr,
203 nptl_pthread_exit_hack_handler, NULL) == 0)
204 (void)pthread_join(dummy_thread, NULL);
209 mysql_mutex_init(key_THR_LOCK_myisam, &THR_LOCK_myisam, MY_MUTEX_INIT_SLOW);
210 mysql_mutex_init(key_THR_LOCK_myisam_mmap, &THR_LOCK_myisam_mmap, MY_MUTEX_INIT_FAST);
215 #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
216 mysql_mutex_init(key_LOCK_localtime_r, &LOCK_localtime_r, MY_MUTEX_INIT_SLOW);
220 install_sigabrt_handler();
227 void my_thread_global_end(
void)
230 my_bool all_threads_killed= 1;
232 set_timespec(abstime, my_thread_end_wait_time);
234 while (THR_thread_count > 0)
238 if (error == ETIMEDOUT || error == ETIME)
240 #ifdef HAVE_PTHREAD_KILL
246 if (THR_thread_count)
248 "Error in my_thread_global_end(): %d threads didn't exit\n",
251 all_threads_killed= 0;
257 pthread_key_delete(THR_KEY_mysys);
258 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
259 pthread_mutexattr_destroy(&my_fast_mutexattr);
261 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
262 pthread_mutexattr_destroy(&my_errorcheck_mutexattr);
272 if (all_threads_killed)
277 #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
281 my_thread_global_init_done= 0;
284 static my_thread_id thread_id= 0;
306 my_bool my_thread_init(
void)
311 #ifdef EXTRA_DEBUG_THREADS
312 fprintf(stderr,
"my_thread_init(): thread_id: 0x%lx\n",
313 (ulong) pthread_self());
318 #ifdef EXTRA_DEBUG_THREADS
319 fprintf(stderr,
"my_thread_init() called more than once in thread 0x%lx\n",
320 (
long) pthread_self());
326 install_sigabrt_handler();
334 pthread_setspecific(THR_KEY_mysys,tmp);
335 tmp->pthread_self= pthread_self();
339 tmp->stack_ends_here= (
char*)&tmp +
340 STACK_DIRECTION * (
long)my_thread_stack_size;
343 tmp->id= ++thread_id;
349 (void) my_thread_name();
369 void my_thread_end(
void)
374 #ifdef EXTRA_DEBUG_THREADS
375 fprintf(stderr,
"my_thread_end(): tmp: 0x%lx pthread_self: 0x%lx thread_id: %ld\n",
376 (
long) tmp, (
long) pthread_self(), tmp ? (
long) tmp->id : 0L);
379 #ifdef HAVE_PSI_INTERFACE
385 PSI_THREAD_CALL(delete_current_thread)();
388 if (tmp && tmp->init)
390 #if !defined(DBUG_OFF)
399 #if !defined(__bsdi__) && !defined(__OpenBSD__)
413 DBUG_ASSERT(THR_thread_count != 0);
414 if (--THR_thread_count == 0)
418 pthread_setspecific(THR_KEY_mysys,0);
428 return my_pthread_setspecific_ptr(THR_KEY_mysys, mysys_var);
435 my_thread_id my_thread_dbug_id()
437 return my_thread_var->id;
441 const char *my_thread_name(
void)
448 const char *my_thread_name(
void)
454 my_thread_id
id= my_thread_dbug_id();
455 sprintf(name_buff,
"T@%lu", (ulong)
id);
456 strmake(tmp->name,name_buff,THREAD_NAME_SIZE);
463 extern void **my_thread_var_dbug()
467 return tmp && tmp->init ? &tmp->dbug : 0;
472 static uint get_thread_lib(
void)
474 #ifdef _CS_GNU_LIBPTHREAD_VERSION
477 confstr(_CS_GNU_LIBPTHREAD_VERSION, buff,
sizeof(buff));
479 if (!strncasecmp(buff,
"NPTL", 4))
481 if (!strncasecmp(buff,
"linuxthreads", 12))
484 return THD_LIB_OTHER;
496 #if (_MSC_VER >= 1400)
497 static void my_sigabrt_handler(
int sig)
503 static void install_sigabrt_handler(
void)
505 #if (_MSC_VER >=1400)
507 _set_abort_behavior(0,_CALL_REPORTFAULT);
508 signal(SIGABRT,my_sigabrt_handler);