diff options
-rw-r--r-- | mysql-test/suite/sys_vars/r/thread_pool_size_high.result | 11 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/thread_pool_size_basic.opt | 1 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/thread_pool_size_basic.test | 1 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/thread_pool_size_high.opt | 1 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/thread_pool_size_high.test | 14 | ||||
-rw-r--r-- | sql/sql_plist.h | 5 | ||||
-rw-r--r-- | sql/sys_vars.cc | 14 | ||||
-rw-r--r-- | sql/threadpool.h | 3 | ||||
-rw-r--r-- | sql/threadpool_common.cc | 1 | ||||
-rw-r--r-- | sql/threadpool_unix.cc | 22 |
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); } |