My understanding is that an atomic_mutex spins for a bit and then sleeps using a futex if it can’t get the lock. If it gets the lock then performance is identical to a spinlock.
Then is atomic_mutex_try_lock something that behaves like a compare_exchange which is lock free?
I’m trying to decide if I should just use this instead of using atomics directly for a job system. If there are performance reasons not to use it then I’d like to know them.
EDIT: Okay, this is going to sound dumb. I assumed since other sync primitives didn’t have source code when I checked then this wouldn’t have it either. I just checked again and it’s there clear as day. It does indeed behave how I think it does, sorry for the pointless post.
EDIT2: I guess I can ask something else I’m curious about. Why use a mutex when atomic_mutex exists?
Atomic_Mutex
is the native Odin implementation of a mutex. Mutex
is an abstraction layer that encompasses Atomic_Mutex
on all non-Windows platforms. On Windows, we use shared reader-writer locks which are more performant. Use Mutex
.
The various try_lock
procedures will not block if you run them, so yes, they are lock-free.
The code is in fact just a compare_exchange as you can see:
// atomic_mutex_try_lock tries to lock m, will return true on success, and false on failure
atomic_mutex_try_lock :: proc "contextless" (m: ^Atomic_Mutex) -> bool {
_, ok := atomic_compare_exchange_strong_explicit(&m.state, .Unlocked, .Locked, .Acquire, .Consume)
return ok
}
I’m not sure what this means. You should have source code for everything in core
.
1 Like
Blockquote
I’m not sure what this means. You should have source code for everything in core
.
I mean like the mutex for example. Is there source for the _Mutex type somewhere? Thanks for answering by the way.
Mutex :: struct #no_copy {
impl: _Mutex,
}
mutex_unlock :: proc "contextless" (m: ^Mutex) {
_mutex_unlock(m)
}
mutex_try_lock :: proc "contextless" (m: ^Mutex) -> bool {
return _mutex_try_lock(m)
}
Indeed. I just grepped for _Mutex ::
and found the non-Windows implementation under primitives_internal.odin
and the Windows implementation under primitives_windows.odin
.
1 Like
I’ll go check those out. Sorry for the trouble.