Skip to content

Commit 2ce2216

Browse files
committedDec 1, 2016
Use Timeout<> in Process::RunThreadPlan
Summary: Since the function is way too big already, I tried at least to factor out the timeout computation stuff into a separate function. I've tried to make the new code semantically equivalent, and it also makes sense when I look at it as a done deal. Reviewers: jingham Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D27258 llvm-svn: 288326
1 parent 33af6fe commit 2ce2216

File tree

1 file changed

+72
-94
lines changed

1 file changed

+72
-94
lines changed
 

‎lldb/source/Target/Process.cpp

+72-94
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <mutex>
1414

1515
// Other libraries and framework includes
16+
#include "llvm/Support/ScopedPrinter.h"
1617
// Project includes
1718
#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
1819
#include "lldb/Breakpoint/BreakpointLocation.h"
@@ -4799,6 +4800,45 @@ class RestorePlanState {
47994800
};
48004801
} // anonymous namespace
48014802

4803+
static microseconds
4804+
GetOneThreadExpressionTimeout(const EvaluateExpressionOptions &options) {
4805+
const milliseconds default_one_thread_timeout(250);
4806+
4807+
// If the overall wait is forever, then we don't need to worry about it.
4808+
if (options.GetTimeoutUsec() == 0) {
4809+
if (options.GetOneThreadTimeoutUsec() != 0)
4810+
return microseconds(options.GetOneThreadTimeoutUsec());
4811+
return default_one_thread_timeout;
4812+
}
4813+
4814+
// If the one thread timeout is set, use it.
4815+
if (options.GetOneThreadTimeoutUsec() != 0)
4816+
return microseconds(options.GetOneThreadTimeoutUsec());
4817+
4818+
// Otherwise use half the total timeout, bounded by the
4819+
// default_one_thread_timeout.
4820+
return std::min<microseconds>(default_one_thread_timeout,
4821+
microseconds(options.GetTimeoutUsec()) / 2);
4822+
}
4823+
4824+
static Timeout<std::micro>
4825+
GetExpressionTimeout(const EvaluateExpressionOptions &options,
4826+
bool before_first_timeout) {
4827+
// If we are going to run all threads the whole time, or if we are only
4828+
// going to run one thread, we can just return the overall timeout.
4829+
if (!options.GetStopOthers() || !options.GetTryAllThreads())
4830+
return ConvertTimeout(microseconds(options.GetTimeoutUsec()));
4831+
4832+
if (before_first_timeout)
4833+
return GetOneThreadExpressionTimeout(options);
4834+
4835+
if (options.GetTimeoutUsec() == 0)
4836+
return llvm::None;
4837+
else
4838+
return microseconds(options.GetTimeoutUsec()) -
4839+
GetOneThreadExpressionTimeout(options);
4840+
}
4841+
48024842
ExpressionResults
48034843
Process::RunThreadPlan(ExecutionContext &exe_ctx,
48044844
lldb::ThreadPlanSP &thread_plan_sp,
@@ -4879,6 +4919,16 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
48794919
}
48804920
}
48814921

4922+
// Make sure the timeout values make sense. The one thread timeout needs to be
4923+
// smaller than the overall timeout.
4924+
if (options.GetOneThreadTimeoutUsec() != 0 && options.GetTimeoutUsec() != 0 &&
4925+
options.GetTimeoutUsec() < options.GetOneThreadTimeoutUsec()) {
4926+
diagnostic_manager.PutString(eDiagnosticSeverityError,
4927+
"RunThreadPlan called with one thread "
4928+
"timeout greater than total timeout");
4929+
return eExpressionSetupError;
4930+
}
4931+
48824932
StackID ctx_frame_id = selected_frame_sp->GetStackID();
48834933

48844934
// N.B. Running the target may unset the currently selected thread and frame.
@@ -4985,67 +5035,20 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
49855035
// that we have to halt the target.
49865036
bool do_resume = true;
49875037
bool handle_running_event = true;
4988-
const uint64_t default_one_thread_timeout_usec = 250000;
49895038

49905039
// This is just for accounting:
49915040
uint32_t num_resumes = 0;
49925041

4993-
uint32_t timeout_usec = options.GetTimeoutUsec();
4994-
uint32_t one_thread_timeout_usec;
4995-
uint32_t all_threads_timeout_usec = 0;
4996-
49975042
// If we are going to run all threads the whole time, or if we are only
4998-
// going to run one thread,
4999-
// then we don't need the first timeout. So we set the final timeout, and
5000-
// pretend we are after the
5001-
// first timeout already.
5002-
5003-
if (!options.GetStopOthers() || !options.GetTryAllThreads()) {
5043+
// going to run one thread, then we don't need the first timeout. So we
5044+
// pretend we are after the first timeout already.
5045+
if (!options.GetStopOthers() || !options.GetTryAllThreads())
50045046
before_first_timeout = false;
5005-
one_thread_timeout_usec = 0;
5006-
all_threads_timeout_usec = timeout_usec;
5007-
} else {
5008-
uint32_t option_one_thread_timeout = options.GetOneThreadTimeoutUsec();
5009-
5010-
// If the overall wait is forever, then we only need to set the one thread
5011-
// timeout:
5012-
if (timeout_usec == 0) {
5013-
if (option_one_thread_timeout != 0)
5014-
one_thread_timeout_usec = option_one_thread_timeout;
5015-
else
5016-
one_thread_timeout_usec = default_one_thread_timeout_usec;
5017-
} else {
5018-
// Otherwise, if the one thread timeout is set, make sure it isn't
5019-
// longer than the overall timeout,
5020-
// and use it, otherwise use half the total timeout, bounded by the
5021-
// default_one_thread_timeout_usec.
5022-
uint64_t computed_one_thread_timeout;
5023-
if (option_one_thread_timeout != 0) {
5024-
if (timeout_usec < option_one_thread_timeout) {
5025-
diagnostic_manager.PutString(eDiagnosticSeverityError,
5026-
"RunThreadPlan called without one "
5027-
"thread timeout greater than total "
5028-
"timeout");
5029-
return eExpressionSetupError;
5030-
}
5031-
computed_one_thread_timeout = option_one_thread_timeout;
5032-
} else {
5033-
computed_one_thread_timeout = timeout_usec / 2;
5034-
if (computed_one_thread_timeout > default_one_thread_timeout_usec)
5035-
computed_one_thread_timeout = default_one_thread_timeout_usec;
5036-
}
5037-
one_thread_timeout_usec = computed_one_thread_timeout;
5038-
all_threads_timeout_usec = timeout_usec - one_thread_timeout_usec;
5039-
}
5040-
}
50415047

50425048
if (log)
5043-
log->Printf(
5044-
"Stop others: %u, try all: %u, before_first: %u, one thread: %" PRIu32
5045-
" - all threads: %" PRIu32 ".\n",
5046-
options.GetStopOthers(), options.GetTryAllThreads(),
5047-
before_first_timeout, one_thread_timeout_usec,
5048-
all_threads_timeout_usec);
5049+
log->Printf("Stop others: %u, try all: %u, before_first: %u.\n",
5050+
options.GetStopOthers(), options.GetTryAllThreads(),
5051+
before_first_timeout);
50495052

50505053
// This isn't going to work if there are unfetched events on the queue.
50515054
// Are there cases where we might want to run the remaining events here, and
@@ -5083,8 +5086,6 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
50835086
// The expression evaluation should still succeed.
50845087
bool miss_first_event = true;
50855088
#endif
5086-
std::chrono::microseconds timeout = std::chrono::microseconds(0);
5087-
50885089
while (true) {
50895090
// We usually want to resume the process if we get to the top of the loop.
50905091
// The only exception is if we get two running events with no intervening
@@ -5178,36 +5179,21 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
51785179
log->PutCString("Process::RunThreadPlan(): waiting for next event.");
51795180
}
51805181

5181-
if (before_first_timeout) {
5182-
if (options.GetTryAllThreads())
5183-
timeout = std::chrono::microseconds(one_thread_timeout_usec);
5184-
else
5185-
timeout = std::chrono::microseconds(timeout_usec);
5186-
} else {
5187-
if (timeout_usec == 0)
5188-
timeout = std::chrono::microseconds(0);
5189-
else
5190-
timeout = std::chrono::microseconds(all_threads_timeout_usec);
5191-
}
5192-
51935182
do_resume = true;
51945183
handle_running_event = true;
51955184

51965185
// Now wait for the process to stop again:
51975186
event_sp.reset();
51985187

5188+
Timeout<std::micro> timeout =
5189+
GetExpressionTimeout(options, before_first_timeout);
51995190
if (log) {
5200-
if (timeout.count()) {
5201-
log->Printf(
5202-
"Process::RunThreadPlan(): about to wait - now is %llu - "
5203-
"endpoint is %llu",
5204-
static_cast<unsigned long long>(
5205-
std::chrono::system_clock::now().time_since_epoch().count()),
5206-
static_cast<unsigned long long>(
5207-
std::chrono::time_point<std::chrono::system_clock,
5208-
std::chrono::microseconds>(timeout)
5209-
.time_since_epoch()
5210-
.count()));
5191+
if (timeout) {
5192+
auto now = system_clock::now();
5193+
log->Printf("Process::RunThreadPlan(): about to wait - now is %s - "
5194+
"endpoint is %s",
5195+
llvm::to_string(now).c_str(),
5196+
llvm::to_string(now + *timeout).c_str());
52115197
} else {
52125198
log->Printf("Process::RunThreadPlan(): about to wait forever.");
52135199
}
@@ -5221,7 +5207,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
52215207
got_event = false;
52225208
} else
52235209
#endif
5224-
got_event = listener_sp->GetEvent(event_sp, ConvertTimeout(timeout));
5210+
got_event = listener_sp->GetEvent(event_sp, timeout);
52255211

52265212
if (got_event) {
52275213
if (event_sp) {
@@ -5371,27 +5357,19 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
53715357
if (log) {
53725358
if (options.GetTryAllThreads()) {
53735359
if (before_first_timeout) {
5374-
if (timeout_usec != 0) {
5375-
log->Printf("Process::RunThreadPlan(): Running function with "
5376-
"one thread timeout timed out, "
5377-
"running for %" PRIu32
5378-
" usec with all threads enabled.",
5379-
all_threads_timeout_usec);
5380-
} else {
5381-
log->Printf("Process::RunThreadPlan(): Running function with "
5382-
"one thread timeout timed out, "
5383-
"running forever with all threads enabled.");
5384-
}
5360+
log->Printf("Process::RunThreadPlan(): Running function with "
5361+
"one thread timeout timed out.");
53855362
} else
53865363
log->Printf("Process::RunThreadPlan(): Restarting function with "
53875364
"all threads enabled "
5388-
"and timeout: %u timed out, abandoning execution.",
5389-
timeout_usec);
5365+
"and timeout: %" PRIu64
5366+
" timed out, abandoning execution.",
5367+
timeout ? timeout->count() : -1);
53905368
} else
53915369
log->Printf("Process::RunThreadPlan(): Running function with "
5392-
"timeout: %u timed out, "
5370+
"timeout: %" PRIu64 " timed out, "
53935371
"abandoning execution.",
5394-
timeout_usec);
5372+
timeout ? timeout->count() : -1);
53955373
}
53965374

53975375
// It is possible that between the time we issued the Halt, and we get

0 commit comments

Comments
 (0)
Please sign in to comment.