Skip to content

Commit bcffc3f

Browse files
committed
Added interception of _os_nospin_lock_lock to fix large atomic storage on macOS
1 parent 229f0a5 commit bcffc3f

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

src/rtcheck.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ struct check_flags_tests
260260
assert(are_all_bits_enabled (to_underlying (check_flags::syscall) + to_underlying (check_flags::openat), 0b0));
261261
auto a1 = to_underlying (check_flags::syscall);
262262
auto a2 = to_underlying (check_flags::openat);
263-
assert(! are_all_bits_enabled (to_underlying (check_flags::syscall) + to_underlying (check_flags::openat), 0b10001000000000000000000000000000000000));
263+
assert(! are_all_bits_enabled (to_underlying (check_flags::syscall) + to_underlying (check_flags::openat), 0b100010000000000000000000000000000000000));
264264
}
265265
};
266266

@@ -687,6 +687,22 @@ INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock)
687687

688688
#pragma clang diagnostic pop
689689

690+
// Newer macOS versions use an internal _os_nospin_lock_lock which is interecpted as per LLVM's RTSan in this commit:
691+
// https://code.ornl.gov/llvm-doe/llvm-project/-/commit/481a55a3d9645a6bc1540d326319b78ad8ed8db1
692+
extern "C" {
693+
// A pointer to this type is in the interface for `_os_nospin_lock_lock`, but
694+
// it's an internal implementation detail of `os/lock.c` on Darwin, and
695+
// therefore not available in any headers. As a workaround, we forward declare
696+
// it here, which is enough to facilitate interception of _os_nospin_lock_lock.
697+
struct _os_nospin_lock_s;
698+
using _os_nospin_lock_t = _os_nospin_lock_s *;
699+
}
700+
701+
INTERCEPTOR(void, _os_nospin_lock_lock, _os_nospin_lock_t lock) {
702+
log_function_if_realtime_context_and_enabled (rtc::check_flags::os_unfair_lock_lock, __func__);
703+
return REAL(_os_nospin_lock_lock)(lock);
704+
}
705+
690706
#endif
691707

692708
//==============================================================================

src/rtcheck.h

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -108,40 +108,42 @@ namespace rtc
108108
futex = 1 << 23, // linux only
109109
OSSpinLockLock = 1 << 24, // apple only
110110
os_unfair_lock_lock = 1 << 25, // apple only
111+
_os_nospin_lock_lock = 1 << 26, // apple only
111112

112113
threads = pthread_create | pthread_mutex_lock | pthread_mutex_unlock | pthread_join
113114
| pthread_cond_signal | pthread_cond_broadcast | pthread_cond_wait
114115
| pthread_rwlock_init | pthread_rwlock_destroy | pthread_cond_timedwait
115116
| pthread_rwlock_rdlock | pthread_rwlock_unlock | pthread_rwlock_wrlock
116-
| pthread_spin_lock | futex | OSSpinLockLock | os_unfair_lock_lock,
117+
| pthread_spin_lock | futex | OSSpinLockLock | os_unfair_lock_lock
118+
| _os_nospin_lock_lock,
117119

118120
//==============================================================================
119121
// sleeping
120122
//==============================================================================
121-
sleep = 1 << 26,
122-
usleep = 1 << 27,
123-
nanosleep = 1 << 28,
123+
sleep = 1 << 27,
124+
usleep = 1 << 28,
125+
nanosleep = 1 << 29,
124126

125127
sleeping = sleep | usleep | nanosleep,
126128

127129
//==============================================================================
128130
// files
129131
//==============================================================================
130-
stat = 1 << 29,
131-
fstat = 1 << 30,
132-
open = 1ull << 31,
133-
fopen = 1ull << 32,
134-
openat = 1ull << 33,
135-
fcntl = 1ull << 34,
132+
stat = 1 << 30,
133+
fstat = 1ull << 31,
134+
open = 1ull << 32,
135+
fopen = 1ull << 33,
136+
openat = 1ull << 34,
137+
fcntl = 1ull << 35,
136138

137139
files = stat | fstat | open | fopen | openat,
138140

139141
//==============================================================================
140142
// system
141143
//==============================================================================
142-
schedule = 1ull << 35, // linux only
143-
context_switch = 1ull << 36, // linux only
144-
syscall = 1ull << 37,
144+
schedule = 1ull << 36, // linux only
145+
context_switch = 1ull << 37, // linux only
146+
syscall = 1ull << 38,
145147

146148
sys = schedule | context_switch | syscall
147149
};

tests/fail_large_atomic.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include <atomic>
2+
#include <cassert>
3+
#include <array>
24
#include <rtcheck.h>
35

46
struct doubles
@@ -9,7 +11,9 @@ struct doubles
911
int main()
1012
{
1113
std::atomic<doubles> a;
12-
doubles d;
14+
assert (! a.is_lock_free());
15+
16+
doubles d { 1.0, 2.0, 3.0, 4.0 };
1317

1418
rtc::realtime_context rc;
1519
a.store (d);

0 commit comments

Comments
 (0)