From fa78ffbcc6956fbbc9ff95fbab27070ef6cfc6e2 Mon Sep 17 00:00:00 2001 From: Andre Pinto Date: Wed, 15 Apr 2015 17:56:57 -0700 Subject: [PATCH] Instrument fibers execution Summary: Add option to setup fibers' instrumentation. Test Plan: Unit tests Reviewed By: andrii@fb.com Subscribers: folly-diffs@, yfeldblum, chalfant FB internal diff: D1991638 Tasks: 6347990 Signature: t1:1991638:1429144487:3c3586b9943b4cc6bbef0297e48b8bffaf586f0d --- folly/Makefile.am | 1 + folly/experimental/fibers/ExecutionObserver.h | 38 +++++++++++++++++++ folly/experimental/fibers/FiberManager-inl.h | 12 ++++++ folly/experimental/fibers/FiberManager.cpp | 4 ++ folly/experimental/fibers/FiberManager.h | 14 +++++++ 5 files changed, 69 insertions(+) create mode 100644 folly/experimental/fibers/ExecutionObserver.h diff --git a/folly/Makefile.am b/folly/Makefile.am index daa849b8..ccc475ba 100644 --- a/folly/Makefile.am +++ b/folly/Makefile.am @@ -80,6 +80,7 @@ nobase_follyinclude_HEADERS = \ experimental/fibers/BoostContextCompatibility.h \ experimental/fibers/EventBaseLoopController.h \ experimental/fibers/EventBaseLoopController-inl.h \ + experimental/fibers/ExecutionObserver.h \ experimental/fibers/Fiber.h \ experimental/fibers/Fiber-inl.h \ experimental/fibers/FiberManager.h \ diff --git a/folly/experimental/fibers/ExecutionObserver.h b/folly/experimental/fibers/ExecutionObserver.h new file mode 100644 index 00000000..5cf1cc00 --- /dev/null +++ b/folly/experimental/fibers/ExecutionObserver.h @@ -0,0 +1,38 @@ +/* + * Copyright 2015 Facebook, Inc. + * + * 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. + */ +#pragma once + +namespace folly { namespace fibers { + +/** + * Observes the execution of a task. + */ +class ExecutionObserver { + public: + virtual ~ExecutionObserver() { } + + /** + * Called when a task is about to start executing. + */ + virtual void starting() noexcept = 0; + + /** + * Called just after a task stops executing. + */ + virtual void stopped() noexcept = 0; +}; + +}} // namespace folly::fibers diff --git a/folly/experimental/fibers/FiberManager-inl.h b/folly/experimental/fibers/FiberManager-inl.h index e77ccb45..793cf1fa 100644 --- a/folly/experimental/fibers/FiberManager-inl.h +++ b/folly/experimental/fibers/FiberManager-inl.h @@ -47,6 +47,9 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { assert(fiber->state_ == Fiber::NOT_STARTED || fiber->state_ == Fiber::READY_TO_RUN); currentFiber_ = fiber; + if (observer_) { + observer_->starting(); + } while (fiber->state_ == Fiber::NOT_STARTED || fiber->state_ == Fiber::READY_TO_RUN) { @@ -66,6 +69,9 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { if (fiber->state_ == Fiber::AWAITING) { awaitFunc_(*fiber); awaitFunc_ = nullptr; + if (observer_) { + observer_->stopped(); + } currentFiber_ = nullptr; } else if (fiber->state_ == Fiber::INVALID) { assert(fibersActive_ > 0); @@ -84,6 +90,9 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { fiber->finallyFunc_ = nullptr; } // Make sure LocalData is not accessible from its destructor + if (observer_) { + observer_->stopped(); + } currentFiber_ = nullptr; fiber->localData_.reset(); @@ -96,6 +105,9 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { --fibersAllocated_; } } else if (fiber->state_ == Fiber::YIELDED) { + if (observer_) { + observer_->stopped(); + } currentFiber_ = nullptr; fiber->state_ = Fiber::READY_TO_RUN; yieldedFibers_.push_back(*fiber); diff --git a/folly/experimental/fibers/FiberManager.cpp b/folly/experimental/fibers/FiberManager.cpp index 744478ab..6ad7174d 100644 --- a/folly/experimental/fibers/FiberManager.cpp +++ b/folly/experimental/fibers/FiberManager.cpp @@ -109,4 +109,8 @@ void FiberManager::remoteReadyInsert(Fiber* fiber) { } } +void FiberManager::setObserver(ExecutionObserver* observer) { + observer_ = observer; +} + }} diff --git a/folly/experimental/fibers/FiberManager.h b/folly/experimental/fibers/FiberManager.h index ee55cd6d..fa4e14aa 100644 --- a/folly/experimental/fibers/FiberManager.h +++ b/folly/experimental/fibers/FiberManager.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -234,6 +235,14 @@ class FiberManager { */ void yield(); + /** + * Setup fibers execution observation/instrumentation. Fiber locals are + * available to observer. + * + * @param observer Fiber's execution observer. + */ + void setObserver(ExecutionObserver* observer); + static FiberManager& getFiberManager(); static FiberManager* getFiberManagerUnsafe(); @@ -349,6 +358,11 @@ class FiberManager { */ std::function immediateFunc_; + /** + * Fiber's execution observer. + */ + ExecutionObserver* observer_{nullptr}; + ExceptionCallback exceptionCallback_; /**< task exception callback */ folly::AtomicLinkedList remoteReadyQueue_; -- 2.34.1