AuroraRuntime/Source/Threading/Threads/TLSView.cpp

139 lines
2.7 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: TLSView.cpp
Date: 2021-6-12
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "TLSView.hpp"
namespace Aurora::Threading::Threads
{
void TLSViewImpl::Remove(AuUInt64 key)
{
AU_LOCK_GUARD(lock_);
auto a = tls_.find(key);
if (a == tls_.end())
{
return;
}
const auto &handler = a->second.second;
if (handler)
{
handler(a->second.first);
}
tls_.erase(a);
}
TLSViewImpl::~TLSViewImpl()
{
for (const auto &itr : tls_)
{
const auto &handler = itr.second.second;
if (handler)
{
handler(itr.second.first);
}
}
tls_.clear();
}
void *TLSViewImpl::GetTLS(AuUInt64 key, AuMach length, bool noAutoCreate)
{
AU_LOCK_GUARD(lock_);
AuPair<void*, TlsCb>*value;
if (!length)
{
return nullptr;
}
if (!AuTryFind(tls_, key, value))
{
if (noAutoCreate)
{
return nullptr;
}
auto buf = Memory::ZAlloc<void *>(length);
if (!buf)
{
return nullptr;
}
auto ok = AuTryInsertNoEnd(tls_, AuMakePair(key, AuMakePair(buf, TlsCb {})));
if (!ok)
{
Memory::Free(buf);
return nullptr;
}
ConsiderRehash();
return buf;
}
return value->first;
}
void *TLSViewImpl::InitTLS(AuUInt64 key, AuMach length, const TlsCb &init, const TlsCb &deinit)
{
AU_LOCK_GUARD(lock_);
AuPair<void*, TlsCb>*value;
if (!length)
{
return nullptr;
}
if (AuTryFind(tls_, key, value))
{
return value->first;
}
auto buf = Memory::ZAlloc<void *>(length);
if (!buf)
{
return nullptr;
}
TlsCb deinitcb = deinit;
auto ok = AuTryInsertNoEnd(tls_, AuMakePair(key, AuMakePair(buf, deinitcb)));
if (!ok)
{
Memory::Free(buf);
return nullptr;
}
ConsiderRehash();
if (init)
{
init(buf);
}
return buf;
}
void TLSViewImpl::ConsiderRehash()
{
try
{
// prevent Add, Remove, Add, Remove stalls
fence_++;
if ((fence_ % 10) == 0)
{
tls_.rehash(tls_.size());
}
}
catch (...)
{
}
}
}