diff options
Diffstat (limited to 'compiler-rt/lib/tsan/rtl/tsan_mman.cc')
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_mman.cc | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_mman.cc b/compiler-rt/lib/tsan/rtl/tsan_mman.cc index 038407f0749..d3af9a08c19 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_mman.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_mman.cc @@ -63,10 +63,29 @@ Allocator *allocator() { return reinterpret_cast<Allocator*>(&allocator_placeholder); } +struct GlobalProc { + Mutex mtx; + Processor *proc; + + GlobalProc() + : mtx(MutexTypeGlobalProc, StatMtxGlobalProc) + , proc(ProcCreate()) { + } +}; + +static char global_proc_placeholder[sizeof(GlobalProc)] ALIGNED(64); +GlobalProc *global_proc() { + return reinterpret_cast<GlobalProc*>(&global_proc_placeholder); +} + void InitializeAllocator() { allocator()->Init(common_flags()->allocator_may_return_null); } +void InitializeAllocatorLate() { + new(global_proc()) GlobalProc(); +} + void AllocatorProcStart(Processor *proc) { allocator()->InitCache(&proc->alloc_cache); internal_allocator()->InitCache(&proc->internal_alloc_cache); @@ -118,11 +137,29 @@ void *user_calloc(ThreadState *thr, uptr pc, uptr size, uptr n) { } void user_free(ThreadState *thr, uptr pc, void *p, bool signal) { + GlobalProc *gp = nullptr; + if (thr->proc() == nullptr) { + // If we don't have a proc, use the global one. + // There is currently only one known case where this path is triggered: + // __interceptor_free + // __nptl_deallocate_tsd + // start_thread + // clone + // Ideally, we destroy thread state (and unwire proc) when a thread actually + // exits (i.e. when we join/wait it). Then we would not need the global proc + gp = global_proc(); + gp->mtx.Lock(); + ProcWire(gp->proc, thr); + } if (ctx && ctx->initialized) OnUserFree(thr, pc, (uptr)p, true); allocator()->Deallocate(&thr->proc()->alloc_cache, p); if (signal) SignalUnsafeCall(thr, pc); + if (gp) { + ProcUnwire(gp->proc, thr); + gp->mtx.Unlock(); + } } void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write) { |

