예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
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);
}
예제 #6
0
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);
}
예제 #7
0
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);
}
예제 #8
0
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));
}
예제 #9
0
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);
      }
    }
  }
}
예제 #10
0
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;
}