Re: Swift and Threads

2016-09-13 Thread Gerriet M. Denkmann

> On 13 Sep 2016, at 15:20, Quincey Morris 
>  wrote:
> 
>> On Sep 13, 2016, at 00:57 , Gerriet M. Denkmann  wrote:
>> 
>> I was struggling to find a solution which is thread safe.
> 
> Your problem didn’t really need thread safety, though. There appeared to be 
> no data dependencies between the bitfield elements — each was written 
> independently and never read — so all you needed was atomicity to make sure 
> the underlying code didn’t trip over itself. Further, as you discovered, your 
> task was easily partitionable into *independent* data sections, so you didn’t 
> really need atomicity either, if your data storage was structured carefully.
> 
> But I’m assuming none of this is true for your real goal, unless your real 
> goal is solely to initialize a big array using multiple CPUs.

My real problem is a pet project: a sieve of Eratosthenes (Ἐρατοσθένης) to find 
all primes up to a certain number.
I use this to learn Swift, and to compare the performance of Swift to 
Objective-C.

So I have this huge bitfield (which different subclasses implement differently) 
and I have to mark certain items in a certain range as non-prime (= true or 1).

As the range to be marked changes as the algorithm proceeds, it makes no sense 
to have 8 sub-bitfields and give one each to a marking thread; at a later stage 
only the last sub-bitfield will need markings, and the algorithm would be again 
single threaded.

I indeed need no atomicity: all threads have their own data section, which do 
not overlap.

Everything works fine (in Swift as in Objective-C) with dispatch_apply, as long 
as the bitfield is malloced.
In case of bitfield: [Bool] the solution suggested by Stephen J. Butler will 
probably also work (I am just implementing it).


Kind regards,

Gerriet.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Swift and Threads

2016-09-13 Thread Gerriet M. Denkmann

> On 13 Sep 2016, at 14:14, Stephen J. Butler  wrote:
> 
> This site suggests a version using withUnsafeMutableBufferPointer:
> 
> http://blog.human-friendly.com/swift-arrays-are-not-threadsafe
> 
> 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
> }
> }
> }

This is excellent: slightly faster than my original code, uses no additional 
memory and does not crash.
Exactly what I was looking for.

Thank your very, very much indeed!

Kind regards,

Gerriet.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Swift and Threads

2016-09-13 Thread Quincey Morris
On Sep 12, 2016, at 23:52 , Gerriet M. Denkmann  wrote:
> 
> I tried a variation of my function. This does not crash (not even in Debug 
> builds), but takes twice the memory and is about four times slower:

I no longer understand what we’re doing here. Based on the code you’ve posted, 
it looks like you’re approaching a multithreaded optimization problem by 
microbenchmarking fake code, using implementation-dependent data structures 
whose characteristics are not governed by an API contract, and ignoring thread 
safety. How can that possibly lead to a design for your real code? What kind of 
advice (if any) are you seeking?

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Swift and Threads

2016-09-13 Thread Alastair Houghton
On 13 Sep 2016, at 05:29, Jens Alfke  wrote:
> 
> The Bool type is one byte in size.
> 
> C++ has a specialization for std::vector that makes it a true bit 
> array, but I’m not sure if Swift’s generic system is powerful enough to be 
> able to entirely switch out the implementation based on the parameter type.

Before anyone thinks it’s a good idea to copy that idea straight into Swift’s 
standard library, std::vector doesn’t behave quite the same as the other 
std::vector<> implementations, and the specialisation is widely regarded as a 
mistake.  It’d be a *really* good idea to avoid making similar mistakes in 
Swift.

(Also, there’s a strong argument for having a separate bit vector type, with 
set-like operations, support for sparse bit vectors and the like.)

Kind regards,

Alastair.

--
http://alastairs-place.net


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Swift and Threads

2016-09-13 Thread Stephen J. Butler
This site suggests a version using withUnsafeMutableBufferPointer:

http://blog.human-friendly.com/swift-arrays-are-not-threadsafe

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
}
}
}


On Tue, Sep 13, 2016 at 1:52 AM, Gerriet M. Denkmann 
wrote:

>
> > On 12 Sep 2016, at 22:49, Jens Alfke  wrote:
> >
> >
> >> On Sep 12, 2016, at 6:42 AM, Gerriet M. Denkmann 
> wrote:
> >>
> >> 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?
>
> I tried a variation of my function. This does not crash (not even in Debug
> builds), but takes twice the memory and is about four times slower:
>
> func markAndTell_2( talk: Bool, number: Int) -> [Bool]
> {
> [...]
> let bitLimit = nbrOfThreads * itemsPerThread
> var bitfield = [Bool](count: bitLimit, repeatedValue: false)
>
> var outputSlice0: ArraySlice = []
> [...]
> var outputSlice7: ArraySlice = []
>
> 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 )
>
> var tempSlice: ArraySlice = bitfield[
> startIndex ..< endIndex ]
>
> var currIndex = startIndex
> while( currIndex < endIndex )
> {
> tempSlice[currIndex] = true
> currIndex += step
> }
>
> switch(idx)
> {
> case 0: outputSlice0 = tempSlice
> [...]
> case 7: outputSlice7 = tempSlice
> default: print("Thread[\(idx)] does not
> know where to put its slice")
> }
> }
> )
>
> bitfield = []
> bitfield += outputSlice0
> [...]
> bitfield += outputSlice7
>
> return bitfield
> }
>
> Gerriet.
>
>
> ___
>
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/
> stephen.butler%40gmail.com
>
> This email sent to stephen.but...@gmail.com
>
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Swift and Threads

2016-09-13 Thread Gerriet M. Denkmann

> On 12 Sep 2016, at 22:49, Jens Alfke  wrote:
> 
> 
>> On Sep 12, 2016, at 6:42 AM, Gerriet M. Denkmann  
>> wrote:
>> 
>> 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?

I tried a variation of my function. This does not crash (not even in Debug 
builds), but takes twice the memory and is about four times slower:

func markAndTell_2( talk: Bool, number: Int) -> [Bool]
{
[...]
let bitLimit = nbrOfThreads * itemsPerThread
var bitfield = [Bool](count: bitLimit, repeatedValue: false)

var outputSlice0: ArraySlice = []
[...]
var outputSlice7: ArraySlice = []

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 )

var tempSlice: ArraySlice = bitfield[ startIndex 
..< endIndex ]

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

switch(idx)
{
case 0: outputSlice0 = tempSlice
[...]
case 7: outputSlice7 = tempSlice
default: print("Thread[\(idx)] does not know 
where to put its slice")
}   
}
)

bitfield = []
bitfield += outputSlice0
[...]
bitfield += outputSlice7

return bitfield
}

Gerriet.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Swift and Threads

2016-09-12 Thread Jens Alfke

> On Sep 12, 2016, at 9:21 PM, Gerriet M. Denkmann  wrote:
> 
> READ of size 1776 at 0x61ce68a0 thread T0
>#0 0x1000516f3 in wrap_memcpy (libclang_rt.asan_osx_dynamic.dylib+0x406f3)
>#1 0x100f85a88 in __swift_memcpy_array1_1 (libswiftCore.dylib+0x1dea88)
>#2 0x100dd9a3e in _TZFSa11_copyBufferfRGVs12_ArrayBufferx_T_ 
> (libswiftCore.dylib+0x32a3e)
>#3 0x100dd7495 in _TFSaap9subscriptFSix (libswiftCore.dylib+0x30495)

One of the writes is copying the array buffer, while presumably a bunch of 
other threads are trying to write to that buffer. Bad news.

Swift arrays are not thread-safe.

> When I use a [Bool] of size 1,000,000,000, the memory footprint goes up by 
> more than 1 GB. Looks like Swift uses only one bit per byte.

The Bool type is one byte in size.

C++ has a specialization for std::vector that makes it a true bit array, 
but I’m not sure if Swift’s generic system is powerful enough to be able to 
entirely switch out the implementation based on the parameter type.

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Swift and Threads

2016-09-12 Thread Gerriet M. Denkmann

> On 12 Sep 2016, at 22:49, Jens Alfke  wrote:
> 
> 
>> On Sep 12, 2016, at 6:42 AM, Gerriet M. Denkmann  
>> wrote:
>> 
>> 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?
> 
> 99% of the time it’s the latter. Which means you should try to debug the 
> code. Did you set the breakpoint on malloc_error?
Yes, see below.

> What line of code is triggering it?
bitfield[currIndex] = true  //  this might crash

> Did you examine the values of variables?
Yes. In all cases the value of index was well inside limits.


> Did you run with the Address Sanitizer?

Just did:
bitfield[0 ..< 1776] with 8 threads
=
==55216==ERROR: AddressSanitizer: heap-use-after-free on address 0x61ce68a0 
at pc 0x0001000516f4 bp 0x7fff5fbfe2f0 sp 0x7fff5fbfdab0
READ of size 1776 at 0x61ce68a0 thread T0
#0 0x1000516f3 in wrap_memcpy (libclang_rt.asan_osx_dynamic.dylib+0x406f3)
#1 0x100f85a88 in __swift_memcpy_array1_1 (libswiftCore.dylib+0x1dea88)
#2 0x100dd9a3e in _TZFSa11_copyBufferfRGVs12_ArrayBufferx_T_ 
(libswiftCore.dylib+0x32a3e)
#3 0x100dd7495 in _TFSaap9subscriptFSix (libswiftCore.dylib+0x30495)
#4 0x13afb in Base.(markAndTell(Bool, number : Int) -> ()).(closure #1) 
Base + BaseA.swift:40
#5 0x13b7e in thunk Base + BaseA.swift
#6 0x101332dd9 in _dispatch_client_callout2 (libdispatch.dylib+0x16dd9)
#7 0x101332c81 in _dispatch_apply_invoke (libdispatch.dylib+0x16c81)
#8 0x101332b01 in dispatch_apply_f (libdispatch.dylib+0x16b01)
#9 0x12bad in Base.markAndTell(Bool, number : Int) -> () Base + 
BaseA.swift:44
#10 0x11b5f in AppDelegate.(doQuiet in 
_FFF4105428658238176D3EC47C78F853)(NSButton) -> () AppDelegate.swift:46
#11 0x11bc9 in @objc AppDelegate.(doQuiet in 
_FFF4105428658238176D3EC47C78F853)(NSButton) -> () AppDelegate.swift
#12 0x7fff9d10e079 in _os_activity_initiate (libsystem_trace.dylib+0x2079)
#13 0x7fff8f365dbc in -[NSApplication sendAction:to:from:] (AppKit+0x2b1dbc)
#14 0x7fff8f377f11 in -[NSControl sendAction:to:] (AppKit+0x2c3f11)
#15 0x7fff8f377e3b in __26-[NSCell _sendActionFrom:]_block_invoke 
(AppKit+0x2c3e3b)
#16 0x7fff9d10e079 in _os_activity_initiate (libsystem_trace.dylib+0x2079)
#17 0x7fff8f377d98 in -[NSCell _sendActionFrom:] (AppKit+0x2c3d98)
#18 0x7fff9d10e079 in _os_activity_initiate (libsystem_trace.dylib+0x2079)
#19 0x7fff8f3763bd in -[NSCell trackMouse:inRect:ofView:untilMouseUp:] 
(AppKit+0x2c23bd)
#20 0x7fff8f3bef03 in -[NSButtonCell 
trackMouse:inRect:ofView:untilMouseUp:] (AppKit+0x30af03)
#21 0x7fff8f374ae7 in -[NSControl mouseDown:] (AppKit+0x2c0ae7)
#22 0x7fff8f8c93c8 in -[NSWindow _handleMouseDownEvent:isDelayedEvent:] 
(AppKit+0x8153c8)
#23 0x7fff8f8ca3ac in -[NSWindow _reallySendEvent:isDelayedEvent:] 
(AppKit+0x8163ac)
#24 0x7fff8f309538 in -[NSWindow sendEvent:] (AppKit+0x255538)
#25 0x7fff8f289a37 in -[NSApplication sendEvent:] (AppKit+0x1d5a37)
#26 0x7fff8f0f0df1 in -[NSApplication run] (AppKit+0x3cdf1)
#27 0x7fff8f0ba367 in NSApplicationMain (AppKit+0x6367)
#28 0x11e63 in main AppDelegate.swift:15
#29 0x7fff8c6f75ac in start (libdyld.dylib+0x35ac)
#30 0x2  (IsKindOfTest)+0x2)

0x61ce68a0 is located 32 bytes inside of 1808-byte region 
[0x61ce6880,0x61ce6f90)
freed by thread T0 here:
#0 0x100059b89 in wrap_free (libclang_rt.asan_osx_dynamic.dylib+0x48b89)
#1 0x100dd9a05 in _TZFSa11_copyBufferfRGVs12_ArrayBufferx_T_ 
(libswiftCore.dylib+0x32a05)
#2 0x100dd7495 in _TFSaap9subscriptFSix (libswiftCore.dylib+0x30495)
#3 0x13afb in Base.(markAndTell(Bool, number : Int) -> ()).(closure #1) 
Base + BaseA.swift:40
#4 0x13b7e in thunk Base + BaseA.swift
#5 0x101332dd9 in _dispatch_client_callout2 (libdispatch.dylib+0x16dd9)
#6 0x101332c81 in _dispatch_apply_invoke (libdispatch.dylib+0x16c81)
#7 0x101332b01 in dispatch_apply_f (libdispatch.dylib+0x16b01)
#8 0x12bad in Base.markAndTell(Bool, number : Int) -> () Base + 
BaseA.swift:44
#9 0x11b5f in AppDelegate.(doQuiet in 
_FFF4105428658238176D3EC47C78F853)(NSButton) -> () AppDelegate.swift:46
#10 0x11bc9 in @objc AppDelegate.(doQuiet in 
_FFF4105428658238176D3EC47C78F853)(NSButton) -> () AppDelegate.swift
#11 0x7fff9d10e079 in _os_activity_initiate (libsystem_trace.dylib+0x2079)
#12 0x7fff8f365dbc in -[NSApplication sendAction:to:from:] (AppKit+0x2b1dbc)
#13 0x7fff8f377f11 in -[NSControl sendAction:to:] (AppKit+0x2c3f11)
#14 0x7fff8f377e3b in __26-[NSCell _sendActionFrom:]_block_invoke 
(AppKit+0x2c3e3b)
#15 0x7fff9d10e079 in _os_activity_initiate (libsystem_trace.dylib+0x2079)
#16 0x7fff8f377d98 in -[NSCell _sendActionFrom:] (AppKit+0x2c3d98)
#17 0x7fff9d10e079 in 

Re: Swift and Threads

2016-09-12 Thread Jens Alfke

> On Sep 12, 2016, at 11:11 AM, Quincey Morris 
>  wrote:
> 
> My understanding is that pure Swift arrays (that is, *not* bridged NSArrays) 
> are stored as efficiently as C arrays.

It’s not the efficiency of storage I was concerned about; in this case it’s the 
COW semantics, which can involve the data backing store being moved at the whim 
of an opaque internal implementation.

If you want just a plain raw array without that sort of behavior, I’m not sure 
how you would do it in Swift without resorting to UnsafePointer shenanigans.

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Swift and Threads

2016-09-12 Thread Quincey Morris
On Sep 12, 2016, at 10:16 , Jens Alfke  wrote:
> 
> The question in my mind is whether the array struct ever gets copied in this 
> code — it’s not explicitly passed as a parameter, just closed over. I don’t 
> think I’ve read any docs that describe explicitly what the behavior is, maybe 
> because it only becomes significant when you introduce threads?

The array is going to get copied at least once, because it’s a local variable 
captured by a block. That means it needs to be copied to the heap.

> This situation also begs the question of what kind of lower-level data 
> structure one can use in Swift when Array is too high-level. In Obj-C one can 
> drop down to C arrays, for example.

My understanding is that pure Swift arrays (that is, *not* bridged NSArrays) 
are stored as efficiently as C arrays.

However, in this particular example, the array, a mutable structure, is 
modified unsafely from multiple threads. That may or may not be the cause of 
the crash, but it’s certainly a bug that should be fixed first.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Swift and Threads

2016-09-12 Thread Jens Alfke

> On Sep 12, 2016, at 9:34 AM, Jean-Daniel  wrote:
> 
> Array are value based in Swift and so use COW optimization, which mean that 
> even if you don’t resize them, you may hit a race condition issue.

Yes, you’re right. The question in my mind is whether the array struct ever 
gets copied in this code — it’s not explicitly passed as a parameter, just 
closed over. I don’t think I’ve read any docs that describe explicitly what the 
behavior is, maybe because it only becomes significant when you introduce 
threads?

This situation also begs the question of what kind of lower-level data 
structure one can use in Swift when Array is too high-level. In Obj-C one can 
drop down to C arrays, for example.

Gerriet, would you mind re-asking your initial question on swift-users? I’d 
love to hear what the Swift gurus say about it.

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Swift and Threads

2016-09-12 Thread Jens Alfke

> On Sep 12, 2016, at 6:42 AM, Gerriet M. Denkmann  wrote:
> 
> 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?

99% of the time it’s the latter. Which means you should try to debug the code. 
Did you set the breakpoint on malloc_error? What line of code is triggering it? 
Did you examine the values of variables? Did you run with the Address Sanitizer?

I don’t see a bug in your code itself, but I’m not sure about the thread-safety 
of Swift arrays. NSMutableArray isn’t thread-safe, and I think Swift follows 
the same general thread-safety conventions. On the other hand, it doesn’t look 
like the array gets resized in the threads since you allocate it with a given 
capacity, so the assignments shouldn’t be doing anything fancy like memory 
allocation.

(But on the other other hand, if Swift is smart enough [like C++] to specialize 
[Bool] as a true bit-array, then assigning to an array element does require 
thread-safety, since it will involve reading a byte from RAM, setting one bit, 
and writing it back. That’s not an atomic operation, so overlapping assignments 
can interfere with each other. It wouldn’t cause a crash, though, obviously.)

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Swift and Threads

2016-09-12 Thread Gerriet M. Denkmann
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.



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com