diff --git a/Justfile b/Justfile index 16831e8..4b176d2 100644 --- a/Justfile +++ b/Justfile @@ -1,7 +1,11 @@ build: - dotnet build + dotnet build -c Release make -C speech2 -j$(nproc) +build-debug: + dotnet build -c Debug + make -C speech2 CONFIG=Debug -j$(nproc) + clean: rm -rf SAPIServer/bin SAPIServer/obj make -C speech2 clean diff --git a/speech2/src/base/BCondVar.cpp b/speech2/src/base/BCondVar.cpp deleted file mode 100644 index 45fb131..0000000 --- a/speech2/src/base/BCondVar.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include - -#include - -namespace base::osdep { - - enum class MemoryOrder { - Relaxed = __ATOMIC_RELAXED, - Consume = __ATOMIC_CONSUME, - Acquire = __ATOMIC_ACQUIRE, - Release = __ATOMIC_RELEASE, - AcqRel = __ATOMIC_ACQ_REL, - SeqCst = __ATOMIC_SEQ_CST - }; - - // TODO: public! - template - struct BAtomic { - BAtomic() = default; - BAtomic(const T value) : - value(value) { - - } - - inline T fetch_add(T val, MemoryOrder order = DefaultOrder) volatile noexcept { - return __atomic_fetch_add(&value, val, static_cast(order)); - } - - inline T fetch_sub(T val, MemoryOrder order = DefaultOrder) volatile noexcept { - volatile T* ptr = &value; - return __atomic_fetch_sub(ptr, val, static_cast(order)); - } - - void store(T desiredValue, MemoryOrder order = DefaultOrder) volatile noexcept { - __atomic_store_n(&value, desiredValue, order); - } - - T operator++() volatile noexcept { - return fetch_add(1) + 1; - } - - T operator++(int) volatile noexcept { - return fetch_add(1); - } - - T operator--() volatile noexcept { - return fetch_sub(1) - 1; - } - - T operator--(int) volatile noexcept { - return fetch_sub(1); - } - - T operator-=(T val) volatile noexcept { - return fetch_sub(val) - val; - } - - T operator+=(T val) volatile noexcept{ - return fetch_add(val) + val; - } - private: - T value; - }; - - struct BCondVar { - BCondVar() { - hNotifyAllEvent = CreateEventA(nullptr, TRUE, FALSE, nullptr); - hNotifyOneEvent = CreateEventA(nullptr, FALSE, FALSE, nullptr); - - waiterMutex = BMutex_Create(true); - } - - ~BCondVar() { - if(hNotifyAllEvent != INVALID_HANDLE_VALUE) - CloseHandle(hNotifyAllEvent); - if(hNotifyOneEvent != INVALID_HANDLE_VALUE) - CloseHandle(hNotifyOneEvent); - - BMutex_Destroy(waiterMutex); - } - - void SignalOne() { - SetEvent(hNotifyOneEvent); - } - - void SignalAll() { - SetEvent(hNotifyAllEvent); - } - - void Wait(bool(*predicate)(void* ctx), void* ctx) { - HANDLE handles[2] = { hNotifyAllEvent, hNotifyOneEvent }; - - BMutex_Lock(waiterMutex); - waiterSemaphore++; - BMutex_Unlock(waiterMutex); - - while(!predicate(ctx)) { - switch(WaitForMultipleObjects(2, &handles[0], FALSE, INFINITE)) { - - case WAIT_OBJECT_0: // hNotifyAllEvent - BMutex_Lock(waiterMutex); - if(waiterSemaphore-- == 0) { - ResetEvent(hNotifyAllEvent); - } - BMutex_Unlock(waiterMutex); - break; - - case WAIT_OBJECT_0 + 1: // hNotifyOneEvent - continue; - break; - - case WAIT_FAILED: - return; - break; - - default: - return; - break; - } - } - } - - HANDLE hNotifyAllEvent{}; - HANDLE hNotifyOneEvent{}; - - // Semaphore for SignalAll(). - BMutex* waiterMutex; - BAtomic waiterSemaphore{0}; - }; - - BCondVar* BCondVar_Create() { - return new BCondVar(); - } - - /// Signals one thread. - void BCondVar_SignalOne(BCondVar* cond) { - cond->SignalOne(); - } - - // Signals all threads. - void BCondVar_SignalAll(BCondVar* cond) { - cond->SignalAll(); - } - - - // Waits. Call this on all threads. - void BCondVar_Wait(BCondVar* condvar, bool(*predicate)(void* ctx), void* ctx) { - condvar->Wait(predicate, ctx); - } - - void BCondVar_Destroy(BCondVar* condvar) { - delete condvar; - } -} diff --git a/speech2/src/base/BMutex.cpp b/speech2/src/base/BMutex.cpp deleted file mode 100644 index a7860b7..0000000 --- a/speech2/src/base/BMutex.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include - -namespace base::osdep { - - struct BMutex { - CRITICAL_SECTION critSec {}; - bool recursive{}; - - BMutex(bool recursive = false) : recursive(recursive) { InitializeCriticalSection(&critSec); } - - ~BMutex() { - if(critSec.LockCount != 0) - Unlock(); - - DeleteCriticalSection(&critSec); - } - - inline void Lock() { - - // recursive lock check - if(!recursive) { - if(critSec.LockCount + 1 > 1) { - ExitProcess(0x69420); - return; - } - } - - EnterCriticalSection(&critSec); - } - - inline void Unlock() { LeaveCriticalSection(&critSec); } - }; - - BMutex* BMutex_Create(bool recursive) { - return new BMutex(recursive); - } - - void BMutex_Destroy(BMutex* mutex) { - delete mutex; - } - - void BMutex_Lock(BMutex* mutex) { - if(mutex) - mutex->Lock(); - } - - void BMutex_Unlock(BMutex* mutex) { - if(mutex) - mutex->Unlock(); - } - -} // namespace base::osdep diff --git a/speech2/src/base/BThread.cpp b/speech2/src/base/BThread.cpp deleted file mode 100644 index 8a811bd..0000000 --- a/speech2/src/base/BThread.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include - -namespace base::osdep { - - struct BThread { - HANDLE hThread; - unsigned dwId; - }; - - BThreadHandle BThread_Spawn(BThreadFunc ep, void* arg, unsigned stackSize) { - unsigned dwID{}; - auto res = _beginthreadex(nullptr, stackSize, static_cast<_beginthreadex_proc_type>(ep), arg, 0, &dwID); - - if(res == -1) - return nullptr; - - auto handle = new BThread(); - handle->hThread = reinterpret_cast(res); - handle->dwId = dwID; - - return handle; - } - - unsigned BThread_GetID(BThreadHandle handle) { - if(handle) - return handle->dwId; - - return -1; - } - - void BThread_Join(BThreadHandle handle) { - if(handle) { - auto res = WaitForSingleObject(handle->hThread, INFINITE); - return; - } - } -} // namespace base::osdep diff --git a/speech2/src/base/BThread.hpp b/speech2/src/base/BThread.hpp deleted file mode 100644 index e560dee..0000000 --- a/speech2/src/base/BThread.hpp +++ /dev/null @@ -1,64 +0,0 @@ -// BThread - it's like GThread, but mentally sane! -// (and without __, pthreads, and other smells.) -#pragma once - -#ifdef _WIN32 -#include -#else -#error BThread only supports Windows. -#endif - -namespace base::osdep { - - // Threads - - struct BThread; - - using BThreadHandle = BThread*; - -#ifdef _WIN32 - using BThreadNativeHandle = HANDLE; -#endif - - using BThreadFunc = - unsigned WINAPI (*)(void* argp); - - // Spawns a new thread, with the given entry point, argument, and stack size. - BThreadHandle BThread_Spawn(BThreadFunc ep, void* arg = nullptr, unsigned stackSize = 0); - - // TODO BThread_Native(BThreadHandle handle) - - unsigned BThread_GetID(BThreadHandle handle); - - // Joins (waits for this thread to terminate) this thread. - void BThread_Join(BThreadHandle handle); - - // Mutexes - - struct BMutex; - - // if recursive is true, this BMutex will be a recursive mutex, - // and multiple threads are allowed to lock it. - BMutex* BMutex_Create(bool recursive); - - void BMutex_Lock(BMutex* mutex); - void BMutex_Unlock(BMutex* mutex); - - void BMutex_Destroy(BMutex* mutex); - - struct BCondVar; - - BCondVar* BCondVar_Create(); - - /// Signals one thread. - void BCondVar_SignalOne(BCondVar* cond); - - // Signals all threads. - void BCondVar_SignalAll(BCondVar* cond); - - - // Waits. Call this on all threads. - void BCondVar_Wait(BCondVar* condvar, bool(*predicate)(void* ctx), void* ctx); - - void BCondVar_Destroy(BCondVar* condvar); -} diff --git a/speech2/src/base/Mutex.cpp b/speech2/src/base/Mutex.cpp deleted file mode 100644 index 9f9bb08..0000000 --- a/speech2/src/base/Mutex.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include - -namespace base { - - Mutex::Mutex() { - mutex = osdep::BMutex_Create(false); - } - - Mutex::~Mutex() { - osdep::BMutex_Destroy(mutex); - } - - void Mutex::Lock() { - osdep::BMutex_Lock(mutex); - } - - void Mutex::Unlock() { - osdep::BMutex_Unlock(mutex); - } - -} // namespace base diff --git a/speech2/src/base/Mutex.hpp b/speech2/src/base/Mutex.hpp deleted file mode 100644 index 3a335b7..0000000 --- a/speech2/src/base/Mutex.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include - -namespace base { - - /** - * A mutex. - */ - struct Mutex { - Mutex(); - ~Mutex(); - - Mutex(const Mutex&) = delete; - Mutex(Mutex&&) = default; - - void Lock(); - void Unlock(); - - // impl data. - private: - osdep::BMutex* mutex; - }; - - template - concept Lockable = requires(T t) { - { t.Lock() }; - { t.Unlock() }; - }; - - /** - * Scoped lock guard. - */ - template - struct LockGuard { - LockGuard(Mut& mtx) - : mutex(mtx) { - mutex.Lock(); - } - - ~LockGuard() { - mutex.Unlock(); - } - private: - Mut& mutex; - }; - -} diff --git a/speech2/src/base/README.md b/speech2/src/base/README.md deleted file mode 100644 index ae85d4e..0000000 --- a/speech2/src/base/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# base/ - -This basically contains replacements of stuff from the standard library that we can't use on Windows XP because mingw sucks: - -- Mutex -- Thread -- ManualResetEvent -- AutoResetEvent - -Oh and some stuff for dealing with COM diff --git a/speech2/src/base/Thread.cpp b/speech2/src/base/Thread.cpp deleted file mode 100644 index 1fe6bcf..0000000 --- a/speech2/src/base/Thread.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include - -namespace base { - - /*static*/ unsigned Thread::EntryFunc(void* argp) { - auto invocable = static_cast(argp); - (*invocable)(); - - // Usually cross thread frees are a no-no, but the thread effectively - // owns the invocable once it has been passed to it, so /shrug. - delete invocable; - return 0; - } - - Thread::~Thread() { - // Join thread on destruction, unless - // it has already been detached. - if(Joinable()) - Join(); - } - - unsigned Thread::Id() const { - return osdep::BThread_GetID(threadHandle); - } - - bool Thread::Joinable() const { - if(!threadHandle) - return false; - - return joinable; - } - - void Thread::Detach() { - threadHandle = nullptr; - joinable = false; - } - - void Thread::Join() { - if(Joinable()) - osdep::BThread_Join(threadHandle); - } - - - void Thread::SpawnImpl(ThreadInvocable* pInvocable) { - threadHandle = osdep::BThread_Spawn(&Thread::EntryFunc, static_cast(pInvocable), 0); - if(threadHandle != nullptr) - joinable = true; - else { - // Thread failed to create, delete the invocable so we don't leak memory. - delete pInvocable; - } - } -} diff --git a/speech2/src/base/Thread.hpp b/speech2/src/base/Thread.hpp deleted file mode 100644 index aa9c576..0000000 --- a/speech2/src/base/Thread.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once -#include -#include -#include - -namespace base { - -// TODO: Put this in a bits header. -#define __BASE_FWD(T) static_cast - - /// A thread. - struct Thread { - using NativeHandle = osdep::BThreadHandle; - - Thread() = default; - - template - explicit Thread(Func&& func, Args&&... args) { - struct FuncInvocable final : ThreadInvocable { - Func&& func; - std::tuple args; - - constexpr FuncInvocable(Func&& func, Args&&... args) : func(__BASE_FWD(Func)(func)), args({ __BASE_FWD(Args)(args)... }) {} - - constexpr void operator()() override { - std::apply([&](auto&&... argt) { func(__BASE_FWD(Args)(argt)...); }, args); - } - }; - - SpawnImpl(new FuncInvocable(__BASE_FWD(Func)(func), __BASE_FWD(Args)(args)...)); - } - - Thread(const Thread&) = delete; - Thread(Thread&&) = default; - - ~Thread(); - - // TODO: Actually return a OS native thread handle, instead of a BThreads handle. - NativeHandle Native() const { return threadHandle; } - - unsigned Id() const; - - bool Joinable() const; - - // Detaches the native thread. - // Once this function is called the thread - // will no longer be joinable. - void Detach(); - - void Join(); - - private: - // For type erasure. I know it's bad or whatever, but generally, - // it shouldn't be a big enough deal. - struct ThreadInvocable { - virtual ~ThreadInvocable() = default; - virtual void operator()() = 0; - }; - - // Takes the invocable and spawns le epic heckin thread. - void SpawnImpl(ThreadInvocable* pInvocable); - - // Actually recieves a pointer to a [ThreadInvocable] on the heap, - // synthesized from a given function. - static unsigned WINAPI EntryFunc(void* args); - - NativeHandle threadHandle {}; - bool joinable { false }; // implicitly false if there's no thread. - }; -} // namespace base diff --git a/speech2/src/base/comresult.hpp b/speech2/src/base/comresult.hpp deleted file mode 100644 index a927a1a..0000000 --- a/speech2/src/base/comresult.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -template -struct ComResult { - -private: - - using VariantType = std::variant< - HRESULT, - T - >; - - VariantType storage; -};