diff options
author | djsollen@google.com <djsollen@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-01-14 21:54:44 +0000 |
---|---|---|
committer | djsollen@google.com <djsollen@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-01-14 21:54:44 +0000 |
commit | 8844f997805ee6c554f457b2777a9af0ff2f3ed3 (patch) | |
tree | d2c769e6ca80f5bcfe174681a192cc715ed9039d /include | |
parent | b5a827ab1cda81ff05e28c4d319d91ac01a137bd (diff) |
Revert "Make leak counters thread-safe and turn them on by default for Debug"
iThis CL is breaking the Android debug test bots by firing an assert.
BUG=skia:1219
Review URL: https://codereview.chromium.org/138683006
git-svn-id: http://skia.googlecode.com/svn/trunk@13076 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include')
-rw-r--r-- | include/core/SkInstCnt.h | 33 | ||||
-rw-r--r-- | include/core/SkOnce.h | 150 | ||||
-rw-r--r-- | include/core/SkPostConfig.h | 4 |
3 files changed, 15 insertions, 172 deletions
diff --git a/include/core/SkInstCnt.h b/include/core/SkInstCnt.h index 1c1770ac48..89bbfa1126 100644 --- a/include/core/SkInstCnt.h +++ b/include/core/SkInstCnt.h @@ -20,7 +20,6 @@ #include "SkTypes.h" #if SK_ENABLE_INST_COUNT -#include "SkOnce.h" #include "SkTArray.h" #include "SkThread.h" @@ -39,16 +38,17 @@ extern bool gPrintInstCount; #define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep) \ class SkInstanceCountHelper { \ public: \ + typedef int (*PFCheckInstCnt)(int level, bool cleanUp); \ SkInstanceCountHelper() { \ - SK_DECLARE_STATIC_ONCE(once); \ - SkOnce(&once, init, 0); \ + static bool gInited; \ + if (!gInited) { \ + initStep \ + GetChildren() = new SkTArray<PFCheckInstCnt>; \ + gInited = true; \ + } \ sk_atomic_inc(GetInstanceCountPtr()); \ } \ \ - static void init(int) { \ - initStep \ - } \ - \ SkInstanceCountHelper(const SkInstanceCountHelper&) { \ sk_atomic_inc(GetInstanceCountPtr()); \ } \ @@ -62,16 +62,11 @@ extern bool gPrintInstCount; return &gInstanceCount; \ } \ \ - static SkTArray<int (*)(int, bool)>*& GetChildren() { \ - static SkTArray<int (*)(int, bool)>* gChildren; \ + static SkTArray<PFCheckInstCnt>*& GetChildren() { \ + static SkTArray<PFCheckInstCnt>* gChildren; \ return gChildren; \ } \ \ - static SkBaseMutex& GetChildrenMutex() { \ - SK_DECLARE_STATIC_MUTEX(childrenMutex); \ - return childrenMutex; \ - } \ - \ } fInstanceCountHelper; \ \ static int32_t GetInstanceCount() { \ @@ -91,7 +86,7 @@ extern bool gPrintInstCount; if (NULL == SkInstanceCountHelper::GetChildren()) { \ return GetInstanceCount(); \ } \ - SkTArray<int (*)(int, bool)>* children = \ + SkTArray<int (*)(int, bool)>* children = \ SkInstanceCountHelper::GetChildren(); \ int childCount = children->count(); \ int count = GetInstanceCount(); \ @@ -110,12 +105,8 @@ extern bool gPrintInstCount; } \ \ static void AddInstChild(int (*childCheckInstCnt)(int, bool)) { \ - if (CheckInstanceCount != childCheckInstCnt) { \ - SkAutoMutexAcquire ama(SkInstanceCountHelper::GetChildrenMutex()); \ - if (NULL == SkInstanceCountHelper::GetChildren()) { \ - SkInstanceCountHelper::GetChildren() = \ - new SkTArray<int (*)(int, bool)>; \ - } \ + if (CheckInstanceCount != childCheckInstCnt && \ + NULL != SkInstanceCountHelper::GetChildren()) { \ SkInstanceCountHelper::GetChildren()->push_back(childCheckInstCnt); \ } \ } diff --git a/include/core/SkOnce.h b/include/core/SkOnce.h deleted file mode 100644 index 78fd7007b0..0000000000 --- a/include/core/SkOnce.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkOnce_DEFINED -#define SkOnce_DEFINED - -// SkOnce.h defines SK_DECLARE_STATIC_ONCE and SkOnce(), which you can use -// together to create a threadsafe way to call a function just once. This -// is particularly useful for lazy singleton initialization. E.g. -// -// static void set_up_my_singleton(Singleton** singleton) { -// *singleton = new Singleton(...); -// } -// ... -// const Singleton& GetSingleton() { -// static Singleton* singleton = NULL; -// SK_DECLARE_STATIC_ONCE(once); -// SkOnce(&once, set_up_my_singleton, &singleton); -// SkASSERT(NULL != singleton); -// return *singleton; -// } -// -// OnceTest.cpp also should serve as a few other simple examples. - -#include "SkThread.h" -#include "SkTypes.h" - -#define SK_ONCE_INIT { false, { 0, SkDEBUGCODE(0) } } -#define SK_DECLARE_STATIC_ONCE(name) static SkOnceFlag name = SK_ONCE_INIT - -struct SkOnceFlag; // If manually created, initialize with SkOnceFlag once = SK_ONCE_INIT - -template <typename Func, typename Arg> -inline void SkOnce(SkOnceFlag* once, Func f, Arg arg); - -// ---------------------- Implementation details below here. ----------------------------- - -struct SkOnceFlag { - bool done; - SkSpinlock lock; -}; - -// TODO(bungeman, mtklein): move all these *barrier* functions to SkThread when refactoring lands. - -#ifdef SK_BUILD_FOR_WIN -# include <intrin.h> -inline static void compiler_barrier() { - _ReadWriteBarrier(); -} -#else -inline static void compiler_barrier() { - asm volatile("" : : : "memory"); -} -#endif - -inline static void full_barrier_on_arm() { -#ifdef SK_CPU_ARM -# if SK_ARM_ARCH >= 7 - asm volatile("dmb" : : : "memory"); -# else - asm volatile("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory"); -# endif -#endif -} - -// On every platform, we issue a compiler barrier to prevent it from reordering -// code. That's enough for platforms like x86 where release and acquire -// barriers are no-ops. On other platforms we may need to be more careful; -// ARM, in particular, needs real code for both acquire and release. We use a -// full barrier, which acts as both, because that the finest precision ARM -// provides. - -inline static void release_barrier() { - compiler_barrier(); - full_barrier_on_arm(); -} - -inline static void acquire_barrier() { - compiler_barrier(); - full_barrier_on_arm(); -} - -// We've pulled a pretty standard double-checked locking implementation apart -// into its main fast path and a slow path that's called when we suspect the -// one-time code hasn't run yet. - -// This is the guts of the code, called when we suspect the one-time code hasn't been run yet. -// This should be rarely called, so we separate it from SkOnce and don't mark it as inline. -// (We don't mind if this is an actual function call, but odds are it'll be inlined anyway.) -template <typename Func, typename Arg> -static void sk_once_slow(SkOnceFlag* once, Func f, Arg arg) { - const SkAutoSpinlock lock(&once->lock); - if (!once->done) { - f(arg); - // Also known as a store-store/load-store barrier, this makes sure that the writes - // done before here---in particular, those done by calling f(arg)---are observable - // before the writes after the line, *done = true. - // - // In version control terms this is like saying, "check in the work up - // to and including f(arg), then check in *done=true as a subsequent change". - // - // We'll use this in the fast path to make sure f(arg)'s effects are - // observable whenever we observe *done == true. - release_barrier(); - once->done = true; - } -} - -// We nabbed this code from the dynamic_annotations library, and in their honor -// we check the same define. If you find yourself wanting more than just -// ANNOTATE_BENIGN_RACE, it might make sense to pull that in as a dependency -// rather than continue to reproduce it here. - -#if DYNAMIC_ANNOTATIONS_ENABLED -// TSAN provides this hook to supress a known-safe apparent race. -extern "C" { -void AnnotateBenignRace(const char* file, int line, const volatile void* mem, const char* desc); -} -#define ANNOTATE_BENIGN_RACE(mem, desc) AnnotateBenignRace(__FILE__, __LINE__, mem, desc) -#else -#define ANNOTATE_BENIGN_RACE(mem, desc) -#endif - -// This is our fast path, called all the time. We do really want it to be inlined. -template <typename Func, typename Arg> -inline void SkOnce(SkOnceFlag* once, Func f, Arg arg) { - ANNOTATE_BENIGN_RACE(&(once->done), "Don't worry TSAN, we're sure this is safe."); - if (!once->done) { - sk_once_slow(once, f, arg); - } - // Also known as a load-load/load-store barrier, this acquire barrier makes - // sure that anything we read from memory---in particular, memory written by - // calling f(arg)---is at least as current as the value we read from once->done. - // - // In version control terms, this is a lot like saying "sync up to the - // commit where we wrote once->done = true". - // - // The release barrier in sk_once_slow guaranteed that once->done = true - // happens after f(arg), so by syncing to once->done = true here we're - // forcing ourselves to also wait until the effects of f(arg) are readble. - acquire_barrier(); -} - -#undef ANNOTATE_BENIGN_RACE - -#endif // SkOnce_DEFINED diff --git a/include/core/SkPostConfig.h b/include/core/SkPostConfig.h index f08e6e1d15..2156519b2d 100644 --- a/include/core/SkPostConfig.h +++ b/include/core/SkPostConfig.h @@ -120,10 +120,12 @@ * SK_ENABLE_INST_COUNT controlls printing how many reference counted objects * are still held on exit. * Defaults to 1 in DEBUG and 0 in RELEASE. + * FIXME: currently always 0, since it fails if multiple threads run at once + * (see skbug.com/1219 ). */ #ifndef SK_ENABLE_INST_COUNT # ifdef SK_DEBUG -# define SK_ENABLE_INST_COUNT 1 +# define SK_ENABLE_INST_COUNT 0 # else # define SK_ENABLE_INST_COUNT 0 # endif |