Re: [swift-users] Swift and Threads

2016-09-13 Thread Gerriet M. Denkmann via swift-users

> On 13 Sep 2016, at 14:49, Quinn The Eskimo! via swift-users 
>  wrote:
> 
> 
> On 13 Sep 2016, at 05:03, Gerriet M. Denkmann via swift-users 
>  wrote:
> 
>> Or is the code fundamentally wrong …?
> 
> This one.
> 
> You’re accessing a mutable value (`bitfield`) from multiple threads.  Swift 
> does not support that, even in situations like this where you’re sure that 
> the items are preallocated and that the threads are accessing non-overlapping 
> values.
> 
> As to how you fix this, it kinda depends on your final use for the array.  If 
> you’re OK with the results being split into per-thread chunks, you can have 
> each thread work on its own chunk and then pass the results back to the 
> ‘main’ thread when it’s done.  OTOH, if you need your results in one big 
> array, things get tricky.

Stephen J. Butler just suggested a solution (on CocoaDev) which works and is 
fast and uses no additional memory.

Here it is:

let nbrOfThreads = 8
let step = 2
let itemsPerThread = number * step
let bitLimit = nbrOfThreads * itemsPerThread
var bitfield = [Bool](count: bitLimit, repeatedValue: false)

let queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 );

bitfield.withUnsafeMutableBufferPointer { (inout bitfieldBuffer : 
UnsafeMutableBufferPointer) -> () in
dispatch_apply( Int(nbrOfThreads), queue ) { ( idx: size_t) -> Void in
let startIndex = itemsPerThread * Int(idx)
let endIndex = min( startIndex + itemsPerThread, bitLimit )
if talk { print("Thread[\(idx)] does \(startIndex) ..< \(endIndex)") }

var currIndex = startIndex
while( currIndex < endIndex )
{
bitfieldBuffer[currIndex] = true
currIndex += step
}
}
}

I hope that this is really thread-safe (testing it, I have no problems so far).

Kind regards,

Gerriet.

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Swift and Threads

2016-09-13 Thread Quinn "The Eskimo!" via swift-users

On 13 Sep 2016, at 05:03, Gerriet M. Denkmann via swift-users 
 wrote:

> Or is the code fundamentally wrong …?

This one.

You’re accessing a mutable value (`bitfield`) from multiple threads.  Swift 
does not support that, even in situations like this where you’re sure that the 
items are preallocated and that the threads are accessing non-overlapping 
values.

As to how you fix this, it kinda depends on your final use for the array.  If 
you’re OK with the results being split into per-thread chunks, you can have 
each thread work on its own chunk and then pass the results back to the ‘main’ 
thread when it’s done.  OTOH, if you need your results in one big array, things 
get tricky.

Share and Enjoy
--
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware


___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] Swift and Threads

2016-09-12 Thread Gerriet M. Denkmann via swift-users
This function works flawlessly in Release build:

func markAndTell( talk: Bool, number: Int)
{
let nbrOfThreads = 8
let step = 2
let itemsPerThread = number * step
let bitLimit = nbrOfThreads * itemsPerThread
var bitfield = [Bool](count: bitLimit, repeatedValue: false)

let queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 
);
dispatch_apply( Int(nbrOfThreads), queue,
{ ( idx: size_t) -> Void in

let startIndex = itemsPerThread * Int(idx)
let endIndex = min( startIndex + itemsPerThread, 
bitLimit )
if talk { print("Thread[\(idx)] does \(startIndex) ..< 
\(endIndex)")}

var currIndex = startIndex
while( currIndex < endIndex )
{
bitfield[currIndex] = true  //  this 
might crash
currIndex += step
}
}
)
}

But it does not work in Debug builds.

“does not work” means: for !talk and any number > 0 or: talk and number ≥ 110:

malloc: *** error for object 0x101007808: incorrect checksum for freed object 
- object was probably modified after being freed. *** set a breakpoint in 
malloc_error_break to debug

Or:
fatal error: UnsafeMutablePointer.initializeFrom non-following overlapping range

Or:
just plain wrong data in bitfield.

So: is the code ok and the compiler broken in Debug mode?
Or is the code fundamentally wrong and that it works in Release is just a fluke?
If so: how could it be fixed?

Btw.: no problems with bitfield malloced into some UnsafeMutablePointer.

Gerriet.
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users