diff options
author | Mathias Stearn <mathias@10gen.com> | 2017-03-22 17:04:16 -0400 |
---|---|---|
committer | Eddie Louie <eddie.louie@mongodb.com> | 2017-05-02 15:44:34 -0400 |
commit | b1f79e14f1a0f0a4b48600c54cd977668322169d (patch) | |
tree | 76f1f0368405167b417b6f3a8e61ef3a7799d824 | |
parent | edf81ac9673164b487534afc7047c789238be0f0 (diff) | |
download | mongo-b1f79e14f1a0f0a4b48600c54cd977668322169d.tar.gz |
SERVER-27727 Note location where thread is marked idle
(cherry picked from commit 8056164a27fcaa1429744f9f2ff039a3d8c39b6f)
32 files changed, 54 insertions, 47 deletions
diff --git a/buildscripts/gdb/mongo.py b/buildscripts/gdb/mongo.py index a607f55c06e..fceff2379a3 100644 --- a/buildscripts/gdb/mongo.py +++ b/buildscripts/gdb/mongo.py @@ -395,12 +395,12 @@ class BtIfActive(gdb.Command): def invoke(self, arg, _from_tty): try: - is_idle = gdb.parse_and_eval("mongo::for_debuggers::threadIsIdle") + idle_location = gdb.parse_and_eval("mongo::for_debuggers::idleThreadLocation") except gdb.error: - is_idle = False # If unsure, print a stack trace. + idle_location = None # If unsure, print a stack trace. - if is_idle: - print("Thread is idle") + if idle_location: + print("Thread is idle at " + idle_location.string()) else: gdb.execute("bt") diff --git a/src/mongo/db/auth/user_cache_invalidator_job.cpp b/src/mongo/db/auth/user_cache_invalidator_job.cpp index 479a2b7f7c8..961b69707d9 100644 --- a/src/mongo/db/auth/user_cache_invalidator_job.cpp +++ b/src/mongo/db/auth/user_cache_invalidator_job.cpp @@ -147,7 +147,7 @@ void UserCacheInvalidator::run() { lastInvalidationTime + Seconds(userCacheInvalidationIntervalSecs.load()); Date_t now = Date_t::now(); while (now < sleepUntil) { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; invalidationIntervalChangedCondition.wait_until(lock, sleepUntil.toSystemTimePoint()); sleepUntil = lastInvalidationTime + Seconds(userCacheInvalidationIntervalSecs.load()); now = Date_t::now(); diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp index 858875a7cb8..ec8de1c052e 100644 --- a/src/mongo/db/clientcursor.cpp +++ b/src/mongo/db/clientcursor.cpp @@ -272,7 +272,7 @@ public: cursorStatsTimedOut.increment( CursorManager::timeoutCursorsGlobal(&txn, t.millisReset())); } - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; sleepsecs(clientCursorMonitorFrequencySecs); } } diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 24ff0dcc942..3c05f89ea64 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -832,7 +832,7 @@ ExitCode _initAndListen(int listenPort) { exitCleanly(EXIT_CLEAN); } - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; return waitForShutdown(); } diff --git a/src/mongo/db/ftdc/controller.cpp b/src/mongo/db/ftdc/controller.cpp index a82b242e079..9e2987db0f9 100644 --- a/src/mongo/db/ftdc/controller.cpp +++ b/src/mongo/db/ftdc/controller.cpp @@ -178,7 +178,7 @@ void FTDCController::doLoop() { // Wait for the next run or signal to shutdown { stdx::unique_lock<stdx::mutex> lock(_mutex); - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; // We ignore spurious wakeups by just doing an iteration of the loop auto status = _condvar.wait_until(lock, next_time.toSystemTimePoint()); diff --git a/src/mongo/db/range_deleter.cpp b/src/mongo/db/range_deleter.cpp index ba00172e328..b97d9fae216 100644 --- a/src/mongo/db/range_deleter.cpp +++ b/src/mongo/db/range_deleter.cpp @@ -425,7 +425,7 @@ void RangeDeleter::doWork() { stdx::unique_lock<stdx::mutex> sl(_queueMutex); while (_taskQueue.empty()) { { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _taskQueueNotEmptyCV.wait_for( sl, Milliseconds(kNotEmptyTimeoutMillis).toSystemDuration()); } diff --git a/src/mongo/db/repl/noop_writer.cpp b/src/mongo/db/repl/noop_writer.cpp index 9329f4048fb..ef5780bda14 100644 --- a/src/mongo/db/repl/noop_writer.cpp +++ b/src/mongo/db/repl/noop_writer.cpp @@ -82,7 +82,7 @@ private: OperationContext& txn = *txnPtr; { stdx::unique_lock<stdx::mutex> lk(_mutex); - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _cv.wait_for(lk, waitTime.toSystemDuration(), [&] { return _inShutdown; }); if (_inShutdown) diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index f318a27682d..4868d7f4a75 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -1193,7 +1193,7 @@ void SnapshotThread::run() { break; } - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; newTimestampNotifier.wait(lock); } } diff --git a/src/mongo/db/repl/sync_source_feedback.cpp b/src/mongo/db/repl/sync_source_feedback.cpp index 0d2e794dc9f..4d395e376e6 100644 --- a/src/mongo/db/repl/sync_source_feedback.cpp +++ b/src/mongo/db/repl/sync_source_feedback.cpp @@ -183,7 +183,7 @@ void SyncSourceFeedback::run(executor::TaskExecutor* executor, BackgroundSync* b stdx::unique_lock<stdx::mutex> lock(_mtx); while (!_positionChanged && !_shutdownSignaled) { { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; if (_cond.wait_for(lock, keepAliveInterval.toSystemDuration()) != stdx::cv_status::timeout) { continue; diff --git a/src/mongo/db/s/balancer/balancer.cpp b/src/mongo/db/s/balancer/balancer.cpp index aaa5bfdbe50..36987fb81ec 100644 --- a/src/mongo/db/s/balancer/balancer.cpp +++ b/src/mongo/db/s/balancer/balancer.cpp @@ -468,7 +468,7 @@ void Balancer::_endRound(OperationContext* opCtx, Seconds waitTimeout) { _condVar.notify_all(); } - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _sleepFor(opCtx, waitTimeout); } diff --git a/src/mongo/db/service_entry_point_mongod.cpp b/src/mongo/db/service_entry_point_mongod.cpp index 4f89b7cdb38..5c8b0e6f5df 100644 --- a/src/mongo/db/service_entry_point_mongod.cpp +++ b/src/mongo/db/service_entry_point_mongod.cpp @@ -115,7 +115,7 @@ void ServiceEntryPointMongod::_sessionLoop(const transport::SessionHandle& sessi if (!inExhaust) { inMessage.reset(); auto status = [&] { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; return session->sourceMessage(&inMessage).wait(); }(); diff --git a/src/mongo/db/stats/snapshots.cpp b/src/mongo/db/stats/snapshots.cpp index c9255e10e62..921014f1b0c 100644 --- a/src/mongo/db/stats/snapshots.cpp +++ b/src/mongo/db/stats/snapshots.cpp @@ -114,7 +114,7 @@ void StatsSnapshotThread::run() { log() << "ERROR in SnapshotThread: " << redact(e.what()) << endl; } - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; sleepsecs(4); } } diff --git a/src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp b/src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp index 8a5c5241f6f..ea0a5b7d637 100644 --- a/src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp +++ b/src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp @@ -213,7 +213,7 @@ void JournalWriter::_journalWriterThread() { try { while (true) { Buffer* const buffer = [&] { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; return _journalQueue.blockingPop(); }(); diff --git a/src/mongo/db/storage/mmap_v1/file_allocator.cpp b/src/mongo/db/storage/mmap_v1/file_allocator.cpp index 451139d014a..fdd45b3e185 100644 --- a/src/mongo/db/storage/mmap_v1/file_allocator.cpp +++ b/src/mongo/db/storage/mmap_v1/file_allocator.cpp @@ -376,7 +376,7 @@ void FileAllocator::run(FileAllocator* fa) { { stdx::unique_lock<stdx::mutex> lk(fa->_pendingMutex); if (fa->_pending.size() == 0) { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; fa->_pendingUpdated.wait(lk); } } diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp index 92ff3d5aba9..c50a72d4ea4 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp @@ -114,7 +114,7 @@ public: ms = 100; } - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; sleepmillis(ms); } LOG(1) << "stopping " << name() << " thread"; diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp index be026dc88ca..c3ecbb0e55b 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp @@ -181,7 +181,7 @@ void WiredTigerRecordStore::OplogStones::awaitHasExcessStonesOrDead() { // Wait until kill() is called or there are too many oplog stones. stdx::unique_lock<stdx::mutex> lock(_oplogReclaimMutex); while (!_isDead && !hasExcessStones()) { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _oplogReclaimCv.wait(lock); } } @@ -1701,7 +1701,7 @@ void WiredTigerRecordStore::_oplogJournalThreadLoop(WiredTigerSessionCache* sess while (true) { stdx::unique_lock<stdx::mutex> lk(_uncommittedRecordIdsMutex); { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _opsWaitingForJournalCV.wait( lk, [&] { return _shuttingDown || !_opsWaitingForJournal.empty(); }); } diff --git a/src/mongo/db/ttl.cpp b/src/mongo/db/ttl.cpp index 591b43aeaee..9688f661578 100644 --- a/src/mongo/db/ttl.cpp +++ b/src/mongo/db/ttl.cpp @@ -89,7 +89,7 @@ public: while (!inShutdown()) { { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; sleepsecs(ttlMonitorSleepSecs); } diff --git a/src/mongo/executor/network_interface_asio.cpp b/src/mongo/executor/network_interface_asio.cpp index e64665b6b81..9056bd1a570 100644 --- a/src/mongo/executor/network_interface_asio.cpp +++ b/src/mongo/executor/network_interface_asio.cpp @@ -186,7 +186,7 @@ void NetworkInterfaceASIO::waitForWork() { stdx::unique_lock<stdx::mutex> lk(_executorMutex); // TODO: This can be restructured with a lambda. while (!_isExecutorRunnable) { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _isExecutorRunnableCondition.wait(lk); } _isExecutorRunnable = false; @@ -200,7 +200,7 @@ void NetworkInterfaceASIO::waitForWorkUntil(Date_t when) { if (waitTime <= Milliseconds(0)) { break; } - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _isExecutorRunnableCondition.wait_for(lk, waitTime.toSystemDuration()); } _isExecutorRunnable = false; diff --git a/src/mongo/s/catalog/replset_dist_lock_manager.cpp b/src/mongo/s/catalog/replset_dist_lock_manager.cpp index 10a8169a222..5e3e22fd51a 100644 --- a/src/mongo/s/catalog/replset_dist_lock_manager.cpp +++ b/src/mongo/s/catalog/replset_dist_lock_manager.cpp @@ -177,7 +177,7 @@ void ReplSetDistLockManager::doTask() { } stdx::unique_lock<stdx::mutex> lk(_mutex); - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _shutDownCV.wait_for(lk, _pingInterval.toSystemDuration(), [this] { return _isShutDown; }); } } diff --git a/src/mongo/s/query/cluster_cursor_cleanup_job.cpp b/src/mongo/s/query/cluster_cursor_cleanup_job.cpp index a1e11c9d523..159934b2f97 100644 --- a/src/mongo/s/query/cluster_cursor_cleanup_job.cpp +++ b/src/mongo/s/query/cluster_cursor_cleanup_job.cpp @@ -73,7 +73,7 @@ void ClusterCursorCleanupJob::run() { Milliseconds(cursorTimeoutMillis.load())); manager->incrementCursorsTimedOut(manager->reapZombieCursors()); - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; sleepsecs(clientCursorMonitorFrequencySecs); } } diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp index 52795659900..9177cccdb73 100644 --- a/src/mongo/s/server.cpp +++ b/src/mongo/s/server.cpp @@ -329,7 +329,7 @@ static ExitCode runMongosServer() { #endif // Block until shutdown. - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; return waitForShutdown(); } diff --git a/src/mongo/s/service_entry_point_mongos.cpp b/src/mongo/s/service_entry_point_mongos.cpp index 834875bc1b6..05d4b3180b2 100644 --- a/src/mongo/s/service_entry_point_mongos.cpp +++ b/src/mongo/s/service_entry_point_mongos.cpp @@ -87,7 +87,7 @@ void ServiceEntryPointMongos::_sessionLoop(const transport::SessionHandle& sessi // Source a Message from the client { auto status = [&] { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; return session->sourceMessage(&message).wait(); }(); diff --git a/src/mongo/s/sharding_uptime_reporter.cpp b/src/mongo/s/sharding_uptime_reporter.cpp index b65b32ca728..61a438dd93e 100644 --- a/src/mongo/s/sharding_uptime_reporter.cpp +++ b/src/mongo/s/sharding_uptime_reporter.cpp @@ -110,7 +110,7 @@ void ShardingUptimeReporter::startPeriodicThread() { } } - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; sleepFor(kUptimeReportInterval); } }); diff --git a/src/mongo/scripting/deadline_monitor.h b/src/mongo/scripting/deadline_monitor.h index 3f50abe5348..b3c5007c72d 100644 --- a/src/mongo/scripting/deadline_monitor.h +++ b/src/mongo/scripting/deadline_monitor.h @@ -151,7 +151,7 @@ private: // wait for a task to be added or a deadline to expire if (_nearestDeadlineWallclock > now) { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; if (_nearestDeadlineWallclock == Date_t::max()) { if ((interruptInterval.count() > 0) && (_nearestDeadlineWallclock - now > interruptInterval)) { diff --git a/src/mongo/scripting/mozjs/proxyscope.cpp b/src/mongo/scripting/mozjs/proxyscope.cpp index 3e9dddda072..ddec63772c7 100644 --- a/src/mongo/scripting/mozjs/proxyscope.cpp +++ b/src/mongo/scripting/mozjs/proxyscope.cpp @@ -342,7 +342,7 @@ void MozJSProxyScope::implThread(void* arg) { while (true) { stdx::unique_lock<stdx::mutex> lk(proxy->_mutex); { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; proxy->_condvar.wait(lk, [proxy] { return proxy->_state == State::ProxyRequest || proxy->_state == State::Shutdown; }); diff --git a/src/mongo/util/background.cpp b/src/mongo/util/background.cpp index 4c2085caf67..4fcd7b4ae1c 100644 --- a/src/mongo/util/background.cpp +++ b/src/mongo/util/background.cpp @@ -311,7 +311,7 @@ void PeriodicTaskRunner::run() { stdx::unique_lock<stdx::mutex> lock(_mutex); while (!_shutdownRequested) { { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; if (stdx::cv_status::timeout != _cond.wait_for(lock, waitTime.toSystemDuration())) continue; } diff --git a/src/mongo/util/background_thread_clock_source.cpp b/src/mongo/util/background_thread_clock_source.cpp index 21371973b3f..13a0b4488c6 100644 --- a/src/mongo/util/background_thread_clock_source.cpp +++ b/src/mongo/util/background_thread_clock_source.cpp @@ -73,7 +73,7 @@ void BackgroundThreadClockSource::_startTimerThread() { stdx::unique_lock<stdx::mutex> lock(_mutex); while (!_shutdownTimer) { { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; if (_condition.wait_for(lock, _granularity.toSystemDuration()) != stdx::cv_status::timeout) { continue; diff --git a/src/mongo/util/concurrency/idle_thread_block.cpp b/src/mongo/util/concurrency/idle_thread_block.cpp index 783ab4184cf..d81bbdecd7a 100644 --- a/src/mongo/util/concurrency/idle_thread_block.cpp +++ b/src/mongo/util/concurrency/idle_thread_block.cpp @@ -34,17 +34,17 @@ namespace mongo { namespace for_debuggers { // This needs external linkage to ensure that debuggers can use it. -MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL bool threadIsIdle = false; +MONGO_TRIVIALLY_CONSTRUCTIBLE_THREAD_LOCAL const char* idleThreadLocation = nullptr; } -using for_debuggers::threadIsIdle; +using for_debuggers::idleThreadLocation; -void IdleThreadBlock::beginIdleThreadBlock() { - invariant(!threadIsIdle); - threadIsIdle = true; +void IdleThreadBlock::beginIdleThreadBlock(const char* location) { + invariant(!idleThreadLocation); + idleThreadLocation = location; } void IdleThreadBlock::endIdleThreadBlock() { - invariant(threadIsIdle); - threadIsIdle = false; + invariant(idleThreadLocation); + idleThreadLocation = nullptr; } } diff --git a/src/mongo/util/concurrency/idle_thread_block.h b/src/mongo/util/concurrency/idle_thread_block.h index cfdcc35d277..aa54f81f7f7 100644 --- a/src/mongo/util/concurrency/idle_thread_block.h +++ b/src/mongo/util/concurrency/idle_thread_block.h @@ -27,12 +27,14 @@ #pragma once +#include <boost/preprocessor/stringize.hpp> + #include "mongo/base/disallow_copying.h" namespace mongo { /** - * Marks a thread as idle while in scope. + * Marks a thread as idle while in scope. Prefer to use the macro below. * * Our debugger scripts can hide idle threads when dumping all stacks. You should mark threads as * idle when printing the stack would just be unhelpful noise. IdleThreadBlocks are not allowed to @@ -43,8 +45,8 @@ class IdleThreadBlock { MONGO_DISALLOW_COPYING(IdleThreadBlock); public: - IdleThreadBlock() { - beginIdleThreadBlock(); + IdleThreadBlock(const char* location) { + beginIdleThreadBlock(location); } ~IdleThreadBlock() { endIdleThreadBlock(); @@ -52,8 +54,13 @@ public: // These should not be called by mongo C++ code. They are only public to allow exposing this // functionality to a C api. - static void beginIdleThreadBlock(); + static void beginIdleThreadBlock(const char* location); static void endIdleThreadBlock(); }; +/** + * Marks a thread idle for the rest of the current scope and passes file:line as the location. + */ +#define MONGO_IDLE_THREAD_BLOCK IdleThreadBlock markIdle(__FILE__ ":" BOOST_PP_STRINGIZE(__LINE__)) + } // namespace mongo diff --git a/src/mongo/util/concurrency/thread_pool.cpp b/src/mongo/util/concurrency/thread_pool.cpp index 5e0e7419adf..5ea024725e0 100644 --- a/src/mongo/util/concurrency/thread_pool.cpp +++ b/src/mongo/util/concurrency/thread_pool.cpp @@ -263,7 +263,7 @@ void ThreadPool::_consumeTasks() { LOG(3) << "Not reaping because the earliest retirement date is " << nextThreadRetirementDate; - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _workAvailable.wait_until(lk, nextThreadRetirementDate.toSystemTimePoint()); } else { // Since the number of threads is not more than minThreads, this thread is not @@ -272,7 +272,7 @@ void ThreadPool::_consumeTasks() { // would be eligible for retirement once they had no work left to do. LOG(3) << "waiting for work; I am one of " << _threads.size() << " thread(s);" << " the minimum number of threads is " << _options.minThreads; - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _workAvailable.wait(lk); } continue; diff --git a/src/mongo/util/net/listen.cpp b/src/mongo/util/net/listen.cpp index d30008cd62e..d3fa5acbc87 100644 --- a/src/mongo/util/net/listen.cpp +++ b/src/mongo/util/net/listen.cpp @@ -293,7 +293,7 @@ void Listener::initAndListen() { maxSelectTime.tv_sec = 0; maxSelectTime.tv_usec = 250000; const int ret = [&] { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; return select(maxfd + 1, fds, nullptr, nullptr, &maxSelectTime); }(); diff --git a/src/mongo/util/signal_handlers.cpp b/src/mongo/util/signal_handlers.cpp index a92a204a520..a52757fafc8 100644 --- a/src/mongo/util/signal_handlers.cpp +++ b/src/mongo/util/signal_handlers.cpp @@ -171,7 +171,7 @@ void signalProcessingThread() { while (true) { int actualSignal = 0; int status = [&] { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; return sigwait(&asyncSignals, &actualSignal); }(); fassert(16781, status == 0); |