Commit 78486d6a authored by Chris Keeline's avatar Chris Keeline Committed by Facebook Github Bot

Allow setting fiber local type through FiberManagerMap

Summary:
Using FiberManagerMap is a prerequisite for the gdb extension, but
previously it didn't support using a non-void local type. One option is to
make GlobalCache<EventBaseT, LocalT>, I ended up sharing the cache across local
types to avoid changing much in the gdb side.

The gdb extension is already updated to handle the namespace change.

Reviewed By: andriigrynenko

Differential Revision: D19422428

fbshipit-source-id: 26cb385791a9503906fc69d91039bfa93837b6db
parent d8b4f2ff
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include <folly/fibers/FiberManagerMap.h> #pragma once
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
...@@ -27,11 +27,11 @@ ...@@ -27,11 +27,11 @@
namespace folly { namespace folly {
namespace fibers { namespace fibers {
namespace { namespace detail {
// ssize_t is a hash of FiberManager::Options // ssize_t is a hash of FiberManager::Options
template <typename EventBaseT> template <typename EventBaseT>
using Key = std::pair<EventBaseT*, ssize_t>; using Key = std::tuple<EventBaseT*, ssize_t, std::type_index>;
template <typename EventBaseT> template <typename EventBaseT>
Function<void()> makeOnEventBaseDestructionCallback(const Key<EventBaseT>& key); Function<void()> makeOnEventBaseDestructionCallback(const Key<EventBaseT>& key);
...@@ -39,11 +39,12 @@ Function<void()> makeOnEventBaseDestructionCallback(const Key<EventBaseT>& key); ...@@ -39,11 +39,12 @@ Function<void()> makeOnEventBaseDestructionCallback(const Key<EventBaseT>& key);
template <typename EventBaseT> template <typename EventBaseT>
class GlobalCache { class GlobalCache {
public: public:
template <typename LocalT>
static FiberManager& get( static FiberManager& get(
const Key<EventBaseT>& key, const Key<EventBaseT>& key,
EventBaseT& evb, EventBaseT& evb,
const FiberManager::Options& opts) { const FiberManager::Options& opts) {
return instance().getImpl(key, evb, opts); return instance().template getImpl<LocalT>(key, evb, opts);
} }
static std::unique_ptr<FiberManager> erase(const Key<EventBaseT>& key) { static std::unique_ptr<FiberManager> erase(const Key<EventBaseT>& key) {
...@@ -60,6 +61,7 @@ class GlobalCache { ...@@ -60,6 +61,7 @@ class GlobalCache {
return *ret; return *ret;
} }
template <typename LocalT>
FiberManager& getImpl( FiberManager& getImpl(
const Key<EventBaseT>& key, const Key<EventBaseT>& key,
EventBaseT& evb, EventBaseT& evb,
...@@ -79,8 +81,8 @@ class GlobalCache { ...@@ -79,8 +81,8 @@ class GlobalCache {
constructed = true; constructed = true;
auto loopController = std::make_unique<EventBaseLoopController>(); auto loopController = std::make_unique<EventBaseLoopController>();
loopController->attachEventBase(evb); loopController->attachEventBase(evb);
fmPtrRef = fmPtrRef = std::make_unique<FiberManager>(
std::make_unique<FiberManager>(std::move(loopController), opts); LocalType<LocalT>(), std::move(loopController), opts);
} }
return *fmPtrRef; return *fmPtrRef;
...@@ -105,11 +107,10 @@ constexpr size_t kEraseListMaxSize = 64; ...@@ -105,11 +107,10 @@ constexpr size_t kEraseListMaxSize = 64;
template <typename EventBaseT> template <typename EventBaseT>
class ThreadLocalCache { class ThreadLocalCache {
public: public:
static FiberManager& get( template <typename LocalT>
const Key<EventBaseT>& key, static FiberManager&
EventBaseT& evb, get(uint64_t token, EventBaseT& evb, const FiberManager::Options& opts) {
const FiberManager::Options& opts) { return instance()->template getImpl<LocalT>(token, evb, opts);
return instance()->getImpl(key, evb, opts);
} }
static void erase(const Key<EventBaseT>& key) { static void erase(const Key<EventBaseT>& key) {
...@@ -140,15 +141,15 @@ class ThreadLocalCache { ...@@ -140,15 +141,15 @@ class ThreadLocalCache {
return *ret; return *ret;
} }
FiberManager& getImpl( template <typename LocalT>
const Key<EventBaseT>& key, FiberManager&
EventBaseT& evb, getImpl(uint64_t token, EventBaseT& evb, const FiberManager::Options& opts) {
const FiberManager::Options& opts) {
eraseImpl(); eraseImpl();
auto key = make_tuple(&evb, token, std::type_index(typeid(LocalT)));
auto& fmPtrRef = map_[key]; auto& fmPtrRef = map_[key];
if (!fmPtrRef) { if (!fmPtrRef) {
fmPtrRef = &GlobalCache<EventBaseT>::get(key, evb, opts); fmPtrRef = &GlobalCache<EventBaseT>::template get<LocalT>(key, evb, opts);
} }
DCHECK(fmPtrRef != nullptr); DCHECK(fmPtrRef != nullptr);
...@@ -197,26 +198,32 @@ Function<void()> makeOnEventBaseDestructionCallback( ...@@ -197,26 +198,32 @@ Function<void()> makeOnEventBaseDestructionCallback(
}; };
} }
} // namespace } // namespace detail
FiberManager& getFiberManager( template <typename LocalT>
FiberManager& getFiberManagerT(
EventBase& evb, EventBase& evb,
const FiberManager::Options& opts) { const FiberManager::Options& opts) {
return ThreadLocalCache<EventBase>::get(std::make_pair(&evb, 0), evb, opts); return detail::ThreadLocalCache<EventBase>::get<LocalT>(0, evb, opts);
}
FiberManager& getFiberManager(
folly::EventBase& evb,
const FiberManager::Options& opts) {
return detail::ThreadLocalCache<EventBase>::get<void>(0, evb, opts);
} }
FiberManager& getFiberManager( FiberManager& getFiberManager(
VirtualEventBase& evb, VirtualEventBase& evb,
const FiberManager::Options& opts) { const FiberManager::Options& opts) {
return ThreadLocalCache<VirtualEventBase>::get( return detail::ThreadLocalCache<VirtualEventBase>::get<void>(0, evb, opts);
std::make_pair(&evb, 0), evb, opts);
} }
FiberManager& getFiberManager( FiberManager& getFiberManager(
folly::EventBase& evb, folly::EventBase& evb,
const FiberManager::FrozenOptions& opts) { const FiberManager::FrozenOptions& opts) {
return ThreadLocalCache<EventBase>::get( return detail::ThreadLocalCache<EventBase>::get<void>(
std::make_pair(&evb, opts.token), evb, opts.options); opts.token, evb, opts.options);
} }
} // namespace fibers } // namespace fibers
......
...@@ -23,17 +23,22 @@ ...@@ -23,17 +23,22 @@
namespace folly { namespace folly {
namespace fibers { namespace fibers {
FiberManager& getFiberManager( template <typename Local>
static inline FiberManager& getFiberManagerT(
folly::EventBase& evb, folly::EventBase& evb,
const FiberManager::Options& opts = FiberManager::Options()); const FiberManager::Options& opts = FiberManager::Options());
FiberManager& getFiberManager( static inline FiberManager& getFiberManager(
folly::EventBase& evb,
const FiberManager::Options& opts = FiberManager::Options());
static inline FiberManager& getFiberManager(
folly::VirtualEventBase& evb, folly::VirtualEventBase& evb,
const FiberManager::Options& opts = FiberManager::Options()); const FiberManager::Options& opts = FiberManager::Options());
FiberManager& getFiberManager( static inline FiberManager& getFiberManager(
folly::EventBase& evb, folly::EventBase& evb,
const FiberManager::FrozenOptions& opts); const FiberManager::FrozenOptions& opts);
} // namespace fibers } // namespace fibers
} // namespace folly } // namespace folly
#include <folly/fibers/FiberManagerMap-inl.h>
...@@ -852,13 +852,20 @@ def fiber_manager_active_fibers(fm): ...@@ -852,13 +852,20 @@ def fiber_manager_active_fibers(fm):
def get_fiber_manager_map(evb_type): def get_fiber_manager_map(evb_type):
try: # global cache was moved from anonymous namespace to "detail", we want to
# Exception thrown if unable to find type # work in both cases.
# Probably because of missing debug symbols for ns in ("detail", "(anonymous namespace)"):
global_cache_type = gdb.lookup_type( try:
"folly::fibers::(anonymous namespace)::GlobalCache<" + evb_type + ">" # Exception thrown if unable to find type
) global_cache_type = gdb.lookup_type(
except gdb.error: "folly::fibers::{ns}::GlobalCache<{evb_type}>".format(
ns=ns, evb_type=evb_type
)
)
break
except gdb.error:
pass
else:
raise gdb.GdbError( raise gdb.GdbError(
"Unable to find types. " "Unable to find types. "
"Please make sure debug info is available for this binary.\n" "Please make sure debug info is available for this binary.\n"
...@@ -936,8 +943,8 @@ def load(): ...@@ -936,8 +943,8 @@ def load():
FiberNameCommand() FiberNameCommand()
Shortcut("get_fiber_manager_map_evb", get_fiber_manager_map_evb) Shortcut("get_fiber_manager_map_evb", get_fiber_manager_map_evb)
Shortcut("get_fiber_manager_map_vevb", get_fiber_manager_map_vevb) Shortcut("get_fiber_manager_map_vevb", get_fiber_manager_map_vevb)
Shortcut("clear_fiber_caches", clear_fiber_caches) Shortcut("clear_fiber_caches", lambda _: clear_fiber_caches())
gdb.events.cont.connect(clear_fiber_caches) gdb.events.cont.connect(lambda _: clear_fiber_caches())
def info(): def info():
......
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