1//===-- tsan_interceptors_mac.cc ------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of ThreadSanitizer (TSan), a race detector.
11//
12// Mac-specific interceptors.
13//===----------------------------------------------------------------------===//
14
15#include "sanitizer_common/sanitizer_platform.h"
16#if SANITIZER_MAC
17
18#include "interception/interception.h"
19#include "tsan_interceptors.h"
20
21#include <libkern/OSAtomic.h>
22
23namespace __tsan {
24
25TSAN_INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) {
26  CHECK(!cur_thread()->is_dead);
27  if (!cur_thread()->is_inited) {
28    return REAL(OSSpinLockLock)(lock);
29  }
30  SCOPED_TSAN_INTERCEPTOR(OSSpinLockLock, lock);
31  REAL(OSSpinLockLock)(lock);
32  Acquire(thr, pc, (uptr)lock);
33}
34
35TSAN_INTERCEPTOR(bool, OSSpinLockTry, volatile OSSpinLock *lock) {
36  CHECK(!cur_thread()->is_dead);
37  if (!cur_thread()->is_inited) {
38    return REAL(OSSpinLockTry)(lock);
39  }
40  SCOPED_TSAN_INTERCEPTOR(OSSpinLockTry, lock);
41  bool result = REAL(OSSpinLockTry)(lock);
42  if (result)
43    Acquire(thr, pc, (uptr)lock);
44  return result;
45}
46
47TSAN_INTERCEPTOR(void, OSSpinLockUnlock, volatile OSSpinLock *lock) {
48  CHECK(!cur_thread()->is_dead);
49  if (!cur_thread()->is_inited) {
50    return REAL(OSSpinLockUnlock)(lock);
51  }
52  SCOPED_TSAN_INTERCEPTOR(OSSpinLockUnlock, lock);
53  Release(thr, pc, (uptr)lock);
54  REAL(OSSpinLockUnlock)(lock);
55}
56
57TSAN_INTERCEPTOR(void, os_lock_lock, void *lock) {
58  CHECK(!cur_thread()->is_dead);
59  if (!cur_thread()->is_inited) {
60    return REAL(os_lock_lock)(lock);
61  }
62  SCOPED_TSAN_INTERCEPTOR(os_lock_lock, lock);
63  REAL(os_lock_lock)(lock);
64  Acquire(thr, pc, (uptr)lock);
65}
66
67TSAN_INTERCEPTOR(bool, os_lock_trylock, void *lock) {
68  CHECK(!cur_thread()->is_dead);
69  if (!cur_thread()->is_inited) {
70    return REAL(os_lock_trylock)(lock);
71  }
72  SCOPED_TSAN_INTERCEPTOR(os_lock_trylock, lock);
73  bool result = REAL(os_lock_trylock)(lock);
74  if (result)
75    Acquire(thr, pc, (uptr)lock);
76  return result;
77}
78
79TSAN_INTERCEPTOR(void, os_lock_unlock, void *lock) {
80  CHECK(!cur_thread()->is_dead);
81  if (!cur_thread()->is_inited) {
82    return REAL(os_lock_unlock)(lock);
83  }
84  SCOPED_TSAN_INTERCEPTOR(os_lock_unlock, lock);
85  Release(thr, pc, (uptr)lock);
86  REAL(os_lock_unlock)(lock);
87}
88
89}  // namespace __tsan
90
91#endif  // SANITIZER_MAC
92