[threading linux] Implement TLS
Implement TLSHandle with pthread_key_t. Test Alloc, Free, Get and Set.
This commit is contained in:
parent
634f87f63b
commit
e9e269622b
|
@ -113,8 +113,35 @@ TEST_CASE("Sleep Current Thread in Alertable State", "Sleep") {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("TlsHandle") {
|
TEST_CASE("TlsHandle") {
|
||||||
// TODO(bwrsandman):
|
// Test Allocate
|
||||||
REQUIRE(true);
|
auto handle = threading::AllocateTlsHandle();
|
||||||
|
|
||||||
|
// Test Free
|
||||||
|
REQUIRE(threading::FreeTlsHandle(handle));
|
||||||
|
REQUIRE(!threading::FreeTlsHandle(handle));
|
||||||
|
REQUIRE(!threading::FreeTlsHandle(threading::kInvalidTlsHandle));
|
||||||
|
|
||||||
|
// Test setting values
|
||||||
|
handle = threading::AllocateTlsHandle();
|
||||||
|
REQUIRE(threading::GetTlsValue(handle) == 0);
|
||||||
|
uint32_t value = 0xDEADBEEF;
|
||||||
|
threading::SetTlsValue(handle, reinterpret_cast<uintptr_t>(&value));
|
||||||
|
auto p_received_value = threading::GetTlsValue(handle);
|
||||||
|
REQUIRE(threading::GetTlsValue(handle) != 0);
|
||||||
|
auto received_value = *reinterpret_cast<uint32_t*>(p_received_value);
|
||||||
|
REQUIRE(received_value == value);
|
||||||
|
|
||||||
|
uintptr_t non_thread_local_value = 0;
|
||||||
|
auto thread = Thread::Create({}, [&non_thread_local_value, &handle] {
|
||||||
|
non_thread_local_value = threading::GetTlsValue(handle);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto result = Wait(thread.get(), false, 50ms);
|
||||||
|
REQUIRE(result == WaitResult::kSuccess);
|
||||||
|
REQUIRE(non_thread_local_value == 0);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
REQUIRE(threading::FreeTlsHandle(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("HighResolutionTimer") {
|
TEST_CASE("HighResolutionTimer") {
|
||||||
|
|
|
@ -117,23 +117,26 @@ SleepResult AlertableSleep(std::chrono::microseconds duration) {
|
||||||
return SleepResult::kSuccess;
|
return SleepResult::kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(dougvj) We can probably wrap this with pthread_key_t but the type of
|
|
||||||
// TlsHandle probably needs to be refactored
|
|
||||||
TlsHandle AllocateTlsHandle() {
|
TlsHandle AllocateTlsHandle() {
|
||||||
assert_always();
|
auto key = static_cast<pthread_key_t>(-1);
|
||||||
return 0;
|
auto res = pthread_key_create(&key, nullptr);
|
||||||
|
assert_zero(res);
|
||||||
|
assert_true(key != static_cast<pthread_key_t>(-1));
|
||||||
|
return static_cast<TlsHandle>(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FreeTlsHandle(TlsHandle handle) { return true; }
|
bool FreeTlsHandle(TlsHandle handle) {
|
||||||
|
return pthread_key_delete(static_cast<pthread_key_t>(handle)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t GetTlsValue(TlsHandle handle) {
|
uintptr_t GetTlsValue(TlsHandle handle) {
|
||||||
assert_always();
|
return reinterpret_cast<uintptr_t>(
|
||||||
return 0;
|
pthread_getspecific(static_cast<pthread_key_t>(handle)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetTlsValue(TlsHandle handle, uintptr_t value) {
|
bool SetTlsValue(TlsHandle handle, uintptr_t value) {
|
||||||
assert_always();
|
return pthread_setspecific(static_cast<pthread_key_t>(handle),
|
||||||
return false;
|
reinterpret_cast<void*>(value)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PosixHighResolutionTimer : public HighResolutionTimer {
|
class PosixHighResolutionTimer : public HighResolutionTimer {
|
||||||
|
|
Loading…
Reference in New Issue