Updates and fixes to Mutex (#933)

Updating Mutex to have specific types: TimedMutex, RecursiveMutex, TimedRecursiveMutex. Fixes to the win32 implementation.
This commit is contained in:
Christoffer Lerno
2023-08-16 15:45:49 +02:00
committed by GitHub
parent 8a4337e819
commit e694d60f23
5 changed files with 34 additions and 10 deletions

View File

@@ -10,6 +10,8 @@ struct NativeMutex
Win32_CRITICAL_SECTION critical_section;
Win32_HANDLE handle;
}
// Size is less than a Win32_HANDLE so due to alignment
// there is no benefit to pack these into a bitstruct.
bool already_locked;
bool recursive;
bool timed;
@@ -102,7 +104,16 @@ fn void! NativeMutex.lock_timeout(&mtx, usz ms)
}
if (!mtx.recursive)
{
while (mtx.already_locked) win32::sleep(1);
usz left_timeout = ms - 1;
while (mtx.already_locked)
{
if (left_timeout-- == 0)
{
win32::releaseMutex(mtx.handle);
return ThreadFault.LOCK_TIMEOUT?;
}
win32::sleep(1);
}
mtx.already_locked = true;
}
}
@@ -118,8 +129,14 @@ fn bool NativeMutex.try_lock(&mtx)
{
if (mtx.already_locked)
{
assert(!mtx.timed);
win32::leaveCriticalSection(&mtx.critical_section);
if (mtx.timed)
{
win32::releaseMutex(mtx.handle);
}
else
{
win32::leaveCriticalSection(&mtx.critical_section);
}
return false;
}
mtx.already_locked = true;

View File

@@ -8,6 +8,9 @@ const MutexType MUTEX_TIMED = 1;
const MutexType MUTEX_RECURSIVE = 2;
def Mutex = distinct NativeMutex;
def TimedMutex = distinct inline Mutex;
def RecursiveMutex = distinct inline Mutex;
def TimedRecursiveMutex = distinct inline Mutex;
def ConditionVariable = distinct NativeConditionVariable;
def Thread = distinct NativeThread;
def OnceFlag = distinct NativeOnceFlag;
@@ -30,10 +33,14 @@ fault ThreadFault
INTERRUPTED,
}
macro void! Mutex.init(&mutex, MutexType type = MUTEX_PLAIN) => NativeMutex.init((NativeMutex*)mutex, type);
macro void! Mutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_PLAIN);
macro void! TimedMutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_TIMED);
macro void! RecursiveMutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_RECURSIVE);
macro void! TimedRecursiveMutex.init(&mutex) => NativeMutex.init((NativeMutex*)mutex, MUTEX_TIMED | MUTEX_RECURSIVE);
macro void! Mutex.destroy(&mutex) => NativeMutex.destroy((NativeMutex*)mutex);
macro void! Mutex.lock(&mutex) => NativeMutex.lock((NativeMutex*)mutex);
macro void! Mutex.lock_timeout(&mutex, ulong ms) => NativeMutex.lock_timeout((NativeMutex*)mutex, ms);
macro void! TimedMutex.lock_timeout(&mutex, ulong ms) => NativeMutex.lock_timeout((NativeMutex*)mutex, ms);
macro void! TimedRecursiveMutex.lock_timeout(&mutex, ulong ms) => NativeMutex.lock_timeout((NativeMutex*)mutex, ms);
macro bool Mutex.try_lock(&mutex) => NativeMutex.try_lock((NativeMutex*)mutex);
macro void! Mutex.unlock(&mutex) => NativeMutex.unlock((NativeMutex*)mutex);

View File

@@ -1025,13 +1025,12 @@ static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl)
SEMA_ERROR(decl, "You cannot create a distinct type from an optional.");
return false;
}
Type *base = type_flatten(info->type);
Type *base = info->type->canonical;
decl->distinct_decl.base_type = base;
switch (base->type_kind)
{
case TYPE_FUNC:
case TYPE_TYPEDEF:
case TYPE_DISTINCT:
case CT_TYPES:
case TYPE_FLEXIBLE_ARRAY:
UNREACHABLE
@@ -1059,6 +1058,7 @@ static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl)
case TYPE_ARRAY:
case TYPE_SUBARRAY:
case TYPE_VECTOR:
case TYPE_DISTINCT:
break;
}
// Do we need anything else?

View File

@@ -6,7 +6,7 @@ fn void! copy_map() @test
{
TrackingAllocator alloc;
alloc.init(mem::heap());
io::printfn("Heap mem: %d", alloc.allocated());
assert(alloc.allocated() == 0);
mem::@scoped(&alloc)
{
HashMap(<String, int>) x;

View File

@@ -21,7 +21,7 @@ fn void! testrun_mutex() @test
{
Thread[100] ts;
a = 0;
m.init(thread::MUTEX_PLAIN)!;
m.init()!;
foreach (&t : ts)
{
t.create(fn int(void* arg) {
@@ -60,7 +60,7 @@ fn void! testrun_mutex_try() @test
fn void! testrun_mutex_timeout() @test
{
Mutex m;
TimedMutex m;
m.init()!;
m.lock()!;
if (try m.lock_timeout(100))