Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
110 lines (95 loc) · 3.39 KB

File metadata and controls

110 lines (95 loc) · 3.39 KB
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "hermes/VM/TimeLimitMonitor.h"
namespace hermes {
namespace vm {
const uint32_t kDefaultSleepMs = 5000;
TimeLimitMonitor &TimeLimitMonitor::getInstance() {
static TimeLimitMonitor instance;
return instance;
}
TimeLimitMonitor::~TimeLimitMonitor() {
// Signal worker thread to exit before shutting down. Otherwise
// main thread may deadlock waiting for destroying newRequestCond_ condition
// variable.
{
std::lock_guard<std::mutex> lock(timeoutMapMtx_);
shouldExit_ = true;
}
newRequestCond_.notify_one();
// Since newRequestCond_ may still be used by worker thread, wait it to die
// before destroying member fields.
if (timerThread_.joinable()) {
timerThread_.join();
}
}
std::chrono::steady_clock::time_point TimeLimitMonitor::getNextDeadline() {
// A min-heap can be used to locate closest deadline more efficient, but did
// not do it for two reasons:
// 1. Total number of runtimes are not expected to be large.
// 2. Performance in TimeLimitMonitor is not the bottleneck.
auto nextDeadlineIter = std::min_element(
timeoutMap_.begin(),
timeoutMap_.end(),
[](const std::pair<Runtime *, std::chrono::steady_clock::time_point>
&elem1,
const std::pair<Runtime *, std::chrono::steady_clock::time_point>
&elem2) { return elem1.second < elem2.second; });
return nextDeadlineIter != timeoutMap_.end()
? nextDeadlineIter->second
: std::chrono::steady_clock::now() +
std::chrono::milliseconds(kDefaultSleepMs);
}
void TimeLimitMonitor::processAndRemoveExpiredItems() {
auto now = std::chrono::steady_clock::now();
for (auto iter = timeoutMap_.begin(), end = timeoutMap_.end(); iter != end;) {
if (iter->second <= now) {
notifyRuntimeTimeout(iter->first);
iter = timeoutMap_.erase(iter);
} else {
++iter;
}
}
}
void TimeLimitMonitor::timerLoop() {
std::unique_lock<std::mutex> lock(timeoutMapMtx_);
while (!shouldExit_) {
std::chrono::steady_clock::time_point wakeupTime = getNextDeadline();
// This wait can wakeup for three different reasons:
// 1. timeout
// 2. new request signal
// 3. condition variable spurious wakeup
//
// Regardless of the reasons we all wanted to do the same things:
// 1. Process expired work items
// 2. Wait for next closest deadline
newRequestCond_.wait_until(lock, wakeupTime);
processAndRemoveExpiredItems();
}
}
void TimeLimitMonitor::watchRuntime(Runtime *runtime, int timeoutInMs) {
{
std::lock_guard<std::mutex> lock(timeoutMapMtx_);
createTimerLoopIfNeeded();
auto deadline = std::chrono::steady_clock::now() +
std::chrono::milliseconds(timeoutInMs);
timeoutMap_[runtime] = deadline;
}
runtime->registerDestructionCallback(
[this](Runtime *runtime) { this->unwatchRuntime(runtime); });
// There is only one thread anyway.
newRequestCond_.notify_one();
}
void TimeLimitMonitor::unwatchRuntime(Runtime *runtime) {
std::lock_guard<std::mutex> lock(timeoutMapMtx_);
// unwatchRuntime() may be called multiple times for the same runtime.
if (timeoutMap_.find(runtime) != timeoutMap_.end()) {
timeoutMap_.erase(runtime);
}
}
} // namespace vm
} // namespace hermes
Morty Proxy This is a proxified and sanitized view of the page, visit original site.