Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ship ASExperimentalDispatchApply #1924

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Source/Private/ASDispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#import <AsyncDisplayKit/ASBaseDefines.h>

/**
* Like dispatch_apply, but you can set the thread count. 0 means 2*active CPUs.
* Like dispatch_apply, but you can set the thread count. 0 means letting dispatch_apply determine it.
*
* Note: The actual number of threads may be lower than threadCount, if libdispatch
* decides the system can't handle it. In reality this rarely happens.
Expand Down
40 changes: 12 additions & 28 deletions Source/Private/ASDispatch.mm
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,27 @@
#import <AsyncDisplayKit/ASDispatch.h>
#import <AsyncDisplayKit/ASConfigurationInternal.h>


// Prefer C atomics in this file because ObjC blocks can't capture C++ atomics well.
#import <stdatomic.h>

/**
* Like dispatch_apply, but you can set the thread count. 0 means 2*active CPUs.
*
* Note: The actual number of threads may be lower than threadCount, if libdispatch
* decides the system can't handle it. In reality this rarely happens.
*/
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments are exactly the same as the ones in the header file, so no point in keeping them.

void ASDispatchApply(size_t iterationCount, dispatch_queue_t queue, NSUInteger threadCount, NS_NOESCAPE void(^work)(size_t i)) {
if (threadCount == 0) {
if (ASActivateExperimentalFeature(ASExperimentalDispatchApply)) {
dispatch_apply(iterationCount, queue, work);
return;
dispatch_apply(iterationCount, queue, work);
} else {
dispatch_group_t group = dispatch_group_create();
__block atomic_size_t counter = ATOMIC_VAR_INIT(0);
for (NSUInteger t = 0; t < threadCount; t++) {
dispatch_group_async(group, queue, ^{
size_t i;
while ((i = atomic_fetch_add(&counter, 1)) < iterationCount) {
work(i);
}
});
}
threadCount = NSProcessInfo.processInfo.activeProcessorCount * 2;
}
dispatch_group_t group = dispatch_group_create();
__block atomic_size_t counter = ATOMIC_VAR_INIT(0);
for (NSUInteger t = 0; t < threadCount; t++) {
dispatch_group_async(group, queue, ^{
size_t i;
while ((i = atomic_fetch_add(&counter, 1)) < iterationCount) {
work(i);
}
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
};

/**
* Like dispatch_async, but you can set the thread count. 0 means 2*active CPUs.
*
* Note: The actual number of threads may be lower than threadCount, if libdispatch
* decides the system can't handle it. In reality this rarely happens.
*/
void ASDispatchAsync(size_t iterationCount, dispatch_queue_t queue, NSUInteger threadCount, NS_NOESCAPE void(^work)(size_t i)) {
if (threadCount == 0) {
threadCount = NSProcessInfo.processInfo.activeProcessorCount * 2;
Expand Down