scheduler.cc 4.42 KB
Newer Older
1
/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
unknown's avatar
unknown committed
2 3 4 5 6 7 8 9 10 11 12 13

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
unknown's avatar
unknown committed
15 16 17 18 19 20 21 22 23

/*
  Implementation for the thread scheduler
*/

#ifdef USE_PRAGMA_INTERFACE
#pragma implementation
#endif

24
#include "sql_connect.h"         // init_new_connection_handler_thread
25
#include "scheduler.h"
Sergei Golubchik's avatar
Sergei Golubchik committed
26 27
#include "mysqld.h"
#include "sql_class.h"
28
#include "sql_callback.h"
unknown's avatar
unknown committed
29 30

/*
31 32
  End connection, in case when we are using 'no-threads'
*/
unknown's avatar
unknown committed
33

34 35 36 37 38 39
static bool no_threads_end(THD *thd, bool put_in_cache)
{
  unlink_thd(thd);
  mysql_mutex_unlock(&LOCK_thread_count);
  return 1;                                     // Abort handle_one_connection
}
unknown's avatar
unknown committed
40

41 42 43
/** @internal
  Helper functions to allow mysys to call the thread scheduler when
  waiting for locks.
unknown's avatar
unknown committed
44 45
*/

46
/**@{*/
Mikael Ronstrom's avatar
Mikael Ronstrom committed
47 48
extern "C"
{
49
static void scheduler_wait_lock_begin(void) {
Sergei Golubchik's avatar
Sergei Golubchik committed
50
  THD *thd=current_thd;
51 52
  if(thd)
    MYSQL_CALLBACK(thd->scheduler, thd_wait_begin, (thd, THD_WAIT_TABLE_LOCK));
53
}
unknown's avatar
unknown committed
54

55
static void scheduler_wait_lock_end(void) {
Sergei Golubchik's avatar
Sergei Golubchik committed
56
  THD *thd=current_thd;
57 58
  if(thd)
    MYSQL_CALLBACK(thd->scheduler, thd_wait_end, (thd));
59
}
60 61

static void scheduler_wait_sync_begin(void) {
Sergei Golubchik's avatar
Sergei Golubchik committed
62
  THD *thd=current_thd;
63 64
  if(thd)
   MYSQL_CALLBACK(thd->scheduler, thd_wait_begin, (thd, THD_WAIT_TABLE_LOCK));
65 66 67
}

static void scheduler_wait_sync_end(void) {
Sergei Golubchik's avatar
Sergei Golubchik committed
68
  THD *thd=current_thd;
69 70
  if(thd)
    MYSQL_CALLBACK(thd->scheduler, thd_wait_end, (thd));
71
}
Mikael Ronstrom's avatar
Mikael Ronstrom committed
72
};
73 74 75 76 77 78 79 80 81
/**@}*/

/**
  Common scheduler init function.

  The scheduler is either initialized by calling
  one_thread_scheduler() or one_thread_per_connection_scheduler() in
  mysqld.cc, so this init function will always be called.
 */
82
void scheduler_init() {
83 84 85 86
  thr_set_lock_wait_callback(scheduler_wait_lock_begin,
                             scheduler_wait_lock_end);
  thr_set_sync_wait_callback(scheduler_wait_sync_begin,
                             scheduler_wait_sync_end);
87
}
unknown's avatar
unknown committed
88 89

/*
90
  Initialize scheduler for --thread-handling=one-thread-per-connection
unknown's avatar
unknown committed
91 92
*/

93
#ifndef EMBEDDED_LIBRARY
94
void one_thread_per_connection_scheduler(scheduler_functions *func,
Sergei Golubchik's avatar
Sergei Golubchik committed
95 96
    ulong *arg_max_connections,
    uint *arg_connection_count)
unknown's avatar
unknown committed
97
{
98
  scheduler_init();
99 100 101 102 103 104
  func->max_threads= *arg_max_connections + 1;
  func->max_connections= arg_max_connections;
  func->connection_count= arg_connection_count;
  func->init_new_connection_thread= init_new_connection_handler_thread;
  func->add_connection= create_thread_to_handle_connection;
  func->end_thread= one_thread_per_connection_end;
unknown's avatar
unknown committed
105
}
106
#endif
unknown's avatar
unknown committed
107 108 109 110 111

/*
  Initailize scheduler for --thread-handling=no-threads
*/

112
void one_thread_scheduler(scheduler_functions *func)
unknown's avatar
unknown committed
113
{
114
  scheduler_init();
115 116 117 118 119 120 121 122 123
  func->max_threads= 1;
  //max_connections= 1;
  func->max_connections= &max_connections;
  func->connection_count= &connection_count;
#ifndef EMBEDDED_LIBRARY
  func->init_new_connection_thread= init_new_connection_handler_thread;
  func->add_connection= handle_connection_in_main_thread;
#endif
  func->end_thread= no_threads_end;
unknown's avatar
unknown committed
124 125 126
}


127

128
/*
Sergei Golubchik's avatar
Sergei Golubchik committed
129 130
  no pluggable schedulers in mariadb.
  when we'll want it, we'll do it properly
131
*/
Sergei Golubchik's avatar
Sergei Golubchik committed
132
#if 0
133

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
static scheduler_functions *saved_thread_scheduler;
static uint saved_thread_handling;

extern "C"
int my_thread_scheduler_set(scheduler_functions *scheduler)
{
  DBUG_ASSERT(scheduler != 0);

  if (scheduler == NULL)
    return 1;

  saved_thread_scheduler= thread_scheduler;
  saved_thread_handling= thread_handling;
  thread_scheduler= scheduler;
  // Scheduler loaded dynamically
  thread_handling= SCHEDULER_TYPES_COUNT;
  return 0;
}


extern "C"
int my_thread_scheduler_reset()
{
  DBUG_ASSERT(saved_thread_scheduler != NULL);

  if (saved_thread_scheduler == NULL)
    return 1;

  thread_scheduler= saved_thread_scheduler;
  thread_handling= saved_thread_handling;
  saved_thread_scheduler= 0;
  return 0;
}
Sergei Golubchik's avatar
Sergei Golubchik committed
167 168 169
#else
extern "C" int my_thread_scheduler_set(scheduler_functions *scheduler)
{ return 1; }
170

Sergei Golubchik's avatar
Sergei Golubchik committed
171 172
extern "C" int my_thread_scheduler_reset()
{ return 1; }
173
#endif
174