Skip to content

Commit f93fb90

Browse files
committedJun 2, 2024
move lock code to atomic.h
1 parent 0b3cd51 commit f93fb90

File tree

8 files changed

+92
-174
lines changed

8 files changed

+92
-174
lines changed
 

‎include/mimalloc/atomic.h

+91
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub) {
309309
return (intptr_t)mi_atomic_addi(p, -sub);
310310
}
311311

312+
313+
// ----------------------------------------------------------------------
314+
// Once and Guard
315+
// ----------------------------------------------------------------------
316+
312317
typedef _Atomic(uintptr_t) mi_atomic_once_t;
313318

314319
// Returns true only on the first invocation
@@ -329,7 +334,9 @@ typedef _Atomic(uintptr_t) mi_atomic_guard_t;
329334

330335

331336

337+
// ----------------------------------------------------------------------
332338
// Yield
339+
// ----------------------------------------------------------------------
333340
#if defined(__cplusplus)
334341
#include <thread>
335342
static inline void mi_atomic_yield(void) {
@@ -393,4 +400,88 @@ static inline void mi_atomic_yield(void) {
393400
#endif
394401

395402

403+
// ----------------------------------------------------------------------
404+
// Locks are only used for abandoned segment visiting
405+
// ----------------------------------------------------------------------
406+
#if defined(_WIN32)
407+
408+
#define mi_lock_t CRITICAL_SECTION
409+
410+
static inline bool _mi_prim_lock(mi_lock_t* lock) {
411+
EnterCriticalSection(lock);
412+
return true;
413+
}
414+
415+
static inline bool _mi_prim_try_lock(mi_lock_t* lock) {
416+
return TryEnterCriticalSection(lock);
417+
}
418+
419+
static inline void _mi_prim_unlock(mi_lock_t* lock) {
420+
LeaveCriticalSection(lock);
421+
}
422+
423+
424+
#elif defined(MI_USE_PTHREADS)
425+
426+
#define mi_lock_t pthread_mutex_t
427+
428+
static inline bool _mi_prim_lock(mi_lock_t* lock) {
429+
return (pthread_mutex_lock(lock) == 0);
430+
}
431+
432+
static inline bool _mi_prim_try_lock(mi_lock_t* lock) {
433+
return (pthread_mutex_trylock(lock) == 0);
434+
}
435+
436+
static inline void _mi_prim_unlock(mi_lock_t* lock) {
437+
pthread_mutex_unlock(lock);
438+
}
439+
440+
#elif defined(__cplusplus)
441+
442+
#include <mutex>
443+
#define mi_lock_t std::mutex
444+
445+
static inline bool _mi_prim_lock(mi_lock_t* lock) {
446+
lock->lock();
447+
return true;
448+
}
449+
450+
static inline bool _mi_prim_try_lock(mi_lock_t* lock) {
451+
return (lock->try_lock();
452+
}
453+
454+
static inline void _mi_prim_unlock(mi_lock_t* lock) {
455+
lock->unlock();
456+
}
457+
458+
#else
459+
460+
// fall back to poor man's locks.
461+
// this should only be the case in a single-threaded environment (like __wasi__)
462+
463+
#define mi_lock_t _Atomic(uintptr_t)
464+
465+
static inline bool _mi_prim_try_lock(mi_lock_t* lock) {
466+
uintptr_t expected = 0;
467+
return mi_atomic_cas_strong_acq_rel(lock, &expected, (uintptr_t)1);
468+
}
469+
470+
static inline bool _mi_prim_lock(mi_lock_t* lock) {
471+
for (int i = 0; i < 1000; i++) { // for at most 1000 tries?
472+
if (_mi_prim_try_lock(lock)) return true;
473+
mi_atomic_yield();
474+
}
475+
return true;
476+
}
477+
478+
static inline void _mi_prim_unlock(mi_lock_t* lock) {
479+
mi_atomic_store_release(lock, (uintptr_t)0);
480+
}
481+
482+
#endif
483+
484+
485+
486+
396487
#endif // __MIMALLOC_ATOMIC_H

‎include/mimalloc/prim.h

-17
Original file line numberDiff line numberDiff line change
@@ -114,23 +114,6 @@ void _mi_prim_thread_done_auto_done(void);
114114
// Called when the default heap for a thread changes
115115
void _mi_prim_thread_associate_default_heap(mi_heap_t* heap);
116116

117-
// Locks are only used if abandoned segment visiting is permitted
118-
#if defined(_WIN32)
119-
#define mi_lock_t CRITICAL_SECTION
120-
#elif defined(MI_USE_PTHREADS)
121-
#define mi_lock_t pthread_mutex_t
122-
#else
123-
#define mi_lock_t _Atomic(uintptr_t)
124-
#endif
125-
126-
// Take a lock (blocking). Return `true` on success.
127-
bool _mi_prim_lock(mi_lock_t* lock);
128-
129-
// Try to take lock and return `true` if successful.
130-
bool _mi_prim_try_lock(mi_lock_t* lock);
131-
132-
// Release a lock.
133-
void _mi_prim_unlock(mi_lock_t* lock);
134117

135118

136119
//-------------------------------------------------------------------

‎include/mimalloc/types.h

-2
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,6 @@ struct mi_subproc_s {
612612
mi_memid_t memid; // provenance
613613
};
614614

615-
mi_subproc_t* mi_subproc_from_id(mi_subproc_id_t subproc_id);
616-
617615
// ------------------------------------------------------
618616
// Thread Local data
619617
// ------------------------------------------------------

‎src/init.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ mi_subproc_id_t mi_subproc_new(void) {
193193
return subproc;
194194
}
195195

196-
mi_subproc_t* mi_subproc_from_id(mi_subproc_id_t subproc_id) {
196+
static mi_subproc_t* mi_subproc_from_id(mi_subproc_id_t subproc_id) {
197197
return (subproc_id == NULL ? &mi_subproc_default : (mi_subproc_t*)subproc_id);
198198
}
199199

‎src/prim/emscripten/prim.c

-47
Original file line numberDiff line numberDiff line change
@@ -242,50 +242,3 @@ void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {
242242

243243
}
244244
#endif
245-
246-
//----------------------------------------------------------------
247-
// Locks
248-
//----------------------------------------------------------------
249-
250-
#if defined(MI_USE_PTHREADS)
251-
252-
bool _mi_prim_lock(mi_lock_t* lock) {
253-
return (pthread_mutex_lock(lock) == 0);
254-
}
255-
256-
bool _mi_prim_try_lock(mi_lock_t* lock) {
257-
return (pthread_mutex_trylock(lock) == 0);
258-
}
259-
260-
void _mi_prim_unlock(mi_lock_t* lock) {
261-
pthread_mutex_unlock(lock);
262-
}
263-
264-
#else
265-
266-
#include <emscripten.h>
267-
268-
// fall back to poor man's locks.
269-
bool _mi_prim_lock(mi_lock_t* lock) {
270-
for(int i = 0; i < 1000; i++) { // for at most 1 second?
271-
if (_mi_prim_try_lock(lock)) return true;
272-
if (i < 25) {
273-
mi_atomic_yield(); // first yield a bit
274-
}
275-
else {
276-
emscripten_sleep(1); // then sleep for 1ms intervals
277-
}
278-
}
279-
return true;
280-
}
281-
282-
bool _mi_prim_try_lock(mi_lock_t* lock) {
283-
uintptr_t expected = 0;
284-
return mi_atomic_cas_strong_acq_rel(lock,&expected,(uintptr_t)1);
285-
}
286-
287-
void _mi_prim_unlock(mi_lock_t* lock) {
288-
mi_atomic_store_release(lock,(uintptr_t)0);
289-
}
290-
291-
#endif

‎src/prim/unix/prim.c

-47
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ terms of the MIT license. A copy of the license can be found in the file
2222

2323
#include "mimalloc.h"
2424
#include "mimalloc/internal.h"
25-
#include "mimalloc/atomic.h"
2625
#include "mimalloc/prim.h"
2726

2827
#include <sys/mman.h> // mmap
@@ -880,49 +879,3 @@ void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {
880879
}
881880

882881
#endif
883-
884-
885-
//----------------------------------------------------------------
886-
// Locks
887-
//----------------------------------------------------------------
888-
889-
#if defined(MI_USE_PTHREADS)
890-
891-
bool _mi_prim_lock(mi_lock_t* lock) {
892-
return (pthread_mutex_lock(lock) == 0);
893-
}
894-
895-
bool _mi_prim_try_lock(mi_lock_t* lock) {
896-
return (pthread_mutex_trylock(lock) == 0);
897-
}
898-
899-
void _mi_prim_unlock(mi_lock_t* lock) {
900-
pthread_mutex_unlock(lock);
901-
}
902-
903-
#else
904-
905-
// fall back to poor man's locks.
906-
bool _mi_prim_lock(mi_lock_t* lock) {
907-
for(int i = 0; i < 1000; i++) { // for at most 1 second?
908-
if (_mi_prim_try_lock(lock)) return true;
909-
if (i < 25) {
910-
mi_atomic_yield(); // first yield a bit
911-
}
912-
else {
913-
usleep(1000); // then sleep for 1ms intervals
914-
}
915-
}
916-
return true;
917-
}
918-
919-
bool _mi_prim_try_lock(mi_lock_t* lock) {
920-
uintptr_t expected = 0;
921-
return mi_atomic_cas_strong_acq_rel(lock,&expected,(uintptr_t)1);
922-
}
923-
924-
void _mi_prim_unlock(mi_lock_t* lock) {
925-
mi_atomic_store_release(lock,(uintptr_t)0);
926-
}
927-
928-
#endif

‎src/prim/wasi/prim.c

-41
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ terms of the MIT license. A copy of the license can be found in the file
99

1010
#include "mimalloc.h"
1111
#include "mimalloc/internal.h"
12-
#include "mimalloc/atomic.h"
1312
#include "mimalloc/prim.h"
1413

1514
#include <stdio.h> // fputs
@@ -278,43 +277,3 @@ void _mi_prim_thread_done_auto_done(void) {
278277
void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {
279278
MI_UNUSED(heap);
280279
}
281-
282-
//----------------------------------------------------------------
283-
// Locks
284-
//----------------------------------------------------------------
285-
286-
#if defined(MI_USE_PTHREADS)
287-
288-
bool _mi_prim_lock(mi_lock_t* lock) {
289-
return (pthread_mutex_lock(lock) == 0);
290-
}
291-
292-
bool _mi_prim_try_lock(mi_lock_t* lock) {
293-
return (pthread_mutex_trylock(lock) == 0);
294-
}
295-
296-
void _mi_prim_unlock(mi_lock_t* lock) {
297-
pthread_mutex_unlock(lock);
298-
}
299-
300-
#else
301-
302-
// fall back to poor man's locks.
303-
bool _mi_prim_lock(mi_lock_t* lock) {
304-
for(int i = 0; i < 1000; i++) { // for at most 1 second?
305-
if (_mi_prim_try_lock(lock)) return true;
306-
mi_atomic_yield(); // this should never happen as wasi is single threaded?
307-
}
308-
return true;
309-
}
310-
311-
bool _mi_prim_try_lock(mi_lock_t* lock) {
312-
uintptr_t expected = 0;
313-
return mi_atomic_cas_strong_acq_rel(lock,&expected,(uintptr_t)1);
314-
}
315-
316-
void _mi_prim_unlock(mi_lock_t* lock) {
317-
mi_atomic_store_release(lock,(uintptr_t)0);
318-
}
319-
320-
#endif

‎src/prim/windows/prim.c

-19
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ terms of the MIT license. A copy of the license can be found in the file
99

1010
#include "mimalloc.h"
1111
#include "mimalloc/internal.h"
12-
#include "mimalloc/atomic.h"
1312
#include "mimalloc/prim.h"
1413
#include <stdio.h> // fputs, stderr
1514

@@ -563,24 +562,6 @@ bool _mi_prim_getenv(const char* name, char* result, size_t result_size) {
563562
}
564563

565564

566-
//----------------------------------------------------------------
567-
// Locks
568-
//----------------------------------------------------------------
569-
570-
bool _mi_prim_lock(mi_lock_t* lock) {
571-
EnterCriticalSection(lock);
572-
return true;
573-
}
574-
575-
bool _mi_prim_try_lock(mi_lock_t* lock) {
576-
return TryEnterCriticalSection(lock);
577-
}
578-
579-
void _mi_prim_unlock(mi_lock_t* lock) {
580-
LeaveCriticalSection(lock);
581-
}
582-
583-
584565
//----------------------------------------------------------------
585566
// Random
586567
//----------------------------------------------------------------

0 commit comments

Comments
 (0)