xref: /third_party/skia/src/core/SkSpinlock.cpp (revision cb93a386)
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
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>
36    static void do_pause() { _mm_pause(); }
37#else
38    static void do_pause() { /*spin*/ }
39#endif
40
41void 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