summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/sys_vars/r/thread_pool_size_high.result11
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_size_basic.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_size_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_size_high.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_size_high.test14
-rw-r--r--sql/sql_plist.h5
-rw-r--r--sql/sys_vars.cc14
-rw-r--r--sql/threadpool.h3
-rw-r--r--sql/threadpool_common.cc1
-rw-r--r--sql/threadpool_unix.cc22
10 files changed, 64 insertions, 9 deletions
diff --git a/mysql-test/suite/sys_vars/r/thread_pool_size_high.result b/mysql-test/suite/sys_vars/r/thread_pool_size_high.result
new file mode 100644
index 00000000000..f581ae8e315
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/thread_pool_size_high.result
@@ -0,0 +1,11 @@
+SELECT @@global.thread_pool_size;
+@@global.thread_pool_size
+200
+SET @@global.thread_pool_size=150;
+SET @@global.thread_pool_size=200;
+SET @@global.thread_pool_size=201;
+Warnings:
+Warning 1292 Truncated incorrect thread_pool_size value: '201'
+SELECT @@global.thread_pool_size;
+@@global.thread_pool_size
+200
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_size_basic.opt b/mysql-test/suite/sys_vars/t/thread_pool_size_basic.opt
new file mode 100644
index 00000000000..7a2696875b8
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/thread_pool_size_basic.opt
@@ -0,0 +1 @@
+--loose-thread-handling=pool-of-threads
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_size_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_size_basic.test
index eeed58956a4..5d432eb9940 100644
--- a/mysql-test/suite/sys_vars/t/thread_pool_size_basic.test
+++ b/mysql-test/suite/sys_vars/t/thread_pool_size_basic.test
@@ -1,6 +1,7 @@
# uint global
--source include/not_windows.inc
--source include/not_embedded.inc
+--source include/have_pool_of_threads.inc
SET @start_global_value = @@global.thread_pool_size;
#
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_size_high.opt b/mysql-test/suite/sys_vars/t/thread_pool_size_high.opt
new file mode 100644
index 00000000000..fe54a37c4ce
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/thread_pool_size_high.opt
@@ -0,0 +1 @@
+--loose-thread-handling=pool-of-threads --loose-thread-pool-size=200
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_size_high.test b/mysql-test/suite/sys_vars/t/thread_pool_size_high.test
new file mode 100644
index 00000000000..761aeee2b0a
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/thread_pool_size_high.test
@@ -0,0 +1,14 @@
+--source include/not_windows.inc
+--source include/not_embedded.inc
+--source include/have_pool_of_threads.inc
+
+SELECT @@global.thread_pool_size;
+
+# Set lower value
+SET @@global.thread_pool_size=150;
+# Set original value
+SET @@global.thread_pool_size=200;
+# Try higher value
+SET @@global.thread_pool_size=201;
+
+SELECT @@global.thread_pool_size;
diff --git a/sql/sql_plist.h b/sql/sql_plist.h
index 2b6f1067321..e703b4c0f62 100644
--- a/sql/sql_plist.h
+++ b/sql/sql_plist.h
@@ -75,6 +75,11 @@ class I_P_List : public C, public I
*/
public:
I_P_List() : I(&m_first), m_first(NULL) {};
+ /*
+ empty() is used in many places in the code instead of a constructor, to
+ initialize a bzero-ed I_P_List instance.
+ */
+
inline void empty() { m_first= NULL; C::reset(); I::set_last(&m_first); }
inline bool is_empty() const { return (m_first == NULL); }
inline void push_front(T* a)
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index b97f2a9dc1e..8bb9f57157e 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -2298,6 +2298,18 @@ static bool fix_tp_min_threads(sys_var *, THD *, enum_var_type)
#ifndef _WIN32
+static bool check_threadpool_size(sys_var *self, THD *thd, set_var *var)
+{
+ ulonglong v= var->save_result.ulonglong_value;
+ if (v > threadpool_max_size)
+ {
+ var->save_result.ulonglong_value= threadpool_max_size;
+ return throw_bounds_warning(thd, self->name.str, true, true, v);
+ }
+ return false;
+}
+
+
static bool fix_threadpool_size(sys_var*, THD*, enum_var_type)
{
tp_set_threadpool_size(threadpool_size);
@@ -2342,7 +2354,7 @@ static Sys_var_uint Sys_threadpool_size(
"executing threads (threads in a waiting state do not count as executing).",
GLOBAL_VAR(threadpool_size), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(1, MAX_THREAD_GROUPS), DEFAULT(my_getncpus()), BLOCK_SIZE(1),
- NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_threadpool_size),
ON_UPDATE(fix_threadpool_size)
);
static Sys_var_uint Sys_threadpool_stall_limit(
diff --git a/sql/threadpool.h b/sql/threadpool.h
index 919836e5a57..c080e5ba343 100644
--- a/sql/threadpool.h
+++ b/sql/threadpool.h
@@ -13,12 +13,13 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define MAX_THREAD_GROUPS 128
+#define MAX_THREAD_GROUPS 100000
/* Threadpool parameters */
extern uint threadpool_min_threads; /* Minimum threads in pool */
extern uint threadpool_idle_timeout; /* Shutdown idle worker threads after this timeout */
extern uint threadpool_size; /* Number of parallel executing threads */
+extern uint threadpool_max_size;
extern uint threadpool_stall_limit; /* time interval in 10 ms units for stall checks*/
extern uint threadpool_max_threads; /* Maximum threads in pool */
extern uint threadpool_oversubscribe; /* Maximum active threads in group */
diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc
index 5be06f0bdc8..9e0cb07b86c 100644
--- a/sql/threadpool_common.cc
+++ b/sql/threadpool_common.cc
@@ -30,6 +30,7 @@
uint threadpool_min_threads;
uint threadpool_idle_timeout;
uint threadpool_size;
+uint threadpool_max_size;
uint threadpool_stall_limit;
uint threadpool_max_threads;
uint threadpool_oversubscribe;
diff --git a/sql/threadpool_unix.cc b/sql/threadpool_unix.cc
index dc2d8d999ef..717fb468769 100644
--- a/sql/threadpool_unix.cc
+++ b/sql/threadpool_unix.cc
@@ -147,7 +147,7 @@ struct thread_group_t
} MY_ALIGNED(512);
-static thread_group_t all_groups[MAX_THREAD_GROUPS];
+static thread_group_t *all_groups;
static uint group_count;
/**
@@ -517,7 +517,7 @@ static void* timer_thread(void *param)
timer->current_microtime= microsecond_interval_timer();
/* Check stalls in thread groups */
- for(i=0; i< array_elements(all_groups);i++)
+ for (i= 0; i < threadpool_max_size; i++)
{
if(all_groups[i].connection_count)
check_stall(&all_groups[i]);
@@ -907,6 +907,7 @@ int thread_group_init(thread_group_t *thread_group, pthread_attr_t* thread_attr)
thread_group->pollfd= -1;
thread_group->shutdown_pipe[0]= -1;
thread_group->shutdown_pipe[1]= -1;
+ thread_group->queue.empty();
DBUG_RETURN(0);
}
@@ -1510,10 +1511,18 @@ static void *worker_main(void *param)
bool tp_init()
{
DBUG_ENTER("tp_init");
+ threadpool_max_size= max(threadpool_size, 128);
+ all_groups= (thread_group_t *)
+ my_malloc(sizeof(thread_group_t) * threadpool_max_size, MYF(MY_WME|MY_ZEROFILL));
+ if (!all_groups)
+ {
+ threadpool_max_size= 0;
+ DBUG_RETURN(1);
+ }
threadpool_started= true;
scheduler_init();
- for(uint i=0; i < array_elements(all_groups); i++)
+ for (uint i= 0; i < threadpool_max_size; i++)
{
thread_group_init(&all_groups[i], get_connection_attrib());
}
@@ -1542,10 +1551,11 @@ void tp_end()
DBUG_VOID_RETURN;
stop_timer(&pool_timer);
- for(uint i=0; i< array_elements(all_groups); i++)
+ for (uint i= 0; i < threadpool_max_size; i++)
{
thread_group_close(&all_groups[i]);
}
+ my_free(all_groups);
threadpool_started= false;
DBUG_VOID_RETURN;
}
@@ -1604,9 +1614,7 @@ void tp_set_threadpool_stall_limit(uint limit)
int tp_get_idle_thread_count()
{
int sum=0;
- for(uint i= 0;
- i< array_elements(all_groups) && (all_groups[i].pollfd >= 0);
- i++)
+ for (uint i= 0; i < threadpool_max_size && all_groups[i].pollfd >= 0; i++)
{
sum+= (all_groups[i].thread_count - all_groups[i].active_thread_count);
}