[ASan] Cache the OSX version to avoid calling sysctl() on every GetMacosVersion() call.


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@186389 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc
index f784536..9200837 100644
--- a/lib/asan/asan_mac.cc
+++ b/lib/asan/asan_mac.cc
@@ -21,6 +21,7 @@
 #include "asan_mapping.h"
 #include "asan_stack.h"
 #include "asan_thread.h"
+#include "sanitizer_common/sanitizer_atomic.h"
 #include "sanitizer_common/sanitizer_libc.h"
 
 #include <crt_externs.h>  // for _NSGetArgv
@@ -52,7 +53,9 @@
 # endif  // SANITIZER_WORDSIZE
 }
 
-int GetMacosVersion() {
+MacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED;
+
+MacosVersion GetMacosVersionInternal() {
   int mib[2] = { CTL_KERN, KERN_OSRELEASE };
   char version[100];
   uptr len = 0, maxlen = sizeof(version) / sizeof(version[0]);
@@ -76,6 +79,18 @@
   }
 }
 
+MacosVersion GetMacosVersion() {
+  atomic_uint32_t *cache =
+      reinterpret_cast<atomic_uint32_t*>(&cached_macos_version);
+  MacosVersion result =
+      static_cast<MacosVersion>(atomic_load(cache, memory_order_acquire));
+  if (result == MACOS_VERSION_UNINITIALIZED) {
+    result = GetMacosVersionInternal();
+    atomic_store(cache, result, memory_order_release);
+  }
+  return result;
+}
+
 bool PlatformHasDifferentMemcpyAndMemmove() {
   // On OS X 10.7 memcpy() and memmove() are both resolved
   // into memmove$VARIANT$sse42.
diff --git a/lib/asan/asan_mac.h b/lib/asan/asan_mac.h
index c0063e0..827b8b0 100644
--- a/lib/asan/asan_mac.h
+++ b/lib/asan/asan_mac.h
@@ -36,8 +36,9 @@
 #endif
 } CFRuntimeBase;
 
-enum {
-  MACOS_VERSION_UNKNOWN = 0,
+enum MacosVersion {
+  MACOS_VERSION_UNINITIALIZED = 0,
+  MACOS_VERSION_UNKNOWN,
   MACOS_VERSION_LEOPARD,
   MACOS_VERSION_SNOW_LEOPARD,
   MACOS_VERSION_LION,
@@ -50,7 +51,7 @@
 
 namespace __asan {
 
-int GetMacosVersion();
+MacosVersion GetMacosVersion();
 void MaybeReplaceCFAllocator();
 
 }  // namespace __asan