diff options
author | Mathias Stearn <mathias@10gen.com> | 2017-03-22 17:04:16 -0400 |
---|---|---|
committer | Mathias Stearn <mathias@10gen.com> | 2017-03-24 16:13:26 -0400 |
commit | 8056164a27fcaa1429744f9f2ff039a3d8c39b6f (patch) | |
tree | 05b2e40aa73cb59e7c18ba2b63c37cb4b956c589 | |
parent | 63d1f4c049587e7923a1154fc31f29bc190316df (diff) | |
download | mongo-8056164a27fcaa1429744f9f2ff039a3d8c39b6f.tar.gz |
SERVER-27727 Note location where thread is marked idle
32 files changed, 55 insertions, 48 deletions
diff --git a/buildscripts/gdb/mongo.py b/buildscripts/gdb/mongo.py index ee2227ea790..a5ae56cdd2e 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 56a6bd29e86..a86cad229b4 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 6fd80a3365b..9bf48a6d379 100644 --- a/src/mongo/db/clientcursor.cpp +++ b/src/mongo/db/clientcursor.cpp @@ -280,7 +280,7 @@ public: cursorStatsTimedOut.increment( CursorManager::timeoutCursorsGlobal(&opCtx, t.millisReset())); } - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; sleepsecs(clientCursorMonitorFrequencySecs.load()); } } diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 686d2de5b76..07d790b9a48 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -736,7 +736,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 cfd983bc686..19af20ffae1 100644 --- a/src/mongo/db/range_deleter.cpp +++ b/src/mongo/db/range_deleter.cpp @@ -427,7 +427,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 5e2abd17dea..c82eb575ae1 100644 --- a/src/mongo/db/repl/noop_writer.cpp +++ b/src/mongo/db/repl/noop_writer.cpp @@ -83,7 +83,7 @@ private: OperationContext& opCtx = *opCtxPtr; { 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 2b319583ccd..51a44a672ed 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -1214,7 +1214,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 5f8826d68c0..dceeb7422d2 100644 --- a/src/mongo/db/repl/sync_source_feedback.cpp +++ b/src/mongo/db/repl/sync_source_feedback.cpp @@ -163,7 +163,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 838142fe6f2..d23c1220874 100644 --- a/src/mongo/db/s/balancer/balancer.cpp +++ b/src/mongo/db/s/balancer/balancer.cpp @@ -452,7 +452,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 ca329af07e1..376a13b695f 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 8f36cfa3cb7..c5ab5832534 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 6a4bfcc8580..985db4864a0 100644 --- a/src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp +++ b/src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp @@ -215,7 +215,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 86f96d0c9de..e0810c49d2d 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 67fad96475d..7dd943f8d33 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 f6b698467ee..46dadad3467 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); } } @@ -1711,7 +1711,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 e51785cf8c4..446f73500fa 100644 --- a/src/mongo/db/ttl.cpp +++ b/src/mongo/db/ttl.cpp @@ -89,7 +89,7 @@ public: while (!globalInShutdownDeprecated()) { { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; sleepsecs(ttlMonitorSleepSecs.load()); } diff --git a/src/mongo/executor/network_interface_asio.cpp b/src/mongo/executor/network_interface_asio.cpp index 3fbca90cd2c..22666b05672 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 dfd3ab32e12..d31bb4f9365 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 441c4bbf235..c222abf921f 100644 --- a/src/mongo/s/query/cluster_cursor_cleanup_job.cpp +++ b/src/mongo/s/query/cluster_cursor_cleanup_job.cpp @@ -72,7 +72,7 @@ void ClusterCursorCleanupJob::run() { Milliseconds(cursorTimeoutMillis.load())); manager->incrementCursorsTimedOut(manager->reapZombieCursors()); - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; sleepsecs(clientCursorMonitorFrequencySecs.load()); } } diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp index 427574a1741..8e6ea2edefd 100644 --- a/src/mongo/s/server.cpp +++ b/src/mongo/s/server.cpp @@ -357,7 +357,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 de00c49479a..5703788161b 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 8ee3bd59325..8db978218fa 100644 --- a/src/mongo/s/sharding_uptime_reporter.cpp +++ b/src/mongo/s/sharding_uptime_reporter.cpp @@ -113,7 +113,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 58084e88ad1..8da2bae11e0 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 4ace0a99ad8..ecb60348d90 100644 --- a/src/mongo/util/background_thread_clock_source.cpp +++ b/src/mongo/util/background_thread_clock_source.cpp @@ -116,12 +116,12 @@ void BackgroundThreadClockSource::_startTimerThread() { } else { // Stop running if nothing has read the time since we last updated the time. _current.store(0); - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _condition.wait(lock, [this] { return _inShutdown || _current.load() != 0; }); } const auto sleepUntil = Date_t::fromMillisSinceEpoch(_current.load()) + _granularity; - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; _clockSource->waitForConditionUntil( _condition, lock, sleepUntil, [this] { return _inShutdown; }); } 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 da0e47629f4..67e9f394308 100644 --- a/src/mongo/util/net/listen.cpp +++ b/src/mongo/util/net/listen.cpp @@ -296,7 +296,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 220631c9732..66ba2c04ed9 100644 --- a/src/mongo/util/signal_handlers.cpp +++ b/src/mongo/util/signal_handlers.cpp @@ -171,7 +171,7 @@ void signalProcessingThread(LogFileStatus rotate) { while (true) { int actualSignal = 0; int status = [&] { - IdleThreadBlock markIdle; + MONGO_IDLE_THREAD_BLOCK; return sigwait(&asyncSignals, &actualSignal); }(); fassert(16781, status == 0); |