@@ -265,6 +265,10 @@ static constexpr size_t globalQueueCacheCount =
265
265
static_cast <size_t >(JobPriority::UserInteractive) + 1;
266
266
static std::atomic<dispatch_queue_t > globalQueueCache[globalQueueCacheCount];
267
267
268
+ #ifndef __APPLE__
269
+ extern " C" void dispatch_queue_set_width (dispatch_queue_t dq, long width);
270
+ #endif
271
+
268
272
static dispatch_queue_t getGlobalQueue (JobPriority priority) {
269
273
size_t numericPriority = static_cast <size_t >(priority);
270
274
if (numericPriority >= globalQueueCacheCount)
@@ -275,6 +279,25 @@ static dispatch_queue_t getGlobalQueue(JobPriority priority) {
275
279
if (SWIFT_LIKELY (queue))
276
280
return queue;
277
281
282
+ #ifndef __APPLE__
283
+ const int DISPATCH_QUEUE_WIDTH_MAX_LOGICAL_CPUS = -3 ;
284
+
285
+ // Create a new cooperative concurrent queue and swap it in.
286
+ dispatch_queue_attr_t newQueueAttr = dispatch_queue_attr_make_with_qos_class (
287
+ DISPATCH_QUEUE_CONCURRENT, (dispatch_qos_class_t )priority, 0 );
288
+ dispatch_queue_t newQueue = dispatch_queue_create (
289
+ " Swift global concurrent queue" , newQueueAttr);
290
+ dispatch_queue_set_width (newQueue, DISPATCH_QUEUE_WIDTH_MAX_LOGICAL_CPUS);
291
+
292
+ if (!ptr->compare_exchange_strong (queue, newQueue,
293
+ /* success*/ std::memory_order_release,
294
+ /* failure*/ std::memory_order_acquire)) {
295
+ dispatch_release (newQueue);
296
+ return queue;
297
+ }
298
+
299
+ return newQueue;
300
+ #else
278
301
// If we don't have a queue cached for this priority, cache it now. This may
279
302
// race with other threads doing this at the same time for this priority, but
280
303
// that's OK, they'll all end up writing the same value.
@@ -284,6 +307,7 @@ static dispatch_queue_t getGlobalQueue(JobPriority priority) {
284
307
// Unconditionally store it back in the cache. If we raced with another
285
308
// thread, we'll just overwrite the entry with the same value.
286
309
ptr->store (queue, std::memory_order_relaxed);
310
+ #endif
287
311
288
312
return queue;
289
313
}
0 commit comments