26#if JUCE_AUDIOWORKGROUP_TYPES_AVAILABLE
28class WorkgroupToken::TokenProvider
31 explicit TokenProvider (os_workgroup_t wg)
32 : workgroup (wg), attached (attach (wg, token)) {}
37 detach (workgroup, token);
40 TokenProvider (
const TokenProvider&) =
delete;
41 TokenProvider (TokenProvider&& other) noexcept
42 : workgroup (
std::exchange (other.workgroup, os_workgroup_t{})),
43 token (
std::exchange (other.token, os_workgroup_join_token_s{})),
46 TokenProvider& operator= (
const TokenProvider&) =
delete;
47 TokenProvider& operator= (TokenProvider&& other)
noexcept
49 TokenProvider { std::move (other) }.swap (*
this);
53 bool isAttached()
const {
return attached; }
54 os_workgroup_t getHandle()
const {
return workgroup; }
57 static void detach (os_workgroup_t wg, os_workgroup_join_token_s token)
59 if (@available (macos 11.0, ios 14.0, *))
60 os_workgroup_leave (wg, &token);
63 static bool attach (os_workgroup_t wg, os_workgroup_join_token_s& tokenOut)
65 if (@available (macos 11.0, ios 14.0, *))
67 if (wg !=
nullptr && os_workgroup_join (wg, &tokenOut) == 0)
74 void swap (TokenProvider& other)
noexcept
81 os_workgroup_t workgroup;
82 os_workgroup_join_token_s token;
86class AudioWorkgroup::WorkgroupProvider
89 explicit WorkgroupProvider (os_workgroup_t ptr) : handle { ptr } {}
91 void join (WorkgroupToken& token)
const
93 if (
const auto* tokenProvider = token.getTokenProvider())
94 if (tokenProvider->isAttached() && tokenProvider->getHandle() == handle.get())
101 if (handle.get() !=
nullptr)
102 token = WorkgroupToken { [provider = WorkgroupToken::TokenProvider { handle.get() }] {
return &provider; } };
107 if (
auto* provider = wg.getWorkgroupProvider())
108 return provider->handle.get();
114 struct ScopedWorkgroupRetainer
116 ScopedWorkgroupRetainer (os_workgroup_t wg) : handle { wg }
118 if (handle !=
nullptr)
122 ~ScopedWorkgroupRetainer()
124 if (handle !=
nullptr)
128 ScopedWorkgroupRetainer (
const ScopedWorkgroupRetainer& other)
129 : ScopedWorkgroupRetainer { other.handle } {}
131 ScopedWorkgroupRetainer& operator= (
const ScopedWorkgroupRetainer& other)
133 ScopedWorkgroupRetainer { other }.swap (*
this);
137 ScopedWorkgroupRetainer (ScopedWorkgroupRetainer&& other)
noexcept
142 ScopedWorkgroupRetainer& operator= (ScopedWorkgroupRetainer&& other)
noexcept
148 void swap (ScopedWorkgroupRetainer& other)
noexcept
153 os_workgroup_t
get() const noexcept {
return handle; }
156 os_workgroup_t handle {
nullptr };
159 ScopedWorkgroupRetainer handle;
173 static void* getWorkgroup (
const AudioWorkgroup&) {
return nullptr; }
179 : erased ([&]() -> Erased
181 if (
auto* p = other.getWorkgroupProvider())
182 return [provider = *p] {
return &provider; };
189 return WorkgroupProvider::getWorkgroup (*
this) == WorkgroupProvider::getWorkgroup (other);
194 #if JUCE_AUDIOWORKGROUP_TYPES_AVAILABLE
196 if (
const auto* p = getWorkgroupProvider())
209 #if JUCE_AUDIOWORKGROUP_TYPES_AVAILABLE
211 if (@available (macos 11.0, ios 14.0, *))
213 if (
auto wg = WorkgroupProvider::getWorkgroup (*
this))
214 return (
size_t) os_workgroup_max_parallel_threads (wg,
nullptr);
222AudioWorkgroup::operator
bool()
const {
return WorkgroupProvider::getWorkgroup (*
this) !=
nullptr; }
224#if JUCE_AUDIOWORKGROUP_TYPES_AVAILABLE
228 if (handle ==
nullptr)
231 return AudioWorkgroup { [provider = AudioWorkgroup::WorkgroupProvider { handle }] {
return &provider; } };
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.
auto & get(ProcessorChain< Processors... > &chain) noexcept
Non-member equivalent of ProcessorChain::get which avoids awkward member template syntax.