Skip to content

Commit 3080775

Browse files
committed
mod: thread counter optimization
1 parent 98b2ccb commit 3080775

File tree

6 files changed

+100
-23
lines changed

6 files changed

+100
-23
lines changed

sql/event_scheduler.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ bool post_init_event_thread(THD *thd) {
170170

171171
Global_THD_manager *thd_manager = Global_THD_manager::get_instance();
172172
thd_manager->add_thd(thd);
173-
thd_manager->inc_thread_running();
174173
return false;
175174
}
176175

@@ -190,7 +189,6 @@ void deinit_event_thread(THD *thd) {
190189
DBUG_PRINT("exit", ("Event thread finishing"));
191190
thd->release_resources();
192191
thd_manager->remove_thd(thd);
193-
thd_manager->dec_thread_running();
194192
delete thd;
195193
}
196194

sql/mysqld_thd_manager.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,32 @@ THD *Global_THD_manager::find_thd(Find_thd_with_id *func) {
315315
return nullptr;
316316
}
317317

318+
/**
319+
This class implements callback for do_for_all_thd().
320+
It counts the total number of running threads
321+
from global thread list.
322+
*/
323+
class Count_thread_running : public Do_THD_Impl {
324+
public:
325+
Count_thread_running() : m_count(0) {}
326+
~Count_thread_running() {}
327+
virtual void operator()(THD *thd) {
328+
if (thd->get_command() != COM_SLEEP) {
329+
m_count++;
330+
}
331+
}
332+
int get_count() { return m_count; }
333+
334+
private:
335+
int m_count;
336+
};
337+
338+
void Global_THD_manager::count_num_thread_running() {
339+
Count_thread_running count_thread_running;
340+
do_for_all_thd(&count_thread_running);
341+
atomic_num_thread_running = count_thread_running.get_count();
342+
}
343+
318344
void inc_thread_created() {
319345
Global_THD_manager::get_instance()->inc_thread_created();
320346
}

sql/mysqld_thd_manager.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,20 +148,15 @@ class Global_THD_manager {
148148
void remove_thd(THD *thd);
149149

150150
/**
151-
Retrieves thread running statistic variable.
152-
@return int Returns the total number of threads currently running
151+
Count thread running statistic variable.
153152
*/
154-
int get_num_thread_running() const { return atomic_num_thread_running; }
153+
void count_num_thread_running();
155154

156155
/**
157-
Increments thread running statistic variable.
158-
*/
159-
void inc_thread_running() { atomic_num_thread_running++; }
160-
161-
/**
162-
Decrements thread running statistic variable.
156+
Retrieves thread running statistic variable.
157+
@return int Returns the total number of threads currently running
163158
*/
164-
void dec_thread_running() { atomic_num_thread_running--; }
159+
int get_num_thread_running() const { return atomic_num_thread_running; }
165160

166161
/**
167162
Retrieves thread created statistic variable.

sql/sql_parse.cc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,7 +1599,6 @@ bool dispatch_command(THD *thd, const COM_DATA *com_data,
15991599
}
16001600
thd->set_query_id(next_query_id());
16011601
thd->reset_rewritten_query();
1602-
thd_manager->inc_thread_running();
16031602

16041603
if (!(server_command_flags[command] & CF_SKIP_QUESTIONS))
16051604
thd->status_var.questions++;
@@ -2265,8 +2264,6 @@ bool dispatch_command(THD *thd, const COM_DATA *com_data,
22652264
/* Prevent rewritten query from getting "stuck" in SHOW PROCESSLIST. */
22662265
thd->reset_rewritten_query();
22672266

2268-
thd_manager->dec_thread_running();
2269-
22702267
/* Freeing the memroot will leave the THD::work_part_info invalid. */
22712268
thd->work_part_info = nullptr;
22722269

storage/perfschema/pfs_variable.cc

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,17 @@ int PFS_status_variable_cache::do_materialize_global(void) {
11571157
false, /* threads */
11581158
true, /* THDs */
11591159
&visitor);
1160+
1161+
/*
1162+
Because of the reason described in
1163+
PFS_status_variable_cache::do_materialize_all(THD *unsafe_thd),
1164+
PFS_status_variable_cache::do_materialize_session(THD *unsafe_thd) and
1165+
PFS_status_variable_cache::do_materialize_session(PFS_thread *pfs_thread),
1166+
count_num_thread_running() cannot put together with
1167+
get_num_thread_running(), so count_num_thread_running() is put here.
1168+
*/
1169+
Global_THD_manager::get_instance()->count_num_thread_running();
1170+
11601171
/*
11611172
Build the status variable cache using the SHOW_VAR array as a reference.
11621173
Use the status totals collected from all threads.
@@ -1200,6 +1211,22 @@ int PFS_status_variable_cache::do_materialize_all(THD *unsafe_thd) {
12001211
init_show_var_array(OPT_SESSION, false);
12011212
}
12021213

1214+
/*
1215+
count_num_thread_running() counts the total number of running threads
1216+
from global thread list, using LOCK_thd_list to protect sharded
1217+
global thread list. In lock_order_dependencies.txt, the lock order
1218+
is that LOCK_thd_list must be locked before LOCK_thd_data. In this
1219+
function, LOCK_thd_data is already locked in get_THD(), Then manifest()
1220+
will call get_num_thread_running(). If get_num_thread_running() counts
1221+
and returns the num, the lock order will be incorrect, which may
1222+
lead to dead lock. To prevent this situation, get_num_thread_running()
1223+
is split into two part, one is still called get_num_thread_running()
1224+
which returns the num, the other is called count_num_thread_running()
1225+
which counts the num and should be called before get_THD() and
1226+
get_num_thread_running(). So count_num_thread_running() is put here.
1227+
*/
1228+
Global_THD_manager::get_instance()->count_num_thread_running();
1229+
12031230
/* Get and lock a validated THD from the thread manager. */
12041231
if ((m_safe_thd = get_THD(unsafe_thd)) != nullptr) {
12051232
/*
@@ -1249,6 +1276,22 @@ int PFS_status_variable_cache::do_materialize_session(THD *unsafe_thd) {
12491276
init_show_var_array(OPT_SESSION, true);
12501277
}
12511278

1279+
/*
1280+
count_num_thread_running() counts the total number of running threads
1281+
from global thread list, using LOCK_thd_list to protect sharded
1282+
global thread list. In lock_order_dependencies.txt, the lock order
1283+
is that LOCK_thd_list must be locked before LOCK_thd_data. In this
1284+
function, LOCK_thd_data is already locked in get_THD(), Then manifest()
1285+
will call get_num_thread_running(). If get_num_thread_running() counts
1286+
and returns the num, the lock order will be incorrect, which may
1287+
lead to dead lock. To prevent this situation, get_num_thread_running()
1288+
is split into two part, one is still called get_num_thread_running()
1289+
which returns the num, the other is called count_num_thread_running()
1290+
which counts the num and should be called before get_THD() and
1291+
get_num_thread_running(). So count_num_thread_running() is put here.
1292+
*/
1293+
Global_THD_manager::get_instance()->count_num_thread_running();
1294+
12521295
/* Get and lock a validated THD from the thread manager. */
12531296
if ((m_safe_thd = get_THD(unsafe_thd)) != nullptr) {
12541297
/*
@@ -1292,6 +1335,22 @@ int PFS_status_variable_cache::do_materialize_session(PFS_thread *pfs_thread) {
12921335
/* The SHOW_VAR array must be initialized externally. */
12931336
assert(m_initialized);
12941337

1338+
/*
1339+
count_num_thread_running() counts the total number of running threads
1340+
from global thread list, using LOCK_thd_list to protect sharded
1341+
global thread list. In lock_order_dependencies.txt, the lock order
1342+
is that LOCK_thd_list must be locked before LOCK_thd_data. In this
1343+
function, LOCK_thd_data is already locked in get_THD(), Then manifest()
1344+
will call get_num_thread_running(). If get_num_thread_running() counts
1345+
and returns the num, the lock order will be incorrect, which may
1346+
lead to dead lock. To prevent this situation, get_num_thread_running()
1347+
is split into two part, one is still called get_num_thread_running()
1348+
which returns the num, the other is called count_num_thread_running()
1349+
which counts the num and should be called before get_THD() and
1350+
get_num_thread_running(). So count_num_thread_running() is put here.
1351+
*/
1352+
Global_THD_manager::get_instance()->count_num_thread_running();
1353+
12951354
/* Get and lock a validated THD from the thread manager. */
12961355
if ((m_safe_thd = get_THD(pfs_thread)) != nullptr) {
12971356
/*
@@ -1343,6 +1402,16 @@ int PFS_status_variable_cache::do_materialize_client(PFS_client *pfs_client) {
13431402
*/
13441403
m_sum_client_status(pfs_client, &status_totals);
13451404

1405+
/*
1406+
Because of the reason described in
1407+
PFS_status_variable_cache::do_materialize_all(THD *unsafe_thd),
1408+
PFS_status_variable_cache::do_materialize_session(THD *unsafe_thd) and
1409+
PFS_status_variable_cache::do_materialize_session(PFS_thread *pfs_thread),
1410+
count_num_thread_running() cannot put together with
1411+
get_num_thread_running(), so count_num_thread_running() is put here.
1412+
*/
1413+
Global_THD_manager::get_instance()->count_num_thread_running();
1414+
13461415
/*
13471416
Build the status variable cache using the SHOW_VAR array as a reference and
13481417
the status totals collected from threads associated with this client.

unittest/gunit/thd_manager-t.cc

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,6 @@ TEST_F(ThreadManagerTest, AddRemoveTHDWithGuard) {
8282
EXPECT_EQ(0U, thd_manager->get_thd_count());
8383
}
8484

85-
TEST_F(ThreadManagerTest, IncDecThreadRunning) {
86-
EXPECT_EQ(0, thd_manager->get_num_thread_running());
87-
thd_manager->inc_thread_running();
88-
EXPECT_EQ(1, thd_manager->get_num_thread_running());
89-
thd_manager->dec_thread_running();
90-
EXPECT_EQ(0, thd_manager->get_num_thread_running());
91-
}
92-
9385
TEST_F(ThreadManagerTest, IncThreadCreated) {
9486
EXPECT_EQ(0U, thd_manager->get_num_thread_created());
9587
thd_manager->inc_thread_created();

0 commit comments

Comments
 (0)