Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
third_party
skia
include
private
base
SkSemaphore.h
Go to the documentation of this file.
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
#ifndef SkSemaphore_DEFINED
9
#define SkSemaphore_DEFINED
10
11
#include "
include/private/base/SkAPI.h
"
12
#include "
include/private/base/SkOnce.h
"
13
#include "
include/private/base/SkThreadAnnotations.h
"
14
15
#include <algorithm>
16
#include <atomic>
17
18
class
SkSemaphore
{
19
public
:
20
constexpr
SkSemaphore
(
int
count
= 0) : fCount(
count
), fOSSemaphore(nullptr) {}
21
22
// Cleanup the underlying OS semaphore.
23
SK_SPI
~SkSemaphore
();
24
25
// Increment the counter n times.
26
// Generally it's better to call signal(n) instead of signal() n times.
27
void
signal(
int
n = 1);
28
29
// Decrement the counter by 1,
30
// then if the counter is < 0, sleep this thread until the counter is >= 0.
31
void
wait
();
32
33
// If the counter is positive, decrement it by 1 and return true, otherwise return false.
34
SK_SPI
bool
try_wait
();
35
36
private
:
37
// This implementation follows the general strategy of
38
// 'A Lightweight Semaphore with Partial Spinning'
39
// found here
40
// http://preshing.com/20150316/semaphores-are-surprisingly-versatile/
41
// That article (and entire blog) are very much worth reading.
42
//
43
// We wrap an OS-provided semaphore with a user-space atomic counter that
44
// lets us avoid interacting with the OS semaphore unless strictly required:
45
// moving the count from >=0 to <0 or vice-versa, i.e. sleeping or waking threads.
46
struct
OSSemaphore;
47
48
SK_SPI
void
osSignal(
int
n);
49
SK_SPI
void
osWait();
50
51
std::atomic<int> fCount;
52
SkOnce
fOSSemaphoreOnce;
53
OSSemaphore* fOSSemaphore;
54
};
55
56
inline
void
SkSemaphore::signal
(
int
n) {
57
int
prev
= fCount.fetch_add(n, std::memory_order_release);
58
59
// We only want to call the OS semaphore when our logical count crosses
60
// from <0 to >=0 (when we need to wake sleeping threads).
61
//
62
// This is easiest to think about with specific examples of prev and n.
63
// If n == 5 and prev == -3, there are 3 threads sleeping and we signal
64
// std::min(-(-3), 5) == 3 times on the OS semaphore, leaving the count at 2.
65
//
66
// If prev >= 0, no threads are waiting, std::min(-prev, n) is always <= 0,
67
// so we don't call the OS semaphore, leaving the count at (prev + n).
68
int
toSignal = std::min(-
prev
, n);
69
if
(toSignal > 0) {
70
this->osSignal(toSignal);
71
}
72
}
73
74
inline
void
SkSemaphore::wait
() {
75
// Since this fetches the value before the subtract, zero and below means that there are no
76
// resources left, so the thread needs to wait.
77
if
(fCount.fetch_sub(1, std::memory_order_acquire) <= 0) {
78
SK_POTENTIALLY_BLOCKING_REGION_BEGIN
;
79
this->osWait();
80
SK_POTENTIALLY_BLOCKING_REGION_END
;
81
}
82
}
83
84
#endif
//SkSemaphore_DEFINED
count
int count
Definition
FontMgrTest.cpp:50
prev
static float prev(float f)
Definition
PathOpsAngleTest.cpp:40
SkAPI.h
SK_SPI
#define SK_SPI
Definition
SkAPI.h:41
SkOnce.h
SkThreadAnnotations.h
SK_POTENTIALLY_BLOCKING_REGION_END
#define SK_POTENTIALLY_BLOCKING_REGION_END
Definition
SkThreadAnnotations.h:101
SK_POTENTIALLY_BLOCKING_REGION_BEGIN
#define SK_POTENTIALLY_BLOCKING_REGION_BEGIN
Definition
SkThreadAnnotations.h:100
SkOnce
Definition
SkOnce.h:22
SkSemaphore
Definition
SkSemaphore.h:18
SkSemaphore::~SkSemaphore
SK_SPI ~SkSemaphore()
Definition
SkSemaphore.cpp:63
SkSemaphore::signal
void signal(int n=1)
Definition
SkSemaphore.h:56
SkSemaphore::wait
void wait()
Definition
SkSemaphore.h:74
SkSemaphore::SkSemaphore
constexpr SkSemaphore(int count=0)
Definition
SkSemaphore.h:20
SkSemaphore::try_wait
SK_SPI bool try_wait()
Definition
SkSemaphore.cpp:77
Generated on Fri Apr 26 2024 06:16:13 for Flutter Engine by
1.9.8