Coverage Report

Created: 2024-09-14 07:19

/src/skia/include/private/base/SkOnce.h
Line
Count
Source
1
/*
2
 * Copyright 2013 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
#ifndef SkOnce_DEFINED
9
#define SkOnce_DEFINED
10
11
#include "include/private/base/SkThreadAnnotations.h"
12
13
#include <atomic>
14
#include <cstdint>
15
#include <utility>
16
17
// SkOnce provides call-once guarantees for Skia, much like std::once_flag/std::call_once().
18
//
19
// There should be no particularly error-prone gotcha use cases when using SkOnce.
20
// It works correctly as a class member, a local, a global, a function-scoped static, whatever.
21
22
class SkOnce {
23
public:
24
98.8M
    constexpr SkOnce() = default;
25
26
    template <typename Fn, typename... Args>
27
112M
    void operator()(Fn&& fn, Args&&... args) {
28
112M
        auto state = fState.load(std::memory_order_acquire);
29
30
112M
        if (state == Done) {
31
112M
            return;
32
112M
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
19.2k
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
19.2k
                                                                  std::memory_order_relaxed,
37
19.2k
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
19.2k
            fn(std::forward<Args>(args)...);
40
19.2k
            return fState.store(Done, std::memory_order_release);
41
19.2k
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
10
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
3.99k
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
10
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
10
    }
FontToolUtils.cpp:void SkOnce::operator()<ToolUtils::TestFontMgr()::$_0>(ToolUtils::TestFontMgr()::$_0&&)
Line
Count
Source
27
329k
    void operator()(Fn&& fn, Args&&... args) {
28
329k
        auto state = fState.load(std::memory_order_acquire);
29
30
329k
        if (state == Done) {
31
329k
            return;
32
329k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
5
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
5
                                                                  std::memory_order_relaxed,
37
5
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
5
            fn(std::forward<Args>(args)...);
40
5
            return fState.store(Done, std::memory_order_release);
41
5
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkSemaphore.cpp:void SkOnce::operator()<SkSemaphore::osSignal(int)::$_0>(SkSemaphore::osSignal(int)::$_0&&)
Line
Count
Source
27
140
    void operator()(Fn&& fn, Args&&... args) {
28
140
        auto state = fState.load(std::memory_order_acquire);
29
30
140
        if (state == Done) {
31
136
            return;
32
136
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
4
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
0
                                                                  std::memory_order_relaxed,
37
0
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
0
            fn(std::forward<Args>(args)...);
40
0
            return fState.store(Done, std::memory_order_release);
41
0
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
4
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
1.48k
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
4
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
4
    }
SkSemaphore.cpp:void SkOnce::operator()<SkSemaphore::osWait()::$_0>(SkSemaphore::osWait()::$_0&&)
Line
Count
Source
27
140
    void operator()(Fn&& fn, Args&&... args) {
28
140
        auto state = fState.load(std::memory_order_acquire);
29
30
140
        if (state == Done) {
31
72
            return;
32
72
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
68
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
62
                                                                  std::memory_order_relaxed,
37
62
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
62
            fn(std::forward<Args>(args)...);
40
62
            return fState.store(Done, std::memory_order_release);
41
62
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
6
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
2.50k
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
6
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
6
    }
SkColorSpace.cpp:void SkOnce::operator()<SkColorSpace::computeLazyDstFields() const::$_0>(SkColorSpace::computeLazyDstFields() const::$_0&&)
Line
Count
Source
27
577k
    void operator()(Fn&& fn, Args&&... args) {
28
577k
        auto state = fState.load(std::memory_order_acquire);
29
30
577k
        if (state == Done) {
31
577k
            return;
32
577k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
183
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
183
                                                                  std::memory_order_relaxed,
37
183
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
183
            fn(std::forward<Args>(args)...);
40
183
            return fState.store(Done, std::memory_order_release);
41
183
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkData.cpp:void SkOnce::operator()<SkData::MakeEmpty()::$_0>(SkData::MakeEmpty()::$_0&&)
Line
Count
Source
27
17.1k
    void operator()(Fn&& fn, Args&&... args) {
28
17.1k
        auto state = fState.load(std::memory_order_acquire);
29
30
17.1k
        if (state == Done) {
31
17.1k
            return;
32
17.1k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
12
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
12
                                                                  std::memory_order_relaxed,
37
12
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
12
            fn(std::forward<Args>(args)...);
40
12
            return fState.store(Done, std::memory_order_release);
41
12
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkGlobalInitialization_core.cpp:void SkOnce::operator()<SkFlattenable::RegisterFlattenablesIfNeeded()::$_0>(SkFlattenable::RegisterFlattenablesIfNeeded()::$_0&&)
Line
Count
Source
27
64.6k
    void operator()(Fn&& fn, Args&&... args) {
28
64.6k
        auto state = fState.load(std::memory_order_acquire);
29
30
64.6k
        if (state == Done) {
31
64.6k
            return;
32
64.6k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
3
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
3
                                                                  std::memory_order_relaxed,
37
3
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
3
            fn(std::forward<Args>(args)...);
40
3
            return fState.store(Done, std::memory_order_release);
41
3
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkImageFilterCache.cpp:void SkOnce::operator()<SkImageFilterCache::Get(SkImageFilterCache::CreateIfNecessary)::$_0>(SkImageFilterCache::Get(SkImageFilterCache::CreateIfNecessary)::$_0&&)
Line
Count
Source
27
538k
    void operator()(Fn&& fn, Args&&... args) {
28
538k
        auto state = fState.load(std::memory_order_acquire);
29
30
538k
        if (state == Done) {
31
538k
            return;
32
538k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
8
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
8
                                                                  std::memory_order_relaxed,
37
8
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
8
            fn(std::forward<Args>(args)...);
40
8
            return fState.store(Done, std::memory_order_release);
41
8
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkPathRef.cpp:void SkOnce::operator()<SkPathRef::CreateEmpty()::$_0>(SkPathRef::CreateEmpty()::$_0&&)
Line
Count
Source
27
110M
    void operator()(Fn&& fn, Args&&... args) {
28
110M
        auto state = fState.load(std::memory_order_acquire);
29
30
110M
        if (state == Done) {
31
110M
            return;
32
110M
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
19
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
19
                                                                  std::memory_order_relaxed,
37
19
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
19
            fn(std::forward<Args>(args)...);
40
19
            return fState.store(Done, std::memory_order_release);
41
19
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkResourceCache.cpp:void SkOnce::operator()<SkMessageBus<SkResourceCache::PurgeSharedIDMessage, unsigned int, true>::Get()::$_0>(SkMessageBus<SkResourceCache::PurgeSharedIDMessage, unsigned int, true>::Get()::$_0&&)
Line
Count
Source
27
6.64k
    void operator()(Fn&& fn, Args&&... args) {
28
6.64k
        auto state = fState.load(std::memory_order_acquire);
29
30
6.64k
        if (state == Done) {
31
6.63k
            return;
32
6.63k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
7
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
7
                                                                  std::memory_order_relaxed,
37
7
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
7
            fn(std::forward<Args>(args)...);
40
7
            return fState.store(Done, std::memory_order_release);
41
7
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkRuntimeEffect.cpp:void SkOnce::operator()<SkRuntimeEffect::getRPProgram(SkSL::DebugTracePriv*) const::$_0>(SkRuntimeEffect::getRPProgram(SkSL::DebugTracePriv*) const::$_0&&)
Line
Count
Source
27
34.4k
    void operator()(Fn&& fn, Args&&... args) {
28
34.4k
        auto state = fState.load(std::memory_order_acquire);
29
30
34.4k
        if (state == Done) {
31
34.3k
            return;
32
34.3k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
69
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
69
                                                                  std::memory_order_relaxed,
37
69
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
69
            fn(std::forward<Args>(args)...);
40
69
            return fState.store(Done, std::memory_order_release);
41
69
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkTypeface.cpp:void SkOnce::operator()<SkTypeface::getBounds() const::$_0>(SkTypeface::getBounds() const::$_0&&)
Line
Count
Source
27
43.0k
    void operator()(Fn&& fn, Args&&... args) {
28
43.0k
        auto state = fState.load(std::memory_order_acquire);
29
30
43.0k
        if (state == Done) {
31
40.4k
            return;
32
40.4k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
2.57k
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
2.57k
                                                                  std::memory_order_relaxed,
37
2.57k
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
2.57k
            fn(std::forward<Args>(args)...);
40
2.57k
            return fState.store(Done, std::memory_order_release);
41
2.57k
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkPerlinNoiseShaderImpl.cpp:void SkOnce::operator()<SkPerlinNoiseShader::appendStages(SkStageRec const&, SkShaders::MatrixRec const&) const::$_0>(SkPerlinNoiseShader::appendStages(SkStageRec const&, SkShaders::MatrixRec const&) const::$_0&&)
Line
Count
Source
27
71.7k
    void operator()(Fn&& fn, Args&&... args) {
28
71.7k
        auto state = fState.load(std::memory_order_acquire);
29
30
71.7k
        if (state == Done) {
31
65.2k
            return;
32
65.2k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
6.48k
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
6.48k
                                                                  std::memory_order_relaxed,
37
6.48k
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
6.48k
            fn(std::forward<Args>(args)...);
40
6.48k
            return fState.store(Done, std::memory_order_release);
41
6.48k
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkEventTracer.cpp:void SkOnce::operator()<SkEventTracer::GetInstance()::$_0>(SkEventTracer::GetInstance()::$_0&&)
Line
Count
Source
27
236
    void operator()(Fn&& fn, Args&&... args) {
28
236
        auto state = fState.load(std::memory_order_acquire);
29
30
236
        if (state == Done) {
31
218
            return;
32
218
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
18
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
18
                                                                  std::memory_order_relaxed,
37
18
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
18
            fn(std::forward<Args>(args)...);
40
18
            return fState.store(Done, std::memory_order_release);
41
18
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkCodec.cpp:void SkOnce::operator()<SkCodecs::get_decoders_for_editing()::$_0>(SkCodecs::get_decoders_for_editing()::$_0&&)
Line
Count
Source
27
123k
    void operator()(Fn&& fn, Args&&... args) {
28
123k
        auto state = fState.load(std::memory_order_acquire);
29
30
123k
        if (state == Done) {
31
123k
            return;
32
123k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
7
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
7
                                                                  std::memory_order_relaxed,
37
7
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
7
            fn(std::forward<Args>(args)...);
40
7
            return fState.store(Done, std::memory_order_release);
41
7
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
GrResourceCache.cpp:void SkOnce::operator()<SkMessageBus<skgpu::UniqueKeyInvalidatedMessage, unsigned int, true>::Get()::$_0>(SkMessageBus<skgpu::UniqueKeyInvalidatedMessage, unsigned int, true>::Get()::$_0&&)
Line
Count
Source
27
102k
    void operator()(Fn&& fn, Args&&... args) {
28
102k
        auto state = fState.load(std::memory_order_acquire);
29
30
102k
        if (state == Done) {
31
102k
            return;
32
102k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
1
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
1
                                                                  std::memory_order_relaxed,
37
1
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
1
            fn(std::forward<Args>(args)...);
40
1
            return fState.store(Done, std::memory_order_release);
41
1
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
GrResourceCache.cpp:void SkOnce::operator()<SkMessageBus<GrResourceCache::UnrefResourceMessage, GrDirectContext::DirectContextID, false>::Get()::$_0>(SkMessageBus<GrResourceCache::UnrefResourceMessage, GrDirectContext::DirectContextID, false>::Get()::$_0&&)
Line
Count
Source
27
8.65k
    void operator()(Fn&& fn, Args&&... args) {
28
8.65k
        auto state = fState.load(std::memory_order_acquire);
29
30
8.65k
        if (state == Done) {
31
8.65k
            return;
32
8.65k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
1
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
1
                                                                  std::memory_order_relaxed,
37
1
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
1
            fn(std::forward<Args>(args)...);
40
1
            return fState.store(Done, std::memory_order_release);
41
1
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
void SkOnce::operator()<void (&)(SkAlignedSTStorage<1, skgpu::UniqueKey>*), SkAlignedSTStorage<1, skgpu::UniqueKey>*>(void (&)(SkAlignedSTStorage<1, skgpu::UniqueKey>*), SkAlignedSTStorage<1, skgpu::UniqueKey>*&&)
Line
Count
Source
27
7.88k
    void operator()(Fn&& fn, Args&&... args) {
28
7.88k
        auto state = fState.load(std::memory_order_acquire);
29
30
7.88k
        if (state == Done) {
31
7.87k
            return;
32
7.87k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
5
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
5
                                                                  std::memory_order_relaxed,
37
5
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
5
            fn(std::forward<Args>(args)...);
40
5
            return fState.store(Done, std::memory_order_release);
41
5
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
Unexecuted instantiation: Context.cpp:void SkOnce::operator()<skgpu::graphite::Context::Context(sk_sp<skgpu::graphite::SharedContext>, std::__1::unique_ptr<skgpu::graphite::QueueManager, std::__1::default_delete<skgpu::graphite::QueueManager> >, skgpu::graphite::ContextOptions const&)::$_0>(skgpu::graphite::Context::Context(sk_sp<skgpu::graphite::SharedContext>, std::__1::unique_ptr<skgpu::graphite::QueueManager, std::__1::default_delete<skgpu::graphite::QueueManager> >, skgpu::graphite::ContextOptions const&)::$_0&&)
SkFontHost_FreeType.cpp:void SkOnce::operator()<SkTypeface_FreeType::onGlyphMaskNeedsCurrentColor() const::$_0>(SkTypeface_FreeType::onGlyphMaskNeedsCurrentColor() const::$_0&&)
Line
Count
Source
27
21.3k
    void operator()(Fn&& fn, Args&&... args) {
28
21.3k
        auto state = fState.load(std::memory_order_acquire);
29
30
21.3k
        if (state == Done) {
31
18.8k
            return;
32
18.8k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
2.52k
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
2.52k
                                                                  std::memory_order_relaxed,
37
2.52k
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
2.52k
            fn(std::forward<Args>(args)...);
40
2.52k
            return fState.store(Done, std::memory_order_release);
41
2.52k
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SkFontHost_FreeType.cpp:void SkOnce::operator()<SkTypeface_FreeType::getFaceRec() const::$_0>(SkTypeface_FreeType::getFaceRec() const::$_0&&)
Line
Count
Source
27
13.1k
    void operator()(Fn&& fn, Args&&... args) {
28
13.1k
        auto state = fState.load(std::memory_order_acquire);
29
30
13.1k
        if (state == Done) {
31
10.5k
            return;
32
10.5k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
2.63k
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
2.63k
                                                                  std::memory_order_relaxed,
37
2.63k
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
2.63k
            fn(std::forward<Args>(args)...);
40
2.63k
            return fState.store(Done, std::memory_order_release);
41
2.63k
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SubRunContainer.cpp:void SkOnce::operator()<(anonymous namespace)::PathOpSubmitter::submitDraws(SkCanvas*, SkPoint, SkPaint const&) const::$_0>((anonymous namespace)::PathOpSubmitter::submitDraws(SkCanvas*, SkPoint, SkPaint const&) const::$_0&&)
Line
Count
Source
27
5.26k
    void operator()(Fn&& fn, Args&&... args) {
28
5.26k
        auto state = fState.load(std::memory_order_acquire);
29
30
5.26k
        if (state == Done) {
31
692
            return;
32
692
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
4.57k
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
4.57k
                                                                  std::memory_order_relaxed,
37
4.57k
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
4.57k
            fn(std::forward<Args>(args)...);
40
4.57k
            return fState.store(Done, std::memory_order_release);
41
4.57k
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
SubRunContainer.cpp:void SkOnce::operator()<(anonymous namespace)::DrawableOpSubmitter::submitDraws(SkCanvas*, SkPoint, SkPaint const&) const::$_0>((anonymous namespace)::DrawableOpSubmitter::submitDraws(SkCanvas*, SkPoint, SkPaint const&) const::$_0&&)
Line
Count
Source
27
5
    void operator()(Fn&& fn, Args&&... args) {
28
5
        auto state = fState.load(std::memory_order_acquire);
29
30
5
        if (state == Done) {
31
0
            return;
32
0
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
5
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
5
                                                                  std::memory_order_relaxed,
37
5
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
5
            fn(std::forward<Args>(args)...);
40
5
            return fState.store(Done, std::memory_order_release);
41
5
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
TextBlobRedrawCoordinator.cpp:void SkOnce::operator()<SkMessageBus<sktext::gpu::TextBlobRedrawCoordinator::PurgeBlobMessage, unsigned int, true>::Get()::$_0>(SkMessageBus<sktext::gpu::TextBlobRedrawCoordinator::PurgeBlobMessage, unsigned int, true>::Get()::$_0&&)
Line
Count
Source
27
9.43k
    void operator()(Fn&& fn, Args&&... args) {
28
9.43k
        auto state = fState.load(std::memory_order_acquire);
29
30
9.43k
        if (state == Done) {
31
9.43k
            return;
32
9.43k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
1
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
1
                                                                  std::memory_order_relaxed,
37
1
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
1
            fn(std::forward<Args>(args)...);
40
1
            return fState.store(Done, std::memory_order_release);
41
1
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
Unexecuted instantiation: SkCpu.cpp:void SkOnce::operator()<SkCpu::CacheRuntimeFeatures()::$_0>(SkCpu::CacheRuntimeFeatures()::$_0&&)
Unexecuted instantiation: SkDataTable.cpp:void SkOnce::operator()<SkDataTable::MakeEmpty()::$_0>(SkDataTable::MakeEmpty()::$_0&&)
GrClientMappedBufferManager.cpp:void SkOnce::operator()<SkMessageBus<skgpu::TClientMappedBufferManager<GrGpuBuffer, GrDirectContext::DirectContextID>::BufferFinishedMessage, GrDirectContext::DirectContextID, false>::Get()::$_0>(SkMessageBus<skgpu::TClientMappedBufferManager<GrGpuBuffer, GrDirectContext::DirectContextID>::BufferFinishedMessage, GrDirectContext::DirectContextID, false>::Get()::$_0&&)
Line
Count
Source
27
8.65k
    void operator()(Fn&& fn, Args&&... args) {
28
8.65k
        auto state = fState.load(std::memory_order_acquire);
29
30
8.65k
        if (state == Done) {
31
8.65k
            return;
32
8.65k
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
1
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
1
                                                                  std::memory_order_relaxed,
37
1
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
1
            fn(std::forward<Args>(args)...);
40
1
            return fState.store(Done, std::memory_order_release);
41
1
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
Unexecuted instantiation: GrGradientShader.cpp:void SkOnce::operator()<make_looping_colorizer(int, SkRGBA4f<(SkAlphaType)2> const*, SkRGBA4f<(SkAlphaType)2> const*, float const*)::$_0>(make_looping_colorizer(int, SkRGBA4f<(SkAlphaType)2> const*, SkRGBA4f<(SkAlphaType)2> const*, float const*)::$_0&&)
GrGradientShader.cpp:void SkOnce::operator()<make_unrolled_colorizer(int, SkRGBA4f<(SkAlphaType)2> const*, SkRGBA4f<(SkAlphaType)2> const*, SkRect, SkRect)::$_0>(make_unrolled_colorizer(int, SkRGBA4f<(SkAlphaType)2> const*, SkRGBA4f<(SkAlphaType)2> const*, SkRect, SkRect)::$_0&&)
Line
Count
Source
27
144
    void operator()(Fn&& fn, Args&&... args) {
28
144
        auto state = fState.load(std::memory_order_acquire);
29
30
144
        if (state == Done) {
31
138
            return;
32
138
        }
33
34
        // If it looks like no one has started calling fn(), try to claim that job.
35
6
        if (state == NotStarted && fState.compare_exchange_strong(state, Claimed,
36
6
                                                                  std::memory_order_relaxed,
37
6
                                                                  std::memory_order_relaxed)) {
38
            // Great!  We'll run fn() then notify the other threads by releasing Done into fState.
39
6
            fn(std::forward<Args>(args)...);
40
6
            return fState.store(Done, std::memory_order_release);
41
6
        }
42
43
        // Some other thread is calling fn().
44
        // We'll just spin here acquiring until it releases Done into fState.
45
0
        SK_POTENTIALLY_BLOCKING_REGION_BEGIN;
46
0
        while (fState.load(std::memory_order_acquire) != Done) { /*spin*/ }
47
0
        SK_POTENTIALLY_BLOCKING_REGION_END;
48
0
    }
Unexecuted instantiation: ClientMappedBufferManager.cpp:void SkOnce::operator()<SkMessageBus<skgpu::TClientMappedBufferManager<skgpu::graphite::Buffer, skgpu::graphite::Context::ContextID>::BufferFinishedMessage, skgpu::graphite::Context::ContextID, false>::Get()::$_0>(SkMessageBus<skgpu::TClientMappedBufferManager<skgpu::graphite::Buffer, skgpu::graphite::Context::ContextID>::BufferFinishedMessage, skgpu::graphite::Context::ContextID, false>::Get()::$_0&&)
Unexecuted instantiation: ProxyCache.cpp:void SkOnce::operator()<SkMessageBus<skgpu::UniqueKeyInvalidatedMsg_Graphite, unsigned int, true>::Get()::$_0>(SkMessageBus<skgpu::UniqueKeyInvalidatedMsg_Graphite, unsigned int, true>::Get()::$_0&&)
Unexecuted instantiation: ParagraphBuilderImpl.cpp:void SkOnce::operator()<skia::textlayout::ParagraphBuilderImpl::ensureUTF16Mapping()::$_0>(skia::textlayout::ParagraphBuilderImpl::ensureUTF16Mapping()::$_0&&)
Unexecuted instantiation: ParagraphImpl.cpp:void SkOnce::operator()<skia::textlayout::ParagraphImpl::ensureUTF16Mapping()::$_0>(skia::textlayout::ParagraphImpl::ensureUTF16Mapping()::$_0&&)
49
50
private:
51
    enum State : uint8_t { NotStarted, Claimed, Done};
52
    std::atomic<uint8_t> fState{NotStarted};
53
};
54
55
#endif  // SkOnce_DEFINED