[llvm-commits] [compiler-rt] r172380 - in /compiler-rt/trunk/lib: asan/ sanitizer_common/ sanitizer_common/tests/ tsan/ tsan/rtl/

Dmitry Vyukov dvyukov at google.com
Sun Jan 13 23:51:39 PST 2013


Author: dvyukov
Date: Mon Jan 14 01:51:39 2013
New Revision: 172380

URL: http://llvm.org/viewvc/llvm-project?rev=172380&view=rev
Log:
asan/tsan: move blocking mutex from asan to sanitizer_common

Modified:
    compiler-rt/trunk/lib/asan/asan_allocator.cc
    compiler-rt/trunk/lib/asan/asan_globals.cc
    compiler-rt/trunk/lib/asan/asan_linux.cc
    compiler-rt/trunk/lib/asan/asan_lock.h
    compiler-rt/trunk/lib/asan/asan_mac.cc
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/asan/asan_stats.cc
    compiler-rt/trunk/lib/asan/asan_thread_registry.cc
    compiler-rt/trunk/lib/asan/asan_thread_registry.h
    compiler-rt/trunk/lib/asan/asan_win.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
    compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt
    compiler-rt/trunk/lib/tsan/Makefile.old
    compiler-rt/trunk/lib/tsan/rtl/Makefile.old

Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.cc Mon Jan 14 01:51:39 2013
@@ -29,7 +29,6 @@
 #if ASAN_ALLOCATOR_VERSION == 1
 #include "asan_interceptors.h"
 #include "asan_internal.h"
-#include "asan_lock.h"
 #include "asan_mapping.h"
 #include "asan_stats.h"
 #include "asan_report.h"
@@ -37,6 +36,7 @@
 #include "asan_thread_registry.h"
 #include "sanitizer/asan_interface.h"
 #include "sanitizer_common/sanitizer_atomic.h"
+#include "sanitizer_common/sanitizer_mutex.h"
 
 namespace __asan {
 
@@ -229,7 +229,7 @@
     AsanChunk *m = 0;
     AsanChunk **fl = &free_lists_[size_class];
     {
-      ScopedLock lock(&mu_);
+      BlockingMutexLock lock(&mu_);
       for (uptr i = 0; i < n_chunks; i++) {
         if (!(*fl)) {
           *fl = GetNewChunks(size_class);
@@ -247,7 +247,7 @@
   void SwallowThreadLocalMallocStorage(AsanThreadLocalMallocStorage *x,
                                        bool eat_free_lists) {
     CHECK(flags()->quarantine_size > 0);
-    ScopedLock lock(&mu_);
+    BlockingMutexLock lock(&mu_);
     AsanChunkFifoList *q = &x->quarantine_;
     if (q->size() > 0) {
       quarantine_.PushList(q);
@@ -271,18 +271,18 @@
   }
 
   void BypassThreadLocalQuarantine(AsanChunk *chunk) {
-    ScopedLock lock(&mu_);
+    BlockingMutexLock lock(&mu_);
     quarantine_.Push(chunk);
   }
 
   AsanChunk *FindChunkByAddr(uptr addr) {
-    ScopedLock lock(&mu_);
+    BlockingMutexLock lock(&mu_);
     return FindChunkByAddrUnlocked(addr);
   }
 
   uptr AllocationSize(uptr ptr) {
     if (!ptr) return 0;
-    ScopedLock lock(&mu_);
+    BlockingMutexLock lock(&mu_);
 
     // Make sure this is our chunk and |ptr| actually points to the beginning
     // of the allocated memory.
@@ -305,7 +305,7 @@
   }
 
   void PrintStatus() {
-    ScopedLock lock(&mu_);
+    BlockingMutexLock lock(&mu_);
     uptr malloced = 0;
 
     Printf(" MallocInfo: in quarantine: %zu malloced: %zu; ",
@@ -323,7 +323,7 @@
   }
 
   PageGroup *FindPageGroup(uptr addr) {
-    ScopedLock lock(&mu_);
+    BlockingMutexLock lock(&mu_);
     return FindPageGroupUnlocked(addr);
   }
 
@@ -481,7 +481,7 @@
 
   AsanChunk *free_lists_[kNumberOfSizeClasses];
   AsanChunkFifoList quarantine_;
-  AsanLock mu_;
+  BlockingMutex mu_;
 
   PageGroup *page_groups_[kMaxAvailableRam / kMinMmapSize];
   atomic_uint32_t n_page_groups_;

Modified: compiler-rt/trunk/lib/asan/asan_globals.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_globals.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_globals.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_globals.cc Mon Jan 14 01:51:39 2013
@@ -13,13 +13,13 @@
 //===----------------------------------------------------------------------===//
 #include "asan_interceptors.h"
 #include "asan_internal.h"
-#include "asan_lock.h"
 #include "asan_mapping.h"
 #include "asan_report.h"
 #include "asan_stack.h"
 #include "asan_stats.h"
 #include "asan_thread.h"
 #include "sanitizer/asan_interface.h"
+#include "sanitizer_common/sanitizer_mutex.h"
 
 namespace __asan {
 
@@ -30,7 +30,7 @@
   ListOfGlobals *next;
 };
 
-static AsanLock mu_for_globals(LINKER_INITIALIZED);
+static BlockingMutex mu_for_globals(LINKER_INITIALIZED);
 static LowLevelAllocator allocator_for_globals;
 static ListOfGlobals *list_of_all_globals;
 static ListOfGlobals *list_of_dynamic_init_globals;
@@ -62,7 +62,7 @@
 
 bool DescribeAddressIfGlobal(uptr addr) {
   if (!flags()->report_globals) return false;
-  ScopedLock lock(&mu_for_globals);
+  BlockingMutexLock lock(&mu_for_globals);
   bool res = false;
   for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
     const Global &g = *l->g;
@@ -146,7 +146,7 @@
 void __asan_register_global(uptr addr, uptr size,
                             const char *name) {
   if (!flags()->report_globals) return;
-  ScopedLock lock(&mu_for_globals);
+  BlockingMutexLock lock(&mu_for_globals);
   Global *g = (Global *)allocator_for_globals.Allocate(sizeof(Global));
   g->beg = addr;
   g->size = size;
@@ -158,7 +158,7 @@
 // Register an array of globals.
 void __asan_register_globals(__asan_global *globals, uptr n) {
   if (!flags()->report_globals) return;
-  ScopedLock lock(&mu_for_globals);
+  BlockingMutexLock lock(&mu_for_globals);
   for (uptr i = 0; i < n; i++) {
     RegisterGlobal(&globals[i]);
   }
@@ -168,7 +168,7 @@
 // We must do this when a shared objects gets dlclosed.
 void __asan_unregister_globals(__asan_global *globals, uptr n) {
   if (!flags()->report_globals) return;
-  ScopedLock lock(&mu_for_globals);
+  BlockingMutexLock lock(&mu_for_globals);
   for (uptr i = 0; i < n; i++) {
     UnregisterGlobal(&globals[i]);
   }
@@ -181,7 +181,7 @@
 void __asan_before_dynamic_init(uptr first_addr, uptr last_addr) {
   if (!flags()->check_initialization_order) return;
   CHECK(list_of_dynamic_init_globals);
-  ScopedLock lock(&mu_for_globals);
+  BlockingMutexLock lock(&mu_for_globals);
   bool from_current_tu = false;
   // The list looks like:
   // a => ... => b => last_addr => ... => first_addr => c => ...
@@ -202,7 +202,7 @@
 // TU are poisoned.  It simply unpoisons all dynamically initialized globals.
 void __asan_after_dynamic_init() {
   if (!flags()->check_initialization_order) return;
-  ScopedLock lock(&mu_for_globals);
+  BlockingMutexLock lock(&mu_for_globals);
   for (ListOfGlobals *l = list_of_dynamic_init_globals; l; l = l->next)
     UnpoisonGlobal(l->g);
 }

Modified: compiler-rt/trunk/lib/asan/asan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_linux.cc Mon Jan 14 01:51:39 2013
@@ -15,7 +15,6 @@
 
 #include "asan_interceptors.h"
 #include "asan_internal.h"
-#include "asan_lock.h"
 #include "asan_thread.h"
 #include "asan_thread_registry.h"
 #include "sanitizer_common/sanitizer_libc.h"
@@ -102,26 +101,6 @@
   // Nothing here for now.
 }
 
-AsanLock::AsanLock(LinkerInitialized) {
-  // We assume that pthread_mutex_t initialized to all zeroes is a valid
-  // unlocked mutex. We can not use PTHREAD_MUTEX_INITIALIZER as it triggers
-  // a gcc warning:
-  // extended initializer lists only available with -std=c++0x or -std=gnu++0x
-}
-
-void AsanLock::Lock() {
-  CHECK(sizeof(pthread_mutex_t) <= sizeof(opaque_storage_));
-  pthread_mutex_lock((pthread_mutex_t*)&opaque_storage_);
-  CHECK(!owner_);
-  owner_ = (uptr)pthread_self();
-}
-
-void AsanLock::Unlock() {
-  CHECK(owner_ == (uptr)pthread_self());
-  owner_ = 0;
-  pthread_mutex_unlock((pthread_mutex_t*)&opaque_storage_);
-}
-
 void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) {
 #if defined(__arm__) || \
     defined(__powerpc__) || defined(__powerpc64__) || \

Modified: compiler-rt/trunk/lib/asan/asan_lock.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_lock.h?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_lock.h (original)
+++ compiler-rt/trunk/lib/asan/asan_lock.h Mon Jan 14 01:51:39 2013
@@ -1,42 +0,0 @@
-//===-- asan_lock.h ---------------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// A wrapper for a simple lock.
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_LOCK_H
-#define ASAN_LOCK_H
-
-#include "sanitizer_common/sanitizer_mutex.h"
-#include "asan_internal.h"
-
-// The locks in ASan are global objects and they are never destroyed to avoid
-// at-exit races (that is, a lock is being used by other threads while the main
-// thread is doing atexit destructors).
-// We define the class using opaque storage to avoid including system headers.
-
-namespace __asan {
-
-class AsanLock {
- public:
-  explicit AsanLock(LinkerInitialized);
-  void Lock();
-  void Unlock();
-  bool IsLocked() { return owner_ != 0; }
- private:
-  uptr opaque_storage_[10];
-  uptr owner_;  // for debugging and for malloc_introspection_t interface
-};
-
-typedef GenericScopedLock<AsanLock> ScopedLock;
-
-}  // namespace __asan
-
-#endif  // ASAN_LOCK_H

Modified: compiler-rt/trunk/lib/asan/asan_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Mon Jan 14 01:51:39 2013
@@ -141,25 +141,6 @@
   }
 }
 
-AsanLock::AsanLock(LinkerInitialized) {
-  // We assume that OS_SPINLOCK_INIT is zero
-}
-
-void AsanLock::Lock() {
-  CHECK(sizeof(OSSpinLock) <= sizeof(opaque_storage_));
-  CHECK(OS_SPINLOCK_INIT == 0);
-  CHECK(owner_ != (uptr)pthread_self());
-  OSSpinLockLock((OSSpinLock*)&opaque_storage_);
-  CHECK(!owner_);
-  owner_ = (uptr)pthread_self();
-}
-
-void AsanLock::Unlock() {
-  CHECK(owner_ == (uptr)pthread_self());
-  owner_ = 0;
-  OSSpinLockUnlock((OSSpinLock*)&opaque_storage_);
-}
-
 void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) {
   (void)fast;
   stack->size = 0;

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Mon Jan 14 01:51:39 2013
@@ -14,7 +14,6 @@
 #include "asan_allocator.h"
 #include "asan_interceptors.h"
 #include "asan_internal.h"
-#include "asan_lock.h"
 #include "asan_mapping.h"
 #include "asan_report.h"
 #include "asan_stack.h"

Modified: compiler-rt/trunk/lib/asan/asan_stats.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_stats.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_stats.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_stats.cc Mon Jan 14 01:51:39 2013
@@ -13,7 +13,6 @@
 //===----------------------------------------------------------------------===//
 #include "asan_interceptors.h"
 #include "asan_internal.h"
-#include "asan_lock.h"
 #include "asan_stats.h"
 #include "asan_thread_registry.h"
 #include "sanitizer/asan_interface.h"
@@ -55,13 +54,13 @@
              malloc_large, malloc_small_slow);
 }
 
-static AsanLock print_lock(LINKER_INITIALIZED);
+static BlockingMutex print_lock(LINKER_INITIALIZED);
 
 static void PrintAccumulatedStats() {
   AsanStats stats;
   asanThreadRegistry().GetAccumulatedStats(&stats);
   // Use lock to keep reports from mixing up.
-  ScopedLock lock(&print_lock);
+  BlockingMutexLock lock(&print_lock);
   stats.Print();
   StackDepotStats *stack_depot_stats = StackDepotGetStats();
   Printf("Stats: StackDepot: %zd ids; %zdM mapped\n",

Modified: compiler-rt/trunk/lib/asan/asan_thread_registry.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread_registry.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread_registry.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_thread_registry.cc Mon Jan 14 01:51:39 2013
@@ -44,7 +44,7 @@
 }
 
 void AsanThreadRegistry::RegisterThread(AsanThread *thread) {
-  ScopedLock lock(&mu_);
+  BlockingMutexLock lock(&mu_);
   u32 tid = n_threads_;
   n_threads_++;
   CHECK(n_threads_ < kMaxNumberOfThreads);
@@ -56,7 +56,7 @@
 }
 
 void AsanThreadRegistry::UnregisterThread(AsanThread *thread) {
-  ScopedLock lock(&mu_);
+  BlockingMutexLock lock(&mu_);
   FlushToAccumulatedStatsUnlocked(&thread->stats());
   AsanThreadSummary *summary = thread->summary();
   CHECK(summary);
@@ -105,13 +105,13 @@
 }
 
 void AsanThreadRegistry::GetAccumulatedStats(AsanStats *stats) {
-  ScopedLock lock(&mu_);
+  BlockingMutexLock lock(&mu_);
   UpdateAccumulatedStatsUnlocked();
   internal_memcpy(stats, &accumulated_stats_, sizeof(accumulated_stats_));
 }
 
 uptr AsanThreadRegistry::GetCurrentAllocatedBytes() {
-  ScopedLock lock(&mu_);
+  BlockingMutexLock lock(&mu_);
   UpdateAccumulatedStatsUnlocked();
   uptr malloced = accumulated_stats_.malloced;
   uptr freed = accumulated_stats_.freed;
@@ -121,13 +121,13 @@
 }
 
 uptr AsanThreadRegistry::GetHeapSize() {
-  ScopedLock lock(&mu_);
+  BlockingMutexLock lock(&mu_);
   UpdateAccumulatedStatsUnlocked();
   return accumulated_stats_.mmaped - accumulated_stats_.munmaped;
 }
 
 uptr AsanThreadRegistry::GetFreeBytes() {
-  ScopedLock lock(&mu_);
+  BlockingMutexLock lock(&mu_);
   UpdateAccumulatedStatsUnlocked();
   uptr total_free = accumulated_stats_.mmaped
                   - accumulated_stats_.munmaped
@@ -143,7 +143,7 @@
 // Return several stats counters with a single call to
 // UpdateAccumulatedStatsUnlocked().
 void AsanThreadRegistry::FillMallocStatistics(AsanMallocStats *malloc_stats) {
-  ScopedLock lock(&mu_);
+  BlockingMutexLock lock(&mu_);
   UpdateAccumulatedStatsUnlocked();
   malloc_stats->blocks_in_use = accumulated_stats_.mallocs;
   malloc_stats->size_in_use = accumulated_stats_.malloced;
@@ -158,7 +158,7 @@
 }
 
 AsanThread *AsanThreadRegistry::FindThreadByStackAddress(uptr addr) {
-  ScopedLock lock(&mu_);
+  BlockingMutexLock lock(&mu_);
   for (u32 tid = 0; tid < n_threads_; tid++) {
     AsanThread *t = thread_summaries_[tid]->thread();
     if (!t || !(t->fake_stack().StackSize())) continue;

Modified: compiler-rt/trunk/lib/asan/asan_thread_registry.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread_registry.h?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread_registry.h (original)
+++ compiler-rt/trunk/lib/asan/asan_thread_registry.h Mon Jan 14 01:51:39 2013
@@ -15,10 +15,10 @@
 #ifndef ASAN_THREAD_REGISTRY_H
 #define ASAN_THREAD_REGISTRY_H
 
-#include "asan_lock.h"
 #include "asan_stack.h"
 #include "asan_stats.h"
 #include "asan_thread.h"
+#include "sanitizer_common/sanitizer_mutex.h"
 
 namespace __asan {
 
@@ -73,7 +73,7 @@
   // per-thread AsanStats.
   uptr max_malloced_memory_;
   u32 n_threads_;
-  AsanLock mu_;
+  BlockingMutex mu_;
   bool inited_;
 };
 

Modified: compiler-rt/trunk/lib/asan/asan_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win.cc Mon Jan 14 01:51:39 2013
@@ -19,15 +19,14 @@
 
 #include "asan_interceptors.h"
 #include "asan_internal.h"
-#include "asan_lock.h"
 #include "asan_thread.h"
 #include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_placement_new.h"
+#include "sanitizer_common/sanitizer_mutex.h"
 
 namespace __asan {
 
 // ---------------------- Stacktraces, symbols, etc. ---------------- {{{1
-static AsanLock dbghelp_lock(LINKER_INITIALIZED);
+static BlockingMutex dbghelp_lock(LINKER_INITIALIZED);
 static bool dbghelp_initialized = false;
 #pragma comment(lib, "dbghelp.lib")
 
@@ -55,42 +54,6 @@
     stack->trace[i] = (uptr)tmp[i + offset];
 }
 
-// ---------------------- AsanLock ---------------- {{{1
-enum LockState {
-  LOCK_UNINITIALIZED = 0,
-  LOCK_READY = -1,
-};
-
-AsanLock::AsanLock(LinkerInitialized li) {
-  // FIXME: see comments in AsanLock::Lock() for the details.
-  CHECK(li == LINKER_INITIALIZED || owner_ == LOCK_UNINITIALIZED);
-
-  CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_));
-  InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_);
-  owner_ = LOCK_READY;
-}
-
-void AsanLock::Lock() {
-  if (owner_ == LOCK_UNINITIALIZED) {
-    // FIXME: hm, global AsanLock objects are not initialized?!?
-    // This might be a side effect of the clang+cl+link Frankenbuild...
-    new(this) AsanLock((LinkerInitialized)(LINKER_INITIALIZED + 1));
-
-    // FIXME: If it turns out the linker doesn't invoke our
-    // constructors, we should probably manually Lock/Unlock all the global
-    // locks while we're starting in one thread to avoid double-init races.
-  }
-  EnterCriticalSection((LPCRITICAL_SECTION)opaque_storage_);
-  CHECK(owner_ == LOCK_READY);
-  owner_ = GetThreadSelf();
-}
-
-void AsanLock::Unlock() {
-  CHECK(owner_ == GetThreadSelf());
-  owner_ = LOCK_READY;
-  LeaveCriticalSection((LPCRITICAL_SECTION)opaque_storage_);
-}
-
 // ---------------------- TSD ---------------- {{{1
 static bool tsd_key_inited = false;
 
@@ -151,7 +114,7 @@
 extern "C" {
 SANITIZER_INTERFACE_ATTRIBUTE NOINLINE
 bool __asan_symbolize(const void *addr, char *out_buffer, int buffer_size) {
-  ScopedLock lock(&dbghelp_lock);
+  BlockingMutexLock lock(&dbghelp_lock);
   if (!dbghelp_initialized) {
     SymSetOptions(SYMOPT_DEFERRED_LOADS |
                   SYMOPT_UNDNAME |

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h Mon Jan 14 01:51:39 2013
@@ -234,7 +234,7 @@
   Batch *NOINLINE AllocateBatch(AllocatorCache *c, uptr class_id) {
     CHECK_LT(class_id, kNumClasses);
     RegionInfo *region = GetRegionInfo(class_id);
-    SpinMutexLock l(&region->mutex);
+    BlockingMutexLock l(&region->mutex);
     if (region->free_list.empty())
       PopulateFreeList(c, class_id, region);
     CHECK(!region->free_list.empty());
@@ -246,7 +246,7 @@
 
   void NOINLINE DeallocateBatch(uptr class_id, Batch *b) {
     RegionInfo *region = GetRegionInfo(class_id);
-    SpinMutexLock l(&region->mutex);
+    BlockingMutexLock l(&region->mutex);
     region->free_list.push_front(b);
     region->n_freed++;
   }
@@ -343,7 +343,7 @@
   static const uptr kMetaMapSize = 1 << 16;
 
   struct RegionInfo {
-    SpinMutex mutex;
+    BlockingMutex mutex;
     IntrusiveList<Batch> free_list;
     uptr allocated_user;  // Bytes allocated for user memory.
     uptr allocated_meta;  // Bytes allocated for metadata.

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Mon Jan 14 01:51:39 2013
@@ -34,6 +34,7 @@
 #include <unwind.h>
 #include <errno.h>
 #include <sys/prctl.h>
+#include <linux/futex.h>
 
 // Are we using 32-bit or 64-bit syscalls?
 // x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 32
@@ -436,6 +437,34 @@
 
 #endif  // #ifndef SANITIZER_GO
 
+enum MutexState {
+  MtxUnlocked = 0,
+  MtxLocked = 1,
+  MtxSleeping = 2
+};
+
+BlockingMutex::BlockingMutex(LinkerInitialized) {
+}
+
+void BlockingMutex::Lock() {
+  atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
+  if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked)
+    return;
+  while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked)
+    syscall(__NR_futex, m, FUTEX_WAIT_PRIVATE, MtxSleeping, 0, 0, 0);
+}
+
+void BlockingMutex::Unlock() {
+  atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
+  u32 v = atomic_exchange(m, MtxUnlocked, memory_order_relaxed);
+  if (v == MtxUnlocked) {
+    Printf("FATAL: unlock of unlocked mutex\n");
+    Die();
+  }
+  if (v == MtxSleeping)
+    syscall(__NR_futex, m, FUTEX_WAKE_PRIVATE, 1, 0, 0, 0);
+}
+
 }  // namespace __sanitizer
 
 #endif  // __linux__

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc Mon Jan 14 01:51:39 2013
@@ -267,6 +267,25 @@
   return IterateForObjectNameAndOffset(addr, offset, filename, filename_size);
 }
 
+BlockingMutex::BlockingMutex(LinkerInitialized) {
+  // We assume that OS_SPINLOCK_INIT is zero
+}
+
+void BlockingMutex::Lock() {
+  CHECK(sizeof(OSSpinLock) <= sizeof(opaque_storage_));
+  CHECK(OS_SPINLOCK_INIT == 0);
+  CHECK(owner_ != (uptr)pthread_self());
+  OSSpinLockLock((OSSpinLock*)&opaque_storage_);
+  CHECK(!owner_);
+  owner_ = (uptr)pthread_self();
+}
+
+void BlockingMutex::Unlock() {
+  CHECK(owner_ == (uptr)pthread_self());
+  owner_ = 0;
+  OSSpinLockUnlock((OSSpinLock*)&opaque_storage_);
+}
+
 }  // namespace __sanitizer
 
 #endif  // __APPLE__

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mutex.h Mon Jan 14 01:51:39 2013
@@ -67,6 +67,15 @@
   void operator=(const SpinMutex&);
 };
 
+class BlockingMutex {
+ public:
+  explicit BlockingMutex(LinkerInitialized);
+  void Lock();
+  void Unlock();
+ private:
+  uptr opaque_storage_[10];
+};
+
 template<typename MutexType>
 class GenericScopedLock {
  public:
@@ -106,6 +115,7 @@
 };
 
 typedef GenericScopedLock<StaticSpinMutex> SpinMutexLock;
+typedef GenericScopedLock<BlockingMutex> BlockingMutexLock;
 
 }  // namespace __sanitizer
 

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc Mon Jan 14 01:51:39 2013
@@ -20,6 +20,7 @@
 
 #include "sanitizer_common.h"
 #include "sanitizer_libc.h"
+#include "sanitizer_placement_new.h"
 
 namespace __sanitizer {
 
@@ -226,6 +227,42 @@
   return 0;
 }
 
+// ---------------------- BlockingMutex ---------------- {{{1
+enum LockState {
+  LOCK_UNINITIALIZED = 0,
+  LOCK_READY = -1,
+};
+
+BlockingMutex::BlockingMutex(LinkerInitialized li) {
+  // FIXME: see comments in BlockingMutex::Lock() for the details.
+  CHECK(li == LINKER_INITIALIZED || owner_ == LOCK_UNINITIALIZED);
+
+  CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_));
+  InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_);
+  owner_ = LOCK_READY;
+}
+
+void BlockingMutex::Lock() {
+  if (owner_ == LOCK_UNINITIALIZED) {
+    // FIXME: hm, global BlockingMutex objects are not initialized?!?
+    // This might be a side effect of the clang+cl+link Frankenbuild...
+    new(this) BlockingMutex((LinkerInitialized)(LINKER_INITIALIZED + 1));
+
+    // FIXME: If it turns out the linker doesn't invoke our
+    // constructors, we should probably manually Lock/Unlock all the global
+    // locks while we're starting in one thread to avoid double-init races.
+  }
+  EnterCriticalSection((LPCRITICAL_SECTION)opaque_storage_);
+  CHECK(owner_ == LOCK_READY);
+  owner_ = GetThreadSelf();
+}
+
+void BlockingMutex::Unlock() {
+  CHECK(owner_ == GetThreadSelf());
+  owner_ = LOCK_READY;
+  LeaveCriticalSection((LPCRITICAL_SECTION)opaque_storage_);
+}
+
 }  // namespace __sanitizer
 
 #endif  // _WIN32

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/CMakeLists.txt Mon Jan 14 01:51:39 2013
@@ -7,6 +7,7 @@
   sanitizer_flags_test.cc
   sanitizer_libc_test.cc
   sanitizer_list_test.cc
+  sanitizer_mutex_test.cc
   sanitizer_printf_test.cc
   sanitizer_stackdepot_test.cc
   sanitizer_test_main.cc

Modified: compiler-rt/trunk/lib/tsan/Makefile.old
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/Makefile.old?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/Makefile.old (original)
+++ compiler-rt/trunk/lib/tsan/Makefile.old Mon Jan 14 01:51:39 2013
@@ -1,6 +1,6 @@
 DEBUG=0
 LDFLAGS=-ldl -lpthread -pie
-CXXFLAGS = -fPIE -g -Wall -Werror -DTSAN_DEBUG=$(DEBUG)
+CXXFLAGS = -fPIE -g -Wall -Werror -DTSAN_DEBUG=$(DEBUG) -DSANITIZER_DEBUG=$(DEBUG)
 # Silence warnings that Clang produces for gtest code.
 # Use -Wno-attributes so that gcc doesn't complain about unknown warning types.
 CXXFLAGS += -Wno-attributes

Modified: compiler-rt/trunk/lib/tsan/rtl/Makefile.old
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/Makefile.old?rev=172380&r1=172379&r2=172380&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/Makefile.old (original)
+++ compiler-rt/trunk/lib/tsan/rtl/Makefile.old Mon Jan 14 01:51:39 2013
@@ -1,4 +1,4 @@
-CXXFLAGS = -fPIE -g -Wall -Werror -fno-builtin -DTSAN_DEBUG=$(DEBUG)
+CXXFLAGS = -fPIE -g -Wall -Werror -fno-builtin -DTSAN_DEBUG=$(DEBUG) -DSANITIZER_DEBUG=$(DEBUG)
 ifeq ($(DEBUG), 0)
   CXXFLAGS += -O3
 endif





More information about the llvm-commits mailing list