mirror of
https://github.com/thunderbrewhq/common.git
synced 2025-12-12 03:02:29 +00:00
feat(thread): add OsTls functions
This commit is contained in:
parent
1eb1d281a9
commit
e1c516b188
5 changed files with 158 additions and 0 deletions
|
|
@ -3,6 +3,7 @@ file(GLOB COMMON_SOURCES
|
|||
"objectalloc/*.cpp"
|
||||
"ref/*.cpp"
|
||||
"string/*.cpp"
|
||||
"thread/*.cpp"
|
||||
)
|
||||
|
||||
add_library(common STATIC
|
||||
|
|
|
|||
6
common/Thread.hpp
Normal file
6
common/Thread.hpp
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef COMMON_THREAD_HPP
|
||||
#define COMMON_THREAD_HPP
|
||||
|
||||
#include "common/thread/Tls.hpp"
|
||||
|
||||
#endif
|
||||
113
common/thread/Tls.cpp
Normal file
113
common/thread/Tls.cpp
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#include "common/thread/Tls.hpp"
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
#include <storm/Array.hpp>
|
||||
#include <storm/List.hpp>
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
typedef void* TLSData;
|
||||
|
||||
struct TLSSlot : public TSLinkedNode<TLSSlot> {
|
||||
TSGrowableArray<TLSData> storage;
|
||||
};
|
||||
|
||||
namespace OsTls {
|
||||
int8_t s_initialized;
|
||||
int32_t s_nextIndex;
|
||||
TSList<TLSSlot, TSGetLink<TLSSlot>> s_tlsCleanupList;
|
||||
pthread_key_t s_tlsKey;
|
||||
SCritSect s_tlsLock;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t OsTlsAlloc() {
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
return TlsAlloc();
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
OsTls::s_tlsLock.Enter();
|
||||
|
||||
if (!OsTls::s_initialized) {
|
||||
OsTls::s_initialized = 1;
|
||||
OsTls::s_nextIndex = 0;
|
||||
pthread_key_create(&OsTls::s_tlsKey, nullptr);
|
||||
}
|
||||
|
||||
int32_t index = OsTls::s_nextIndex++;
|
||||
|
||||
OsTls:: s_tlsLock.Leave();
|
||||
|
||||
return index;
|
||||
#endif
|
||||
}
|
||||
|
||||
void* OsTlsGetValue(uint32_t tlsIndex) {
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
return TlsGetValue(tlsIndex);
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
if (!OsTls::s_initialized) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto slot = static_cast<TLSSlot*>(pthread_getspecific(OsTls::s_tlsKey));
|
||||
|
||||
if (!slot) {
|
||||
OsTls::s_tlsLock.Enter();
|
||||
|
||||
slot = OsTls::s_tlsCleanupList.NewNode(1, 1, 0x8);
|
||||
|
||||
OsTls::s_tlsLock.Leave();
|
||||
|
||||
pthread_setspecific(OsTls::s_tlsKey, slot);
|
||||
}
|
||||
|
||||
if (slot->storage.Count() > tlsIndex) {
|
||||
return slot->storage[tlsIndex];
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t OsTlsSetValue(uint32_t tlsIndex, void* tlsValue) {
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
return TlsSetValue(tlsIndex, tlsValue);
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||
if (!OsTls::s_initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto slot = static_cast<TLSSlot*>(pthread_getspecific(OsTls::s_tlsKey));
|
||||
|
||||
if (!slot) {
|
||||
OsTls::s_tlsLock.Enter();
|
||||
|
||||
slot = OsTls::s_tlsCleanupList.NewNode(1, 1, 0x8);
|
||||
|
||||
OsTls::s_tlsLock.Leave();
|
||||
|
||||
pthread_setspecific(OsTls::s_tlsKey, slot);
|
||||
}
|
||||
|
||||
if (slot->storage.Count() > tlsIndex) {
|
||||
slot->storage[tlsIndex] = tlsValue;
|
||||
} else {
|
||||
slot->storage.GrowToFit(tlsIndex, 0);
|
||||
slot->storage[tlsIndex] = tlsValue;
|
||||
}
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
12
common/thread/Tls.hpp
Normal file
12
common/thread/Tls.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef COMMON_THREAD_TLS_HPP
|
||||
#define COMMON_THREAD_TLS_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
int32_t OsTlsAlloc();
|
||||
|
||||
void* OsTlsGetValue(uint32_t tlsIndex);
|
||||
|
||||
int32_t OsTlsSetValue(uint32_t tlsIndex, void* tlsValue);
|
||||
|
||||
#endif
|
||||
26
test/Thread.cpp
Normal file
26
test/Thread.cpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include "common/Thread.hpp"
|
||||
#include "test/Test.hpp"
|
||||
|
||||
TEST_CASE("OsTlsAlloc", "[thread]") {
|
||||
SECTION("allocates tls index") {
|
||||
int32_t tlsIndex = OsTlsAlloc();
|
||||
REQUIRE(tlsIndex >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("OsTlsSetValue", "[thread]") {
|
||||
SECTION("sets value in tls index") {
|
||||
int32_t tlsIndex = OsTlsAlloc();
|
||||
uint32_t tlsValue = 123;
|
||||
REQUIRE(OsTlsSetValue(tlsIndex, &tlsValue));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("OsTlsGetValue", "[thread]") {
|
||||
SECTION("gets value in tls index") {
|
||||
int32_t tlsIndex = OsTlsAlloc();
|
||||
uint32_t tlsValue = 456;
|
||||
OsTlsSetValue(tlsIndex, &tlsValue);
|
||||
REQUIRE(OsTlsGetValue(tlsIndex) == &tlsValue);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue