Commit 3d381a35 authored by Brian Watling's avatar Brian Watling Committed by Viswanath Sivakumar

Add 'runnable' callback to ExecutionObserver

Summary: Add a callback when a fiber becomes runnable

Test Plan: unit tests

Reviewed By: andrii@fb.com

Subscribers: alikhtarov, folly-diffs@, yfeldblum, chalfant

FB internal diff: D2081306

Signature: t1:2081306:1432011152:0ee93cb2682eb2a289b99c403e91465e72dd4ee8
parent 1e2aee3a
......@@ -15,6 +15,8 @@
*/
#pragma once
#include <cstdint>
namespace folly { namespace fibers {
/**
......@@ -26,13 +28,24 @@ class ExecutionObserver {
/**
* Called when a task is about to start executing.
*
* @param id Unique id for the fiber which is starting.
*/
virtual void starting(uintptr_t id) noexcept = 0;
/**
* Called when a task is ready to run.
*
* @param id Unique id for the fiber which is ready to run.
*/
virtual void starting() noexcept = 0;
virtual void runnable(uintptr_t id) noexcept = 0;
/**
* Called just after a task stops executing.
*
* @param id Unique id for the fiber which is stopping.
*/
virtual void stopped() noexcept = 0;
virtual void stopped(uintptr_t id) noexcept = 0;
};
}} // namespace folly::fibers
......@@ -60,6 +60,10 @@ void Fiber::setData(intptr_t data) {
data_ = data;
state_ = READY_TO_RUN;
if (fiberManager_.observer_) {
fiberManager_.observer_->runnable(reinterpret_cast<uintptr_t>(this));
}
if (LIKELY(threadId_ == localThreadId())) {
fiberManager_.readyFibers_.push_back(*this);
fiberManager_.ensureLoopScheduled();
......
......@@ -64,7 +64,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
fiber->state_ == Fiber::READY_TO_RUN);
currentFiber_ = fiber;
if (observer_) {
observer_->starting();
observer_->starting(reinterpret_cast<uintptr_t>(fiber));
}
while (fiber->state_ == Fiber::NOT_STARTED ||
......@@ -86,7 +86,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
awaitFunc_(*fiber);
awaitFunc_ = nullptr;
if (observer_) {
observer_->stopped();
observer_->stopped(reinterpret_cast<uintptr_t>(fiber));
}
currentFiber_ = nullptr;
} else if (fiber->state_ == Fiber::INVALID) {
......@@ -107,7 +107,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
}
// Make sure LocalData is not accessible from its destructor
if (observer_) {
observer_->stopped();
observer_->stopped(reinterpret_cast<uintptr_t>(fiber));
}
currentFiber_ = nullptr;
fiber->localData_.reset();
......@@ -122,7 +122,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
}
} else if (fiber->state_ == Fiber::YIELDED) {
if (observer_) {
observer_->stopped();
observer_->stopped(reinterpret_cast<uintptr_t>(fiber));
}
currentFiber_ = nullptr;
fiber->state_ = Fiber::READY_TO_RUN;
......@@ -168,12 +168,20 @@ inline bool FiberManager::loopUntilNoReady() {
fiber->setFunction(std::move(task->func));
fiber->data_ = reinterpret_cast<intptr_t>(fiber);
if (observer_) {
observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
}
runReadyFiber(fiber);
hadRemoteFiber = true;
}
);
}
if (observer_) {
for (auto& yielded : yieldedFibers_) {
observer_->runnable(reinterpret_cast<uintptr_t>(&yielded));
}
}
readyFibers_.splice(readyFibers_.end(), yieldedFibers_);
return fibersActive_ > 0;
......@@ -233,6 +241,9 @@ void FiberManager::addTask(F&& func) {
fiber->data_ = reinterpret_cast<intptr_t>(fiber);
readyFibers_.push_back(*fiber);
if (observer_) {
observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
}
ensureLoopScheduled();
}
......@@ -364,6 +375,9 @@ void FiberManager::addTaskFinally(F&& func, G&& finally) {
fiber->data_ = reinterpret_cast<intptr_t>(fiber);
readyFibers_.push_back(*fiber);
if (observer_) {
observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
}
ensureLoopScheduled();
}
......
......@@ -104,6 +104,9 @@ size_t FiberManager::stackHighWatermark() const {
}
void FiberManager::remoteReadyInsert(Fiber* fiber) {
if (observer_) {
observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
}
if (remoteReadyQueue_.insertHead(fiber)) {
loopController_->scheduleThreadSafe();
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment