-
-
Save cjappl/0e0465b738290b81667fefa2d4b4f04b to your computer and use it in GitHub Desktop.
Error in os_workgroup_join
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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