JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_AudioWorkgroup.cpp
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26#if JUCE_AUDIOWORKGROUP_TYPES_AVAILABLE
27
28class WorkgroupToken::TokenProvider
29{
30public:
31 explicit TokenProvider (os_workgroup_t wg)
32 : workgroup (wg), attached (attach (wg, token)) {}
33
35 {
36 if (attached)
37 detach (workgroup, token);
38 }
39
40 TokenProvider (const TokenProvider&) = delete;
41 TokenProvider (TokenProvider&& other) noexcept
44 attached (std::exchange (other.attached, false)) {}
45
46 TokenProvider& operator= (const TokenProvider&) = delete;
47 TokenProvider& operator= (TokenProvider&& other) noexcept
48 {
49 TokenProvider { std::move (other) }.swap (*this);
50 return *this;
51 }
52
53 bool isAttached() const { return attached; }
54 os_workgroup_t getHandle() const { return workgroup; }
55
56private:
58 {
59 if (@available (macos 11.0, ios 14.0, *))
61 }
62
64 {
65 if (@available (macos 11.0, ios 14.0, *))
66 {
67 if (wg != nullptr && os_workgroup_join (wg, &tokenOut) == 0)
68 return true;
69 }
70
71 return false;
72 }
73
74 void swap (TokenProvider& other) noexcept
75 {
76 std::swap (other.workgroup, workgroup);
77 std::swap (other.token, token);
78 std::swap (other.attached, attached);
79 }
80
83 bool attached;
84};
85
86class AudioWorkgroup::WorkgroupProvider
87{
88public:
89 explicit WorkgroupProvider (os_workgroup_t ptr) : handle { ptr } {}
90
91 void join (WorkgroupToken& token) const
92 {
93 if (const auto* tokenProvider = token.getTokenProvider())
94 if (tokenProvider->isAttached() && tokenProvider->getHandle() == handle.get())
95 return;
96
97 // Explicit reset before constructing the new workgroup to ensure that the old workgroup
98 // is left before the new one is joined.
99 token.reset();
100
101 if (handle.get() != nullptr)
102 token = WorkgroupToken { [provider = WorkgroupToken::TokenProvider { handle.get() }] { return &provider; } };
103 }
104
105 static os_workgroup_t getWorkgroup (const AudioWorkgroup& wg)
106 {
107 if (auto* provider = wg.getWorkgroupProvider())
108 return provider->handle.get();
109
110 return nullptr;
111 }
112
113private:
115 {
116 ScopedWorkgroupRetainer (os_workgroup_t wg) : handle { wg }
117 {
118 if (handle != nullptr)
119 os_retain (handle);
120 }
121
122 ~ScopedWorkgroupRetainer()
123 {
124 if (handle != nullptr)
125 os_release (handle);
126 }
127
128 ScopedWorkgroupRetainer (const ScopedWorkgroupRetainer& other)
129 : ScopedWorkgroupRetainer { other.handle } {}
130
131 ScopedWorkgroupRetainer& operator= (const ScopedWorkgroupRetainer& other)
132 {
133 ScopedWorkgroupRetainer { other }.swap (*this);
134 return *this;
135 }
136
137 ScopedWorkgroupRetainer (ScopedWorkgroupRetainer&& other) noexcept
138 {
139 swap (other);
140 }
141
142 ScopedWorkgroupRetainer& operator= (ScopedWorkgroupRetainer&& other) noexcept
143 {
144 swap (other);
145 return *this;
146 }
147
148 void swap (ScopedWorkgroupRetainer& other) noexcept
149 {
150 std::swap (handle, other.handle);
151 }
152
153 os_workgroup_t get() const noexcept { return handle; }
154
155 private:
156 os_workgroup_t handle { nullptr };
157 };
158
160};
161
162#else
163
165
167{
168public:
169 explicit WorkgroupProvider() = default;
170
171 void join (WorkgroupToken& t) const { t.reset(); }
172
173 static void* getWorkgroup (const AudioWorkgroup&) { return nullptr; }
174};
175
176#endif
177
179 : erased ([&]() -> Erased
180 {
181 if (auto* p = other.getWorkgroupProvider())
182 return [provider = *p] { return &provider; };
183
184 return nullptr;
185 }()) {}
186
188{
189 return WorkgroupProvider::getWorkgroup (*this) == WorkgroupProvider::getWorkgroup (other);
190}
191
193{
194 #if JUCE_AUDIOWORKGROUP_TYPES_AVAILABLE
195
196 if (const auto* p = getWorkgroupProvider())
197 {
198 p->join (token);
199 return;
200 }
201
202 #endif
203
204 token.reset();
205}
206
208{
209 #if JUCE_AUDIOWORKGROUP_TYPES_AVAILABLE
210
211 if (@available (macos 11.0, ios 14.0, *))
212 {
213 if (auto wg = WorkgroupProvider::getWorkgroup (*this))
214 return (size_t) os_workgroup_max_parallel_threads (wg, nullptr);
215 }
216
217 #endif
218
219 return 0;
220}
221
222AudioWorkgroup::operator bool() const { return WorkgroupProvider::getWorkgroup (*this) != nullptr; }
223
224#if JUCE_AUDIOWORKGROUP_TYPES_AVAILABLE
225
227{
228 if (handle == nullptr)
229 return AudioWorkgroup{};
230
231 return AudioWorkgroup { [provider = AudioWorkgroup::WorkgroupProvider { handle }] { return &provider; } };
232}
233
234#endif
235
236} // namespace juce
A handle to an audio workgroup, which is a collection of realtime threads working together to produce...
size_t getMaxParallelThreadCount() const
Returns the recommended maximum number of parallel threads that should join this workgroup.
AudioWorkgroup()=default
Constructs a disengaged handle that does not represent any workgroup.
bool operator==(const AudioWorkgroup &other) const
Equality operator.
void join(WorkgroupToken &token) const
This method attempts to join the calling thread to this workgroup.
Created by AudioWorkgroup to join the calling thread to a workgroup.
void reset()
If this token was engaged by joining a workgroup, leaves that workgroup and disengages the token.
T exchange(T... args)
auto & get(ProcessorChain< Processors... > &chain) noexcept
Non-member equivalent of ProcessorChain::get which avoids awkward member template syntax.
JUCE Namespace.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
T swap(T... args)