Skip to content

Commit 4a9b747

Browse files
committed
[TSan] Add interceptors for os_unfair_lock
llvm-svn: 369164
1 parent 97176bd commit 4a9b747

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,59 @@ TSAN_INTERCEPTOR(void, os_lock_unlock, void *lock) {
243243
REAL(os_lock_unlock)(lock);
244244
}
245245

246+
extern "C" {
247+
#define _LOCK_AVAILABILITY \
248+
__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) \
249+
__TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
250+
251+
_LOCK_AVAILABILITY void os_unfair_lock_lock(void *lock);
252+
// NOTE: `options` actually has type `os_unfair_lock_options_t` but this
253+
// should be ABI compatible.
254+
_LOCK_AVAILABILITY void os_unfair_lock_lock_with_options(void *lock,
255+
u32 options);
256+
_LOCK_AVAILABILITY bool os_unfair_lock_trylock(void *lock);
257+
_LOCK_AVAILABILITY void os_unfair_lock_unlock(void *lock);
258+
}
259+
260+
TSAN_INTERCEPTOR(void, os_unfair_lock_lock, void *lock) {
261+
if (!cur_thread()->is_inited || cur_thread()->is_dead) {
262+
return REAL(os_unfair_lock_lock)(lock);
263+
}
264+
SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_lock, lock);
265+
REAL(os_unfair_lock_lock)(lock);
266+
Acquire(thr, pc, (uptr)lock);
267+
}
268+
269+
TSAN_INTERCEPTOR(void, os_unfair_lock_lock_with_options, void *lock,
270+
u32 options) {
271+
if (!cur_thread()->is_inited || cur_thread()->is_dead) {
272+
return REAL(os_unfair_lock_lock_with_options)(lock, options);
273+
}
274+
SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_lock_with_options, lock, options);
275+
REAL(os_unfair_lock_lock_with_options)(lock, options);
276+
Acquire(thr, pc, (uptr)lock);
277+
}
278+
279+
TSAN_INTERCEPTOR(bool, os_unfair_lock_trylock, void *lock) {
280+
if (!cur_thread()->is_inited || cur_thread()->is_dead) {
281+
return REAL(os_unfair_lock_trylock)(lock);
282+
}
283+
SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_trylock, lock);
284+
bool result = REAL(os_unfair_lock_trylock)(lock);
285+
if (result)
286+
Acquire(thr, pc, (uptr)lock);
287+
return result;
288+
}
289+
290+
TSAN_INTERCEPTOR(void, os_unfair_lock_unlock, void *lock) {
291+
if (!cur_thread()->is_inited || cur_thread()->is_dead) {
292+
return REAL(os_unfair_lock_unlock)(lock);
293+
}
294+
SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_unlock, lock);
295+
Release(thr, pc, (uptr)lock);
296+
REAL(os_unfair_lock_unlock)(lock);
297+
}
298+
246299
TSAN_INTERCEPTOR(void, xpc_connection_set_event_handler,
247300
xpc_connection_t connection, xpc_handler_t handler) {
248301
SCOPED_TSAN_INTERCEPTOR(xpc_connection_set_event_handler, connection,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %clang_tsan %s -o %t -mmacosx-version-min=10.12
2+
// RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'
3+
4+
// UNSUPPORTED: ios
5+
6+
#include <os/lock.h>
7+
#include <pthread.h>
8+
#include <stdio.h>
9+
10+
long global_variable;
11+
os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
12+
13+
void *Thread(void *a) {
14+
os_unfair_lock_lock(&lock);
15+
global_variable++;
16+
os_unfair_lock_unlock(&lock);
17+
return NULL;
18+
}
19+
20+
int main() {
21+
pthread_t t1, t2;
22+
global_variable = 0;
23+
pthread_create(&t1, NULL, Thread, NULL);
24+
pthread_create(&t2, NULL, Thread, NULL);
25+
pthread_join(t1, NULL);
26+
pthread_join(t2, NULL);
27+
fprintf(stderr, "global_variable = %ld\n", global_variable);
28+
}
29+
30+
// CHECK: global_variable = 2

0 commit comments

Comments
 (0)