Skip to content

Instantly share code, notes, and snippets.

@cjappl
Created December 23, 2022 01:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cjappl/0e0465b738290b81667fefa2d4b4f04b to your computer and use it in GitHub Desktop.
Save cjappl/0e0465b738290b81667fefa2d4b4f04b to your computer and use it in GitHub Desktop.
Error in os_workgroup_join
#include <mach/mach_time.h>
#import <AudioToolbox/AudioToolbox.h>
#include <thread>
#include <chrono>
// This workgroup attribute isn't currently used. Set it to NULL.
os_workgroup_attr_t _Nullable attr = nullptr;
// One nanosecond in seconds.
constexpr static double kOneNanosecond = 1.0e9;
// The I/O interval time in seconds.
constexpr static double kIOIntervalTime = 0.020;
// The clock identifier that specifies interval timestamps.
os_clockid_t clockId = OS_CLOCK_MACH_ABSOLUTE_TIME;
// Create a workgroup interval.
os_workgroup_interval_t _Nullable workgroup =
AudioWorkIntervalCreate("My Work Interval", clockId, attr);
bool joinThisThreadToWorkgroup(os_workgroup_t workgroup);
void realtimeThreadFunction() {
// Join this thread to the workgroup.
if (not joinThisThreadToWorkgroup(workgroup))
{
// Early return, unable to add this thread to the workgroup
return;
}
// Get the mach time info.
struct mach_timebase_info timeBaseInfo;
mach_timebase_info(&timeBaseInfo);
// The frequency of the clock is: (timeBaseInfo.denom / timeBaseInfo.numer) * kOneNanosecond
const auto nanoSecFrequency = static_cast<double>(timeBaseInfo.denom) / static_cast<double>(timeBaseInfo.numer);
const auto frequency = nanoSecFrequency * kOneNanosecond;
// Convert the interval time in seconds to mach time length.
const auto intervalMachLength = static_cast<int64_t>(kIOIntervalTime * frequency);
while (true) {
// Get the current host time.
const auto currentTime = mach_absolute_time();
const auto deadline = currentTime + intervalMachLength;
// Call os_workgroup_interval_start each time the thread begins a work cycle
int result = os_workgroup_interval_start(workgroup, currentTime, deadline, nullptr);
if (result != 0) {
// Something went wrong.
}
// Perform some custom DSP processing.
std::this_thread::sleep_for(std::chrono::milliseconds(10));
//customAudioDSP();
// Call os_workgroup_interval_finish on completion of each a work cycle.
result = os_workgroup_interval_finish(workgroup, nullptr);
}
}
// Return true if the method joined the thread to the workgroup.
bool joinThisThreadToWorkgroup(os_workgroup_t aWorkgroup) {
// Join this thread to the workgroup.
os_workgroup_join_token_t joinToken{};
const int result = os_workgroup_join(aWorkgroup, joinToken);
if (result == 0) {
return true;
} else if (result == EALREADY) {
// The thread is already part of a workgroup that can't be
// nested in the the specified workgroup.
assert(false);
return false;
} else if (result == EINVAL) {
// The workgroup has been canceled.
assert(false);
return false;
}
else
{
assert(false);
}
}
int main()
{
realtimeThreadFunction();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment