1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2015 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkSpinlock.h" 9*c8dee2aaSAndroid Build Coastguard Worker 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkFeatures.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkThreadAnnotations.h" 12*c8dee2aaSAndroid Build Coastguard Worker 13*c8dee2aaSAndroid Build Coastguard Worker #if 0 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkMutex.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include <execinfo.h> 16*c8dee2aaSAndroid Build Coastguard Worker #include <stdio.h> 17*c8dee2aaSAndroid Build Coastguard Worker 18*c8dee2aaSAndroid Build Coastguard Worker static void debug_trace() { 19*c8dee2aaSAndroid Build Coastguard Worker void* stack[64]; 20*c8dee2aaSAndroid Build Coastguard Worker int len = backtrace(stack, std::size(stack)); 21*c8dee2aaSAndroid Build Coastguard Worker 22*c8dee2aaSAndroid Build Coastguard Worker // As you might imagine, we can't use an SkSpinlock here... 23*c8dee2aaSAndroid Build Coastguard Worker static SkMutex lock; 24*c8dee2aaSAndroid Build Coastguard Worker { 25*c8dee2aaSAndroid Build Coastguard Worker SkAutoMutexExclusive locked(lock); 26*c8dee2aaSAndroid Build Coastguard Worker fprintf(stderr, "\n"); 27*c8dee2aaSAndroid Build Coastguard Worker backtrace_symbols_fd(stack, len, 2/*stderr*/); 28*c8dee2aaSAndroid Build Coastguard Worker fprintf(stderr, "\n"); 29*c8dee2aaSAndroid Build Coastguard Worker } 30*c8dee2aaSAndroid Build Coastguard Worker } 31*c8dee2aaSAndroid Build Coastguard Worker #else debug_trace()32*c8dee2aaSAndroid Build Coastguard Worker static void debug_trace() {} 33*c8dee2aaSAndroid Build Coastguard Worker #endif 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker // Renamed from "pause" to avoid conflict with function defined in unistd.h 36*c8dee2aaSAndroid Build Coastguard Worker #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 37*c8dee2aaSAndroid Build Coastguard Worker #include <emmintrin.h> do_pause()38*c8dee2aaSAndroid Build Coastguard Worker static void do_pause() { _mm_pause(); } 39*c8dee2aaSAndroid Build Coastguard Worker #else do_pause()40*c8dee2aaSAndroid Build Coastguard Worker static void do_pause() { /*spin*/ } 41*c8dee2aaSAndroid Build Coastguard Worker #endif 42*c8dee2aaSAndroid Build Coastguard Worker contendedAcquire()43*c8dee2aaSAndroid Build Coastguard Workervoid SkSpinlock::contendedAcquire() { 44*c8dee2aaSAndroid Build Coastguard Worker debug_trace(); 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard Worker // To act as a mutex, we need an acquire barrier when we acquire the lock. 47*c8dee2aaSAndroid Build Coastguard Worker SK_POTENTIALLY_BLOCKING_REGION_BEGIN; 48*c8dee2aaSAndroid Build Coastguard Worker while (fLocked.exchange(true, std::memory_order_acquire)) { 49*c8dee2aaSAndroid Build Coastguard Worker do_pause(); 50*c8dee2aaSAndroid Build Coastguard Worker } 51*c8dee2aaSAndroid Build Coastguard Worker SK_POTENTIALLY_BLOCKING_REGION_END; 52*c8dee2aaSAndroid Build Coastguard Worker } 53