Is is possible to partition an array into non-overlapping parts in a way the compiler recognizes this fact and thus knows that there is no possibility of a data race?
func doTest() async
{
let arrSize = 10_000_000_000
var byteArray: [UInt8] = Array(repeating: 0, count: arrSize)
let bytesPertask = 10_000_000
let nbrTasks = arrSize / bytesPertask
#if true // Swift 6: does not compile
await withTaskGroup
{ taskGroup in
for i in 0 ..< nbrTasks
{
taskGroup.addTask()
{
/* Swift 6 Compile Error:
Passing closure as a 'sending' parameter risks causing data races between code
in the current task and concurrent execution of the closure
**/
let startIndex = i * bytesPertask
let endIndex = min( startIndex + bytesPertask, arrSize)
for j in startIndex ..< endIndex { byteArray[j] = 1 }
}
}
await taskGroup.waitForAll()
}
#else // Swift 5 or 6: compiles with Warning
byteArray.withUnsafeMutableBufferPointer
{ pointer in
guard let bytePointer = pointer.baseAddress else {return}
DispatchQueue.concurrentPerform( iterations: nbrTasks)
{
i in
let startIndex = i * bytesPertask
let endIndex = min( startIndex + bytesPertask, arrSize)
/* Compile Warning:
Capture of 'bytePointer' with non-sendable type 'UnsafeMutablePointer<UInt8>' in
a '@Sendable' closure
**/
for j in startIndex ..< endIndex { bytePointer[j] = 1 }
}
}
#endif
}
How to get rid of the warning with concurrentPerform?
How to make TaskGroup compile in Swift Language Mode 6?