mirror of
https://github.com/thunderbrewhq/bc.git
synced 2025-12-12 01:52:30 +00:00
feat(lock): add basic lock functions
This commit is contained in:
parent
3b5da1af9c
commit
e8d3709d31
8 changed files with 207 additions and 0 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
file(GLOB BC_SOURCES
|
file(GLOB BC_SOURCES
|
||||||
"*.cpp"
|
"*.cpp"
|
||||||
|
"lock/*.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(bc STATIC
|
add_library(bc STATIC
|
||||||
|
|
|
||||||
58
bc/Lock.cpp
Normal file
58
bc/Lock.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include "bc/Lock.hpp"
|
||||||
|
#include "bc/Debug.hpp"
|
||||||
|
#include "bc/Process.hpp"
|
||||||
|
#include "bc/System_Lock.hpp"
|
||||||
|
|
||||||
|
void Blizzard::Lock::DoOnce(DoOnceData& a1, void (*a2)(void*), void* a3) {
|
||||||
|
if (!a1.done) {
|
||||||
|
if (Blizzard::Lock::Atomic::Increment(&a1.atomic) == 1) {
|
||||||
|
a2(a3);
|
||||||
|
a1.done = true;
|
||||||
|
} else {
|
||||||
|
while (!a1.done) {
|
||||||
|
Blizzard::Process::Sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Blizzard::Lock::MutexCreate(Blizzard::Lock::Mutex& mutex) {
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
InitializeCriticalSection(&mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
Blizzard::Lock::DoOnce(System_Lock::s_initMutexAttrOnce, System_Lock::InitAttr, nullptr);
|
||||||
|
|
||||||
|
auto result = pthread_mutex_init(&mutex, &System_Lock::s_mutexattr);
|
||||||
|
BLIZZARD_ASSERT(result == 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Blizzard::Lock::MutexEnter(Blizzard::Lock::Mutex& mutex) {
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
EnterCriticalSection(&mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
auto result = pthread_mutex_lock(&mutex);
|
||||||
|
BLIZZARD_ASSERT(result == 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Blizzard::Lock::MutexLeave(Blizzard::Lock::Mutex& mutex) {
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
LeaveCriticalSection(&mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
auto result = pthread_mutex_unlock(&mutex);
|
||||||
|
BLIZZARD_ASSERT(result == 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
37
bc/Lock.hpp
Normal file
37
bc/Lock.hpp
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef BC_LOCK_HPP
|
||||||
|
#define BC_LOCK_HPP
|
||||||
|
|
||||||
|
#include "bc/lock/Atomic.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
#include <windows.h>
|
||||||
|
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Blizzard {
|
||||||
|
namespace Lock {
|
||||||
|
|
||||||
|
// Types
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
typedef CRITICAL_SECTION Mutex;
|
||||||
|
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
typedef pthread_mutex_t Mutex;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct DoOnceData {
|
||||||
|
bool done;
|
||||||
|
int32_t atomic;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
void DoOnce(DoOnceData& a1, void (*a2)(void*), void* a3);
|
||||||
|
int32_t MutexCreate(Mutex& mutex);
|
||||||
|
int32_t MutexEnter(Mutex& mutex);
|
||||||
|
int32_t MutexLeave(Mutex& mutex);
|
||||||
|
|
||||||
|
} // namespace Lock
|
||||||
|
} // namespace Blizzard
|
||||||
|
|
||||||
|
#endif
|
||||||
13
bc/System_Lock.cpp
Normal file
13
bc/System_Lock.cpp
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "bc/System_Lock.hpp"
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
Blizzard::Lock::DoOnceData Blizzard::System_Lock::s_initMutexAttrOnce;
|
||||||
|
Blizzard::System_Lock::MutexAttr Blizzard::System_Lock::s_mutexattr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Blizzard::System_Lock::InitAttr(void* a1) {
|
||||||
|
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
pthread_mutexattr_init(&System_Lock::s_mutexattr);
|
||||||
|
pthread_mutexattr_settype(&System_Lock::s_mutexattr, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
30
bc/System_Lock.hpp
Normal file
30
bc/System_Lock.hpp
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef BC_SYSTEM_LOCK_HPP
|
||||||
|
#define BC_SYSTEM_LOCK_HPP
|
||||||
|
|
||||||
|
#include "bc/Lock.hpp"
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Blizzard {
|
||||||
|
namespace System_Lock {
|
||||||
|
|
||||||
|
// Types
|
||||||
|
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
typedef pthread_mutexattr_t MutexAttr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
extern Lock::DoOnceData s_initMutexAttrOnce;
|
||||||
|
extern MutexAttr s_mutexattr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
void InitAttr(void* a1);
|
||||||
|
|
||||||
|
} // namespace System_Lock
|
||||||
|
} // namespace Blizzard
|
||||||
|
|
||||||
|
#endif
|
||||||
13
bc/lock/Atomic.cpp
Normal file
13
bc/lock/Atomic.cpp
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "bc/lock/Atomic.hpp"
|
||||||
|
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int32_t Blizzard::Lock::Atomic::Increment(volatile int32_t* value) {
|
||||||
|
#if defined(WHOA_SYSTEM_WIN)
|
||||||
|
return InterlockedIncrement(reinterpret_cast<volatile long*>(value));
|
||||||
|
#elif defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
|
||||||
|
return __sync_fetch_and_add(value, 1) + 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
16
bc/lock/Atomic.hpp
Normal file
16
bc/lock/Atomic.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef BC_LOCK_ATOMIC_HPP
|
||||||
|
#define BC_LOCK_ATOMIC_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Blizzard {
|
||||||
|
namespace Lock {
|
||||||
|
namespace Atomic {
|
||||||
|
|
||||||
|
int32_t Increment(volatile int32_t* value);
|
||||||
|
|
||||||
|
} // namespace Atomic
|
||||||
|
} // namespace Lock
|
||||||
|
} // namespace Blizzard
|
||||||
|
|
||||||
|
#endif
|
||||||
39
test/Lock.cpp
Normal file
39
test/Lock.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "bc/Lock.hpp"
|
||||||
|
#include "test/Test.hpp"
|
||||||
|
|
||||||
|
TEST_CASE("Blizzard::Lock::Atomic::Increment", "[lock]") {
|
||||||
|
SECTION("increments -1") {
|
||||||
|
int32_t value = -1;
|
||||||
|
REQUIRE(Blizzard::Lock::Atomic::Increment(&value) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("increments 0") {
|
||||||
|
int32_t value = 0;
|
||||||
|
REQUIRE(Blizzard::Lock::Atomic::Increment(&value) == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Blizzard::Lock::MutexCreate", "[lock]") {
|
||||||
|
SECTION("creates mutex") {
|
||||||
|
Blizzard::Lock::Mutex mutex1;
|
||||||
|
REQUIRE(Blizzard::Lock::MutexCreate(mutex1) == 0);
|
||||||
|
|
||||||
|
Blizzard::Lock::Mutex mutex2;
|
||||||
|
REQUIRE(Blizzard::Lock::MutexCreate(mutex2) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Blizzard::Lock::MutexEnter", "[lock]") {
|
||||||
|
SECTION("enters and leaves mutex") {
|
||||||
|
Blizzard::Lock::Mutex mutex;
|
||||||
|
Blizzard::Lock::MutexCreate(mutex);
|
||||||
|
|
||||||
|
int32_t mutexEntered = 0;
|
||||||
|
|
||||||
|
Blizzard::Lock::MutexEnter(mutex);
|
||||||
|
mutexEntered = 1;
|
||||||
|
Blizzard::Lock::MutexLeave(mutex);
|
||||||
|
|
||||||
|
REQUIRE(mutexEntered == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue