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 @@ ...@@ -15,6 +15,8 @@
*/ */
#pragma once #pragma once
#include <cstdint>
namespace folly { namespace fibers { namespace folly { namespace fibers {
/** /**
...@@ -26,13 +28,24 @@ class ExecutionObserver { ...@@ -26,13 +28,24 @@ class ExecutionObserver {
/** /**
* Called when a task is about to start executing. * 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. * 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 }} // namespace folly::fibers
...@@ -60,6 +60,10 @@ void Fiber::setData(intptr_t data) { ...@@ -60,6 +60,10 @@ void Fiber::setData(intptr_t data) {
data_ = data; data_ = data;
state_ = READY_TO_RUN; state_ = READY_TO_RUN;
if (fiberManager_.observer_) {
fiberManager_.observer_->runnable(reinterpret_cast<uintptr_t>(this));
}
if (LIKELY(threadId_ == localThreadId())) { if (LIKELY(threadId_ == localThreadId())) {
fiberManager_.readyFibers_.push_back(*this); fiberManager_.readyFibers_.push_back(*this);
fiberManager_.ensureLoopScheduled(); fiberManager_.ensureLoopScheduled();
......
...@@ -64,7 +64,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { ...@@ -64,7 +64,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
fiber->state_ == Fiber::READY_TO_RUN); fiber->state_ == Fiber::READY_TO_RUN);
currentFiber_ = fiber; currentFiber_ = fiber;
if (observer_) { if (observer_) {
observer_->starting(); observer_->starting(reinterpret_cast<uintptr_t>(fiber));
} }
while (fiber->state_ == Fiber::NOT_STARTED || while (fiber->state_ == Fiber::NOT_STARTED ||
...@@ -86,7 +86,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { ...@@ -86,7 +86,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
awaitFunc_(*fiber); awaitFunc_(*fiber);
awaitFunc_ = nullptr; awaitFunc_ = nullptr;
if (observer_) { if (observer_) {
observer_->stopped(); observer_->stopped(reinterpret_cast<uintptr_t>(fiber));
} }
currentFiber_ = nullptr; currentFiber_ = nullptr;
} else if (fiber->state_ == Fiber::INVALID) { } else if (fiber->state_ == Fiber::INVALID) {
...@@ -107,7 +107,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { ...@@ -107,7 +107,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
} }
// Make sure LocalData is not accessible from its destructor // Make sure LocalData is not accessible from its destructor
if (observer_) { if (observer_) {
observer_->stopped(); observer_->stopped(reinterpret_cast<uintptr_t>(fiber));
} }
currentFiber_ = nullptr; currentFiber_ = nullptr;
fiber->localData_.reset(); fiber->localData_.reset();
...@@ -122,7 +122,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { ...@@ -122,7 +122,7 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
} }
} else if (fiber->state_ == Fiber::YIELDED) { } else if (fiber->state_ == Fiber::YIELDED) {
if (observer_) { if (observer_) {
observer_->stopped(); observer_->stopped(reinterpret_cast<uintptr_t>(fiber));
} }
currentFiber_ = nullptr; currentFiber_ = nullptr;
fiber->state_ = Fiber::READY_TO_RUN; fiber->state_ = Fiber::READY_TO_RUN;
...@@ -168,12 +168,20 @@ inline bool FiberManager::loopUntilNoReady() { ...@@ -168,12 +168,20 @@ inline bool FiberManager::loopUntilNoReady() {
fiber->setFunction(std::move(task->func)); fiber->setFunction(std::move(task->func));
fiber->data_ = reinterpret_cast<intptr_t>(fiber); fiber->data_ = reinterpret_cast<intptr_t>(fiber);
if (observer_) {
observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
}
runReadyFiber(fiber); runReadyFiber(fiber);
hadRemoteFiber = true; hadRemoteFiber = true;
} }
); );
} }
if (observer_) {
for (auto& yielded : yieldedFibers_) {
observer_->runnable(reinterpret_cast<uintptr_t>(&yielded));
}
}
readyFibers_.splice(readyFibers_.end(), yieldedFibers_); readyFibers_.splice(readyFibers_.end(), yieldedFibers_);
return fibersActive_ > 0; return fibersActive_ > 0;
...@@ -233,6 +241,9 @@ void FiberManager::addTask(F&& func) { ...@@ -233,6 +241,9 @@ void FiberManager::addTask(F&& func) {
fiber->data_ = reinterpret_cast<intptr_t>(fiber); fiber->data_ = reinterpret_cast<intptr_t>(fiber);
readyFibers_.push_back(*fiber); readyFibers_.push_back(*fiber);
if (observer_) {
observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
}
ensureLoopScheduled(); ensureLoopScheduled();
} }
...@@ -364,6 +375,9 @@ void FiberManager::addTaskFinally(F&& func, G&& finally) { ...@@ -364,6 +375,9 @@ void FiberManager::addTaskFinally(F&& func, G&& finally) {
fiber->data_ = reinterpret_cast<intptr_t>(fiber); fiber->data_ = reinterpret_cast<intptr_t>(fiber);
readyFibers_.push_back(*fiber); readyFibers_.push_back(*fiber);
if (observer_) {
observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
}
ensureLoopScheduled(); ensureLoopScheduled();
} }
......
...@@ -104,6 +104,9 @@ size_t FiberManager::stackHighWatermark() const { ...@@ -104,6 +104,9 @@ size_t FiberManager::stackHighWatermark() const {
} }
void FiberManager::remoteReadyInsert(Fiber* fiber) { void FiberManager::remoteReadyInsert(Fiber* fiber) {
if (observer_) {
observer_->runnable(reinterpret_cast<uintptr_t>(fiber));
}
if (remoteReadyQueue_.insertHead(fiber)) { if (remoteReadyQueue_.insertHead(fiber)) {
loopController_->scheduleThreadSafe(); 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