Use a thread_local to manage rt cache lifetime.

Rollback to immutable allocator
nix
Owen Green 5 years ago
parent ac163c4a11
commit 52bb79a581

@ -50,19 +50,36 @@ public:
using Cache = std::unordered_map<index, CacheEntryPointer>; using Cache = std::unordered_map<index, CacheEntryPointer>;
using RTCacheAllocator = using RTCacheAllocator =
SCWorldAllocator<std::pair<const index, WeakCacheEntryPointer>, Wrapper>; SCWorldAllocator<std::pair<const index, WeakCacheEntryPointer>, Wrapper>;
struct RTCacheMirror: public std::unordered_map<index, WeakCacheEntryPointer, std::hash<index>,
std::equal_to<index>, RTCacheAllocator> struct RTCacheMirror
: public std::unordered_map<index, WeakCacheEntryPointer,
std::hash<index>, std::equal_to<index>,
RTCacheAllocator>
{ {
~RTCacheMirror() RTCacheMirror(RTCacheAllocator&& alloc)
: std::unordered_map<index, WeakCacheEntryPointer, std::hash<index>,
std::equal_to<index>, RTCacheAllocator>{
std::move(alloc)}
{ {
if(mWorld) mWorld = nullptr; //if we get as far as destroying this, then the world is gone and we should accept that and move on // std::cout << "Warning: And up...\n" << std::endl;
} }
~RTCacheMirror()
{
// std::cout << "Warning: And down...\n" << std::endl;
}
}; };
static Cache mCache; static Cache mCache;
static RTCacheMirror mRTCache;
static RTCacheMirror& rtCache(World* world)
{
thread_local static RTCacheMirror mRTCache(
RTCacheAllocator(world, Wrapper::getInterfaceTable()));
return mRTCache;
}
private: private:
static bool isNull(WeakCacheEntryPointer const& weak) static bool isNull(WeakCacheEntryPointer const& weak)
{ {
@ -70,10 +87,11 @@ private:
!WeakCacheEntryPointer{}.owner_before(weak); !WeakCacheEntryPointer{}.owner_before(weak);
} }
static WeakCacheEntryPointer rtget(index id) static WeakCacheEntryPointer rtget(World* world, index id)
{ {
auto lookup = mRTCache.find(id); auto lookup = rtCache(world).find(id);
return lookup == mRTCache.end() ? WeakCacheEntryPointer() : lookup->second; return lookup == rtCache(world).end() ? WeakCacheEntryPointer()
: lookup->second;
} }
using RawCacheEntry = typename Cache::value_type; using RawCacheEntry = typename Cache::value_type;
@ -84,17 +102,8 @@ private:
{ {
FifoMsg msg; FifoMsg msg;
auto add = [](FifoMsg* m) { auto add = [](FifoMsg* m) {
if(!mWorld) mWorld = m->mWorld;
else if (mWorld != m->mWorld) //internal server has restarted
{
mWorld = nullptr;
mRTCache.clear();
mWorld = m->mWorld;
}
RawCacheEntry* r = static_cast<RawCacheEntry*>(m->mData); RawCacheEntry* r = static_cast<RawCacheEntry*>(m->mData);
mRTCache.emplace(r->first, r->second); rtCache(m->mWorld).emplace(r->first, r->second);
}; };
msg.Set(w, add, nullptr, &r); msg.Set(w, add, nullptr, &r);
auto ft = Wrapper::getInterfaceTable(); auto ft = Wrapper::getInterfaceTable();
@ -115,21 +124,8 @@ private:
FifoMsg msg; FifoMsg msg;
auto remove = [](FifoMsg* m) { auto remove = [](FifoMsg* m) {
if(!mWorld)
{
mRTCache.clear();
mWorld = m->mWorld; //
}
else if (mWorld != m->mWorld) //internal server has restarted
{
mWorld = nullptr;
mRTCache.clear();
mWorld = m->mWorld;
}
int* id = static_cast<int*>(m->mData); int* id = static_cast<int*>(m->mData);
mRTCache.erase(*id); rtCache(m->mWorld).erase(*id);
}; };
auto cleanup = [](FifoMsg* m) { delete static_cast<index*>(m->mData); }; auto cleanup = [](FifoMsg* m) { delete static_cast<index*>(m->mData); };
@ -464,7 +460,6 @@ private:
Params mParams; Params mParams;
bool mOverwriteParams{false}; bool mOverwriteParams{false};
WeakCacheEntryPointer mRecord; WeakCacheEntryPointer mRecord;
}; };
@ -564,9 +559,7 @@ private:
replyAddress}; replyAddress};
auto launchCompletionFromNRT = [](FifoMsg* inmsg) { auto launchCompletionFromNRT = [](FifoMsg* inmsg) {
auto runCompletion = [](FifoMsg* msg) { auto runCompletion = [](FifoMsg* msg) {
Context* c = static_cast<Context*>(msg->mData); Context* c = static_cast<Context*>(msg->mData);
World* world = c->mWorld; World* world = c->mWorld;
index id = c->mID; index id = c->mID;
@ -817,7 +810,7 @@ private:
mInterval = static_cast<index>(0.02 / controlDur()); mInterval = static_cast<index>(0.02 / controlDur());
mID = static_cast<index>(mInBuf[0][0]); mID = static_cast<index>(mInBuf[0][0]);
std::cout << mID << std::endl; std::cout << mID << std::endl;
mRecord = rtget(mID); mRecord = rtget(mWorld, mID);
set_calc_function<NRTProgressUnit, &NRTProgressUnit::next>(); set_calc_function<NRTProgressUnit, &NRTProgressUnit::next>();
Wrapper::getInterfaceTable()->fClearUnitOutputs(this, 1); Wrapper::getInterfaceTable()->fClearUnitOutputs(this, 1);
} }
@ -825,7 +818,7 @@ private:
void next(int) void next(int)
{ {
if (isNull(mRecord)) { mRecord = rtget(mID); }; if (isNull(mRecord)) { mRecord = rtget(mWorld, mID); };
if (0 == mCounter++) if (0 == mCounter++)
{ {
@ -941,7 +934,7 @@ private:
} }
else else
{ {
auto record = rtget(mID); auto record = rtget(mWorld, mID);
if (auto ptr = record.lock()) if (auto ptr = record.lock())
{ {
mInit = true; mInit = true;
@ -953,6 +946,7 @@ private:
mDone = mInit; mDone = mInit;
} }
} }
private: private:
bool mPreviousTrigger{false}; bool mPreviousTrigger{false};
bool mTrigger{false}; bool mTrigger{false};
@ -996,7 +990,7 @@ private:
void init() void init()
{ {
mInit = false; mInit = false;
mInst = rtget(mID); mInst = rtget(mWorld, mID);
if (auto ptr = mInst.lock()) if (auto ptr = mInst.lock())
{ {
auto& client = ptr->mClient; auto& client = ptr->mClient;
@ -1102,14 +1096,9 @@ public:
void init(){}; void init(){};
static World* getWorld() static World* getWorld() { return mWorld; }
{
return mWorld;
}
private: private:
static World* mWorld; static World* mWorld;
static Result validateParameters(ParamSetType& p) static Result validateParameters(ParamSetType& p)
@ -1158,10 +1147,6 @@ template <typename Client, typename Wrapper>
typename NonRealTime<Client, Wrapper>::Cache typename NonRealTime<Client, Wrapper>::Cache
NonRealTime<Client, Wrapper>::mCache{}; NonRealTime<Client, Wrapper>::mCache{};
template <typename Client, typename Wrapper>
typename NonRealTime<Client, Wrapper>::RTCacheMirror
NonRealTime<Client, Wrapper>::mRTCache{};
} // namespace impl } // namespace impl
} // namespace client } // namespace client
} // namespace fluid } // namespace fluid

@ -19,6 +19,9 @@ namespace fluid {
template <typename T, typename Wrapper> template <typename T, typename Wrapper>
class SCWorldAllocator class SCWorldAllocator
{ {
World* mWorld;
InterfaceTable* mInterface;
public: public:
using propagate_on_container_move_assignment = std::true_type; using propagate_on_container_move_assignment = std::true_type;
using value_type = T; using value_type = T;
@ -26,22 +29,24 @@ public:
template <typename U, typename W> template <typename U, typename W>
friend class SCWorldAllocator; friend class SCWorldAllocator;
SCWorldAllocator() = default; SCWorldAllocator(World* w, InterfaceTable* interface)
: mWorld{w}, mInterface{interface}
{}
template <typename U, typename W> template <typename U, typename W>
SCWorldAllocator(const SCWorldAllocator<U,W>&) noexcept SCWorldAllocator(const SCWorldAllocator<U, W>& other) noexcept
{} {
mWorld = other.mWorld;
mInterface = other.mInterface;
}
T* allocate(std::size_t n) T* allocate(std::size_t n)
{ {
if (n > std::numeric_limits<std::size_t>::max() / sizeof(T)) if (n > std::numeric_limits<std::size_t>::max() / sizeof(T))
throw std::bad_array_new_length(); throw std::bad_array_new_length();
World* world = Wrapper::getWorld(); if (mWorld && mInterface)
InterfaceTable* interface = Wrapper::getInterfaceTable(); if (auto p = static_cast<T*>(mInterface->fRTAlloc(mWorld, n * sizeof(T))))
if (world && interface)
if (auto p = static_cast<T*>(interface->fRTAlloc(world, n * sizeof(T))))
return p; return p;
throw std::bad_alloc(); throw std::bad_alloc();
@ -49,9 +54,7 @@ public:
void deallocate(T* p, std::size_t /*n*/) noexcept void deallocate(T* p, std::size_t /*n*/) noexcept
{ {
World* world = Wrapper::getWorld(); if (mWorld && mInterface) mInterface->fRTFree(mWorld, p);
InterfaceTable* interface = Wrapper::getInterfaceTable();
if(world && interface) interface->fRTFree(world, p);
} }
}; };
} // namespace fluid } // namespace fluid

Loading…
Cancel
Save