Improve test duration under Valgrind 83/78083/3
authorJames Harrison <00jamesh@gmail.com>
Fri, 12 May 2017 15:33:42 +0000 (16:33 +0100)
committerDave Rigby <daver@couchbase.com>
Wed, 17 May 2017 10:20:40 +0000 (10:20 +0000)
Compared to the parent commit, this change reduces the run time of tests
under Valgrind from 1051s (17m31) to 295s (4m55) - roughly a 72%
reduction.

This reduction comes from the teardown phase of a number of tests.
When destroying an ExecutorPool, all the taskables must be unregistered.

Prior to this change, when unregistering the last taskable from an
ExecutorPool, all threads were woken and prevented from sleeping (by
pretending there is work, numReadyTasks[idx]++) /before/ they were
marked as dead. During this time the woken threads all busy-wait for
work.

Usually this wouldn't be too problematic because the main thread would
mark them dead soon after. However, under Valgrind only one thread can
execute at a time, and it can take significant time before the main
thread is able to mark all of the ExecutorThreads as dead.

This change simply marks them dead before waking them. They check their
status, find it is "dead", and exit.

Change-Id: Ic88ccec46ac26d511a18a1370d20117af173703b
Reviewed-on: http://review.couchbase.org/78083
Tested-by: Build Bot <build@couchbase.com>
Reviewed-by: Dave Rigby <daver@couchbase.com>
src/executorpool.cc

index 5206a2e..332eb36 100644 (file)
@@ -690,19 +690,14 @@ void ExecutorPool::_unregisterTaskable(Taskable& taskable, bool force) {
                     "Attempting to unregister taskable '" +
                     taskable.getName() + "' but taskLocator is not empty");
         }
-        for (unsigned int idx = 0; idx < numTaskSets; idx++) {
-            TaskQueue *sleepQ = getSleepQ(idx);
-            size_t wakeAll = threadQ.size();
-            numReadyTasks[idx]++; // this prevents woken workers from sleeping
-            totReadyTasks++;
-            sleepQ->doWake(wakeAll);
-        }
         for (size_t tidx = 0; tidx < threadQ.size(); ++tidx) {
             threadQ[tidx]->stop(false); // only set state to DEAD
         }
+
         for (unsigned int idx = 0; idx < numTaskSets; idx++) {
-            numReadyTasks[idx]--; // once woken reset the ready tasks
-            totReadyTasks--;
+            TaskQueue *sleepQ = getSleepQ(idx);
+            size_t wakeAll = threadQ.size();
+            sleepQ->doWake(wakeAll);
         }
 
         for (size_t tidx = 0; tidx < threadQ.size(); ++tidx) {