CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
mutex.h
Go to the documentation of this file.
1
35
36#pragma once
37
38#include <cx/cx.h>
39#include <cx/meta/block.h>
40#include <cx/time/time.h>
41#include <cx/utils/macros.h>
42#include "aspin.h"
43#include "futex.h"
44
45#ifdef CX_LOCK_DEBUG
46#include <cx/log/log.h>
47#endif
48
49CX_C_BEGIN
50
55
60typedef struct Mutex {
61 Futex ftx;
62 AdaptiveSpin aspin;
64
65void _mutexInit(_Out_ Mutex* m, uint32 flags);
66
74#define mutexInit(m, ...) _mutexInit(m, opt_flags(__VA_ARGS__))
75
83_When_(return == true, _Acquires_nonreentrant_lock_(*m))
84 _When_(timeout == timeForever, _Acquires_nonreentrant_lock_(*m))
85 _When_(timeout != timeForever,
86 _Must_inspect_result_) bool mutexTryAcquireTimeout(_Inout_ Mutex* m, int64 timeout);
87
94_Releases_nonreentrant_lock_(*m) bool mutexRelease(_Inout_ Mutex* m);
95
102_When_(return == true,
103 _Acquires_nonreentrant_lock_(
104 *m)) _Must_inspect_result_ _meta_inline bool mutexTryAcquire(_Inout_ Mutex* m)
105{
106 int32 curstate = atomicLoad(int32, &m->ftx.val, Relaxed);
107 if (curstate == 0 &&
108 atomicCompareExchange(int32, strong, &m->ftx.val, &curstate, 1, Acquire, Relaxed)) {
109 aspinRecordUncontended(&m->aspin);
110 return true;
111 }
112 return false;
113}
114
120_Acquires_nonreentrant_lock_(*m) _meta_inline void mutexAcquire(_Inout_ Mutex* m)
121{
123}
124
139#define withMutex(m) blkWrap (mutexAcquire(m), mutexRelease(m))
140
141#ifdef CX_LOCK_DEBUG
142#define _logFmtMutexArgComp2(level, fmt, nargs, args) \
143 _logFmt_##level(LOG_##level, LogDefault, fmt, nargs, args)
144#define _logFmtMutexArgComp(level, fmt, ...) \
145 _logFmtMutexArgComp2(level, fmt, count_macro_args(__VA_ARGS__), (stvar[]) { __VA_ARGS__ })
146_Acquires_nonreentrant_lock_(*m)
147 _meta_inline bool mutexLogAndAcquire(_Inout_ Mutex* m, const char* name, const char* filename,
148 int line)
149{
150 _logFmtMutexArgComp(CX_LOCK_DEBUG,
151 _S"Locking mutex ${string} at ${string}:${int}",
152 stvar(string, (string)name),
153 stvar(string, (string)filename),
154 stvar(int32, line));
155 return mutexAcquire(m);
156}
157
158#define mutexAcquire(m) mutexLogAndAcquire(m, #m, __FILE__, __LINE__)
159#endif
160
161#ifdef CX_LOCK_DEBUG
162_Releases_nonreentrant_lock_(*m)
163 _meta_inline bool mutexLogAndRelease(_Inout_ Mutex* m, const char* name, const char* filename,
164 int line)
165{
166 _logFmtMutexArgComp(CX_LOCK_DEBUG,
167 _S"Releasing mutex ${string} at ${string}:${int}",
168 stvar(string, (string)name),
169 stvar(string, (string)filename),
170 stvar(int32, line));
171 return mutexRelease(m);
172}
173
174#define mutexRelease(m) mutexLogAndRelease(m, #m, __FILE__, __LINE__)
175#endif
176
182void mutexDestroy(_Pre_valid_ _Post_invalid_ Mutex* m);
183
184CX_C_END
185
187// end of thread_mutex group
Block wrapping macros for automatic resource management.
#define _S
Creates a static ASCII string from a string literal.
Definition strbase.h:392
#define stvar(typen, val)
Definition stvar.h:153
bool mutexTryAcquireTimeout(Mutex *m, int64 timeout)
void mutexAcquire(Mutex *m)
Definition mutex.h:120
void mutexDestroy(Mutex *m)
bool mutexTryAcquire(Mutex *m)
Definition mutex.h:104
MUTEX_Flags
Mutex initialization flags.
Definition mutex.h:52
bool mutexRelease(Mutex *m)
@ MUTEX_NoSpin
Disable adaptive spinning, use kernel futex immediately.
Definition mutex.h:53
#define timeForever
Maximum representable time value (approximately year 294,276 CE)
Definition time.h:13
Core logging system API.
Definition mutex.h:60
Futex ftx
Futex for kernel-level synchronization.
Definition mutex.h:61
AdaptiveSpin aspin
Adaptive spin state.
Definition mutex.h:62
Time manipulation and conversion functions.