aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/core/util/exec_on_stall.h
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2018-06-05 11:54:41 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-06-05 11:59:25 -0700
commitb1fd2ef4d02719cd929fa574796b2c080a21a9ee (patch)
tree437b20f1b8a4b786f09c2c04f733cf7df6ec5ed7 /tensorflow/core/util/exec_on_stall.h
parente86d969c07c14f8790f364d0b48724848db48d4e (diff)
Add core/util/exec_on_stall.h a tool for debugging deadlocks with
less logging. PiperOrigin-RevId: 199334548
Diffstat (limited to 'tensorflow/core/util/exec_on_stall.h')
-rw-r--r--tensorflow/core/util/exec_on_stall.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/tensorflow/core/util/exec_on_stall.h b/tensorflow/core/util/exec_on_stall.h
new file mode 100644
index 0000000000..5c8f9d2324
--- /dev/null
+++ b/tensorflow/core/util/exec_on_stall.h
@@ -0,0 +1,89 @@
+/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef TENSORFLOW_CORE_UTIL_EXEC_ON_STALL_H_
+#define TENSORFLOW_CORE_UTIL_EXEC_ON_STALL_H_
+
+#include <functional>
+
+#include "tensorflow/core/platform/env.h"
+#include "tensorflow/core/platform/mutex.h"
+
+namespace tensorflow {
+
+// An object that executes a particular function only if it
+// is not deleted within the allotted number of seconds.
+//
+// This can be useful in diagnosing deadlocks, stalls and memory leaks
+// without logging too agressively.
+class ExecuteOnStall {
+ public:
+ // delay_secs: If the object still exists after this many seconds,
+ // execute f.
+ // f: The function to be executed, for example a detailed log of the
+ // the state of an object to which this is attached.
+ // poll_microseconds: The spawned thread will wake and test whether
+ // the destructor has been invoked this frequently.
+ ExecuteOnStall(int delay_secs, std::function<void()> f,
+ int32 poll_microseconds = 100)
+ : disabled_(false),
+ joined_(false),
+ env_(Env::Default()),
+ f_(f),
+ poll_microseconds_(poll_microseconds) {
+ deadline_ = env_->NowMicros() + 1000000 * delay_secs;
+ env_->SchedClosure([this]() {
+ while (env_->NowMicros() < deadline_) {
+ {
+ mutex_lock l(mu_);
+ if (disabled_) {
+ break;
+ }
+ }
+ env_->SleepForMicroseconds(poll_microseconds_);
+ }
+ {
+ mutex_lock l(mu_);
+ if (!disabled_) {
+ f_();
+ }
+ joined_ = true;
+ cond_var_.notify_all();
+ }
+ });
+ }
+
+ ~ExecuteOnStall() {
+ // Wait for spawned thread to terminate.
+ mutex_lock l(mu_);
+ disabled_ = true;
+ if (!joined_) {
+ cond_var_.wait(l);
+ }
+ }
+
+ private:
+ mutex mu_;
+ condition_variable cond_var_;
+ bool disabled_ GUARDED_BY(mu_);
+ bool joined_ GUARDED_BY(mu_);
+ Env* env_;
+ std::function<void()> f_;
+ int64 deadline_;
+ int32 poll_microseconds_;
+};
+
+} // namespace tensorflow
+#endif // TENSORFLOW_CORE_UTIL_EXEC_ON_STALL_H_