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