static int start_helper_thread(void) { pthread_barrier_t barrier; if (pthread_barrier_init(&barrier, NULL, 2)) { my_message_local(ERROR_LEVEL, "Failed to initialize pthread barrier. errno=%d", errno); return -1; } if (mysql_thread_create(key_thread_timer_notifier, &timer_notify_thread, NULL, timer_notify_thread_func, &barrier)) { my_message_local(ERROR_LEVEL, "Failed to create timer notify thread (errno= %d).", errno); pthread_barrier_destroy(&barrier); return -1; } pthread_barrier_wait(&barrier); pthread_barrier_destroy(&barrier); return 0; }
my_bool my_thread_init(void) { struct st_my_thread_var *tmp; my_bool error=0; if (!my_thread_global_init_done) return 1; /* cannot proceed with unintialized library */ #ifdef EXTRA_DEBUG_THREADS my_message_local(INFORMATION_LEVEL, "my_thread_init(): thread_id: 0x%lx", (ulong) pthread_self()); #endif if (_my_thread_var()) { #ifdef EXTRA_DEBUG_THREADS my_message_local(WARNING_LEVEL, "my_thread_init() called more than once in thread 0x%lx", (long) pthread_self()); #endif goto end; } #ifdef _MSC_VER install_sigabrt_handler(); #endif if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp)))) { error= 1; goto end; } set_mysys_var(tmp); tmp->pthread_self= pthread_self(); mysql_mutex_init(key_my_thread_var_mutex, &tmp->mutex, MY_MUTEX_INIT_FAST); mysql_cond_init(key_my_thread_var_suspend, &tmp->suspend, NULL); tmp->stack_ends_here= (char*)&tmp + STACK_DIRECTION * (long)my_thread_stack_size; mysql_mutex_lock(&THR_LOCK_threads); tmp->id= ++thread_id; ++THR_thread_count; mysql_mutex_unlock(&THR_LOCK_threads); tmp->init= 1; #ifndef DBUG_OFF /* Generate unique name for thread */ (void) my_thread_name(); #endif end: return error; }
int my_timer_initialize(void) { int rc; sigset_t set, old_set; if (sigfillset(&set)) { my_message_local(ERROR_LEVEL, "Failed to intialize signal set (errno=%d).", errno); return -1; } /* Temporarily block all signals. New thread will inherit signal mask of the current thread. */ if (pthread_sigmask(SIG_BLOCK, &set, &old_set)) return -1; /* Create a helper thread. */ rc= start_helper_thread(); /* Restore the signal mask. */ pthread_sigmask(SIG_SETMASK, &old_set, NULL); return rc; }
void my_thread_global_end(void) { struct timespec abstime; my_bool all_threads_killed= 1; set_timespec(&abstime, my_thread_end_wait_time); mysql_mutex_lock(&THR_LOCK_threads); while (THR_thread_count > 0) { int error= mysql_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads, &abstime); if (error == ETIMEDOUT || error == ETIME) { #ifndef _WIN32 /* We shouldn't give an error here, because if we don't have pthread_kill(), programs like mysqld can't ensure that all threads are killed when we enter here. */ if (THR_thread_count) /* purecov: begin inspected */ my_message_local(ERROR_LEVEL, "Error in my_thread_global_end(): " "%d threads didn't exit", THR_thread_count); /* purecov: end */ #endif all_threads_killed= 0; break; } } mysql_mutex_unlock(&THR_LOCK_threads); DBUG_ASSERT(THR_KEY_mysys_initialized); my_delete_thread_local_key(THR_KEY_mysys); THR_KEY_mysys_initialized= FALSE; #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP pthread_mutexattr_destroy(&my_fast_mutexattr); #endif #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP pthread_mutexattr_destroy(&my_errorcheck_mutexattr); #endif mysql_mutex_destroy(&THR_LOCK_malloc); mysql_mutex_destroy(&THR_LOCK_open); mysql_mutex_destroy(&THR_LOCK_lock); mysql_mutex_destroy(&THR_LOCK_myisam); mysql_mutex_destroy(&THR_LOCK_myisam_mmap); mysql_mutex_destroy(&THR_LOCK_heap); mysql_mutex_destroy(&THR_LOCK_net); mysql_mutex_destroy(&THR_LOCK_charset); if (all_threads_killed) { mysql_mutex_destroy(&THR_LOCK_threads); mysql_cond_destroy(&THR_COND_threads); } my_thread_global_init_done= 0; }
uint my_get_large_page_size(void) { uint size; DBUG_ENTER("my_get_large_page_size"); if (!(size = my_get_large_page_size_int())) my_message_local(WARNING_LEVEL, "Failed to determine large page size"); /* purecov: inspected */ DBUG_RETURN(size); }
uchar* my_large_malloc_int(size_t size, myf my_flags) { int shmid; uchar* ptr; struct shmid_ds buf; DBUG_ENTER("my_large_malloc_int"); /* Align block size to my_large_page_size */ size= MY_ALIGN(size, (size_t) my_large_page_size); shmid = shmget(IPC_PRIVATE, size, SHM_HUGETLB | SHM_R | SHM_W); if (shmid < 0) { if (my_flags & MY_WME) /* purecov: begin inspected */ my_message_local(WARNING_LEVEL, "Failed to allocate %lu bytes from HugeTLB memory." " errno %d", (ulong) size, errno); /* purecov: end */ DBUG_RETURN(NULL); } ptr = (uchar*) shmat(shmid, NULL, 0); if (ptr == (uchar *) -1) { if (my_flags& MY_WME) /* purecov: begin inspected */ my_message_local(WARNING_LEVEL, "Failed to attach shared memory segment," " errno %d", errno); /* purecov: end */ shmctl(shmid, IPC_RMID, &buf); DBUG_RETURN(NULL); } /* Remove the shared memory segment so that it will be automatically freed after memory is detached or process exits */ shmctl(shmid, IPC_RMID, &buf); DBUG_RETURN(ptr); }
void my_thread_end(void) { struct st_my_thread_var *tmp; tmp= _my_thread_var(); #ifdef EXTRA_DEBUG_THREADS my_message_local(INFORMATION_LEVEL, "my_thread_end(): tmp: 0x%lx " "pthread_self: 0x%lx thread_id: %ld", (long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L); #endif #ifdef HAVE_PSI_INTERFACE /* Remove the instrumentation for this thread. This must be done before trashing st_my_thread_var, because the LF_HASH depends on it. */ PSI_THREAD_CALL(delete_current_thread)(); #endif if (tmp && tmp->init) { #if !defined(DBUG_OFF) /* tmp->dbug is allocated inside DBUG library */ if (tmp->dbug) { DBUG_POP(); free(tmp->dbug); tmp->dbug=0; } #endif mysql_cond_destroy(&tmp->suspend); mysql_mutex_destroy(&tmp->mutex); free(tmp); /* Decrement counter for number of running threads. We are using this in my_thread_global_end() to wait until all threads have called my_thread_end and thus freed all memory they have allocated in my_thread_init() and DBUG_xxxx */ mysql_mutex_lock(&THR_LOCK_threads); DBUG_ASSERT(THR_thread_count != 0); if (--THR_thread_count == 0) mysql_cond_signal(&THR_COND_threads); mysql_mutex_unlock(&THR_LOCK_threads); } set_mysys_var(NULL); }
uchar* my_large_malloc(PSI_memory_key key, size_t size, myf my_flags) { uchar* ptr; DBUG_ENTER("my_large_malloc"); if (my_use_large_pages && my_large_page_size) { if ((ptr = my_large_malloc_int(size, my_flags)) != NULL) DBUG_RETURN(ptr); if (my_flags & MY_WME) my_message_local(WARNING_LEVEL, "Using conventional memory pool"); /* purecov: inspected */ } DBUG_RETURN(my_malloc(key, size, my_flags)); }
void my_print_open_files(void) { if (my_file_opened | my_stream_opened) { uint i; for (i= 0 ; i < my_file_limit ; i++) { if (my_file_info[i].type != UNOPEN) { my_message_local(INFORMATION_LEVEL, EE(EE_FILE_NOT_CLOSED), my_file_info[i].name, i); } } } }
my_bool my_thread_global_init(void) { int pth_ret; if (my_thread_global_init_done) return 0; my_thread_global_init_done= 1; #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP /* Set mutex type to "fast" a.k.a "adaptive" In this case the thread may steal the mutex from some other thread that is waiting for the same mutex. This will save us some context switches but may cause a thread to 'starve forever' while waiting for the mutex (not likely if the code within the mutex is short). */ pthread_mutexattr_init(&my_fast_mutexattr); pthread_mutexattr_settype(&my_fast_mutexattr, PTHREAD_MUTEX_ADAPTIVE_NP); #endif #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP /* Set mutex type to "errorcheck" */ pthread_mutexattr_init(&my_errorcheck_mutexattr); pthread_mutexattr_settype(&my_errorcheck_mutexattr, PTHREAD_MUTEX_ERRORCHECK); #endif DBUG_ASSERT(! THR_KEY_mysys_initialized); if ((pth_ret= my_create_thread_local_key(&THR_KEY_mysys, NULL)) != 0) { /* purecov: begin inspected */ my_message_local(ERROR_LEVEL, "Can't initialize threads: error %d", pth_ret); /* purecov: end */ return 1; } THR_KEY_mysys_initialized= TRUE; mysql_mutex_init(key_THR_LOCK_malloc, &THR_LOCK_malloc, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_THR_LOCK_open, &THR_LOCK_open, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_THR_LOCK_charset, &THR_LOCK_charset, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST); if (my_thread_init()) return 1; mysql_mutex_init(key_THR_LOCK_lock, &THR_LOCK_lock, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_THR_LOCK_myisam, &THR_LOCK_myisam, MY_MUTEX_INIT_SLOW); mysql_mutex_init(key_THR_LOCK_myisam_mmap, &THR_LOCK_myisam_mmap, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_THR_LOCK_heap, &THR_LOCK_heap, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_THR_LOCK_net, &THR_LOCK_net, MY_MUTEX_INIT_FAST); mysql_cond_init(key_THR_COND_threads, &THR_COND_threads); #ifdef _MSC_VER install_sigabrt_handler(); #endif return 0; }