Sane C++ Libraries
C++ Platform Abstraction Libraries
Threading.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Foundation/AlignedStorage.h"
5#include "../Foundation/Function.h"
6#include "../Foundation/Result.h"
7#include "Internal/Optional.h" // UniqueOptional
8
9namespace SC
10{
11struct Thread;
12struct ConditionVariable;
13struct Mutex;
14struct EventObject;
15} // namespace SC
16
19
22
28{
29 Mutex();
30 ~Mutex();
31
32 // Underlying OS primitives can't be copied or moved
33 Mutex(const Mutex&) = delete;
34 Mutex(Mutex&&) = delete;
35 Mutex& operator=(const Mutex&) = delete;
36 Mutex& operator=(Mutex&&) = delete;
37
38 void lock();
39 void unlock();
40
41 private:
42 friend struct ConditionVariable;
43#if SC_PLATFORM_APPLE
44 static constexpr int OpaqueMutexSize = 56 + sizeof(long);
45 static constexpr int OpaqueMutexAlignment = alignof(long);
46#elif SC_PLATFORM_WINDOWS
47 static constexpr int OpaqueMutexSize = 4 * sizeof(void*) + 2 * sizeof(long);
48 static constexpr int OpaqueMutexAlignment = alignof(void*);
49#elif SC_PLATFORM_EMSCRIPTEN
50 static constexpr int OpaqueMutexSize = sizeof(void*) * 6 + sizeof(long);
51 static constexpr int OpaqueMutexAlignment = alignof(long);
52#else
53 static constexpr int OpaqueMutexSize = sizeof(void*) * 6;
54 static constexpr int OpaqueMutexAlignment = alignof(long);
55#endif
56 // Wrap native mutex as opaque array of bytes
58 OpaqueMutex mutex;
59};
60
63{
66
67 // Underlying OS primitives can't be copied or moved
68 ConditionVariable(const ConditionVariable&) = delete;
70 ConditionVariable& operator=(const ConditionVariable&) = delete;
71 ConditionVariable& operator=(ConditionVariable&&) = delete;
72
73 void wait(Mutex& mutex);
74 void signal();
75 void broadcast();
76
77 private:
78#if SC_PLATFORM_APPLE
79 static constexpr int OpaqueCVSize = 40 + sizeof(long);
80 static constexpr int OpaqueCVAlignment = alignof(long);
81#elif SC_PLATFORM_WINDOWS
82 static constexpr int OpaqueCVSize = sizeof(void*);
83 static constexpr int OpaqueCVAlignment = alignof(void*);
84#elif SC_PLATFORM_EMSCRIPTEN
85 static constexpr int OpaqueCVSize = sizeof(void*) * 12;
86 static constexpr int OpaqueCVAlignment = alignof(long);
87#else
88 static constexpr int OpaqueCVSize = sizeof(void*) * 6;
89 static constexpr int OpaqueCVAlignment = alignof(long);
90#endif
91
92 // Wrap native condition variable as opaque array of bytes
95};
96
118{
119 Thread() = default;
120 ~Thread();
121
122 // Cannot be copied or moved (as it would require a dynamic allocation for the type erased Function)
123 Thread(Thread&&) = delete;
124 Thread& operator=(Thread&&) = delete;
125 Thread(const Thread&) = delete;
126 Thread& operator=(const Thread&) = delete;
127
131
134
137 [[nodiscard]] Result start(Function<void(Thread&)>&& func);
138
142 void setThreadName(const native_char_t* name);
143
146 [[nodiscard]] Result join();
147
151 [[nodiscard]] Result detach();
152
155 [[nodiscard]] bool wasStarted() const;
156
159 static void Sleep(uint32_t milliseconds);
160
161 private:
162 void setThreadNameInternal(const native_char_t* name);
163 struct Internal;
164 using OpaqueThread = AlignedStorage<sizeof(void*), alignof(void*)>;
165 UniqueOptional<OpaqueThread> thread;
166 Function<void(Thread&)> userFunction;
167};
168
174{
175 bool autoReset = true;
176
178 void wait();
179
181 void signal();
182
183 private:
184 bool isSignaled = false;
185 Mutex mutex;
186
188};
189
char native_char_t
The native char for the platform (wchar_t (4 bytes) on Windows, char (1 byte) everywhere else )
Definition: PrimitiveTypes.h:34
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition: PrimitiveTypes.h:42
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition: PrimitiveTypes.h:38
A native OS condition variable.
Definition: Threading.h:63
An automatically reset event object to synchronize two threads.
Definition: Threading.h:174
void signal()
Unblocks another thread, waiting on EventObject::wait.
void wait()
Waits on a thread for EventObject::signal to be called from another thread.
Wraps function pointers, member functions and lambdas without ever allocating.
Definition: Function.h:50
A native OS mutex to synchronize access to shared resources.
Definition: Threading.h:28
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition: Result.h:12
A native OS thread.
Definition: Threading.h:118
bool wasStarted() const
Check if thread has been started.
static void Sleep(uint32_t milliseconds)
Puts current thread to sleep.
Result start(Function< void(Thread &)> &&func)
Starts the new thread with given name and func.
void setThreadName(const native_char_t *name)
Sets current thread name ONLY if called from inside the thread.
Result detach()
Detaches the thread so that its resources are automatically released back to the system without Threa...
static uint64_t CurrentThreadID()
Returns thread id of the thread calling the function.
uint64_t threadID()
Returns thread id of this thread object (not current thread)
Result join()
Waits for thread to finish and releases its resources.