Skip to content

Commit

Permalink
Ship ASExperimentalDispatchApply (#1924)
Browse files Browse the repository at this point in the history
Closes #1850.
  • Loading branch information
nguyenhuy committed Oct 6, 2020
1 parent efdd8ac commit ec19b92
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 29 deletions.
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.
*/
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

0 comments on commit ec19b92

Please sign in to comment.