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