139 lines
2.7 KiB
C++
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 = AuMemory::ZAlloc<void *>(length);
|
|
if (!buf)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
auto ok = AuTryInsertNoEnd(tls_, AuMakePair(key, AuMakePair(buf, TlsCb {})));
|
|
if (!ok)
|
|
{
|
|
AuMemory::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 = AuMemory::ZAlloc<void *>(length);
|
|
if (!buf)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
TlsCb deinitcb = deinit;
|
|
auto ok = AuTryInsertNoEnd(tls_, AuMakePair(key, AuMakePair(buf, deinitcb)));
|
|
if (!ok)
|
|
{
|
|
AuMemory::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 (...)
|
|
{
|
|
|
|
}
|
|
}
|
|
} |