Is this really a race condition?


(Edward Connell) #1

The thread sanitizer on Linux is reporting that I have race conditions in
libswiftcore. I eliminated enough code down to this trivial example. Is
there really a race condition here or are these bogus errors?

let count = 1000
var items = [[UInt8]?](repeating: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
items[$0] = [UInt8](repeating: 7, count: 10)
}

My real scenario is retrieving data asynchronously, so I just threw in a
buffer assignment.

Thanks, Ed

···

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Read of size 8 at 0x7d9000008028 by thread T16:
    #0 memcpy <null> (libtsan.so.0+0x00000002617a)
    #1 _TwCcOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e0fa)

  Previous write of size 8 at 0x7d9000008028 by main thread:
    #0 memcpy <null> (libtsan.so.0+0x00000002617a)
    #1 _TwCcOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e0fa)

  Location is heap block of size 8032 at 0x7d9000008000 allocated by main
thread:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T16 (tid=30917, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 memcpy

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Write of size 8 at 0x7d0c00015d80 by thread T16:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TwXxOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e071)

  Previous write of size 8 at 0x7d0c00015d80 by main thread:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T16 (tid=30917, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Write of size 8 at 0x7d900000a028 by thread T20:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TZFSa11_copyBufferfRGVs22_ContiguousArrayBufferx_T_ <null>
(libswiftCore.so+0x00000010884e)

  Previous read of size 8 at 0x7d900000a028 by thread T17:
    #0 memcpy <null> (libtsan.so.0+0x00000002617a)
    #1 _TwCcOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e0fa)

  Thread T20 (tid=30921, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

  Thread T17 (tid=30918, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Read of size 8 at 0x7d9000006028 by thread T23:
    #0 memcpy <null> (libtsan.so.0+0x00000002617a)
    #1 _TwCcOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e0fa)

  Previous write of size 8 at 0x7d9000006028 by main thread:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Location is heap block of size 8032 at 0x7d9000006000 allocated by main
thread:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T23 (tid=30924, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 memcpy

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Write of size 8 at 0x7d900002e000 by thread T19:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TZFSa11_copyBufferfRGVs22_ContiguousArrayBufferx_T_ <null>
(libswiftCore.so+0x000000108859)

  Previous write of size 8 at 0x7d900002e000 by thread T20:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T19 (tid=30920, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

  Thread T20 (tid=30921, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Write of size 8 at 0x7d9000004000 by thread T17:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TZFSa11_copyBufferfRGVs22_ContiguousArrayBufferx_T_ <null>
(libswiftCore.so+0x00000010884e)

  Previous write of size 8 at 0x7d9000004000 by main thread:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T17 (tid=30918, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free


(Dave Abrahams) #2

The thread sanitizer on Linux is reporting that I have race conditions in
libswiftcore.

The only one we currently know about that's actually in libswiftcore is
the one addressed by https://github.com/apple/swift/pull/7183

···

on Wed Mar 01 2017, Edward Connell <swift-users-AT-swift.org> wrote:

I eliminated enough code down to this trivial example. Is there really
a race condition here or are these bogus errors?

let count = 1000
var items = [[UInt8]?](repeating: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
items[$0] = [UInt8](repeating: 7, count: 10)
}

My real scenario is retrieving data asynchronously, so I just threw in a
buffer assignment.

Thanks, Ed

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Read of size 8 at 0x7d9000008028 by thread T16:
    #0 memcpy <null> (libtsan.so.0+0x00000002617a)
    #1 _TwCcOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e0fa)

  Previous write of size 8 at 0x7d9000008028 by main thread:
    #0 memcpy <null> (libtsan.so.0+0x00000002617a)
    #1 _TwCcOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e0fa)

  Location is heap block of size 8032 at 0x7d9000008000 allocated by main
thread:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T16 (tid=30917, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 memcpy

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Write of size 8 at 0x7d0c00015d80 by thread T16:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TwXxOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e071)

  Previous write of size 8 at 0x7d0c00015d80 by main thread:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T16 (tid=30917, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Write of size 8 at 0x7d900000a028 by thread T20:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TZFSa11_copyBufferfRGVs22_ContiguousArrayBufferx_T_ <null>
(libswiftCore.so+0x00000010884e)

  Previous read of size 8 at 0x7d900000a028 by thread T17:
    #0 memcpy <null> (libtsan.so.0+0x00000002617a)
    #1 _TwCcOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e0fa)

  Thread T20 (tid=30921, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

  Thread T17 (tid=30918, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Read of size 8 at 0x7d9000006028 by thread T23:
    #0 memcpy <null> (libtsan.so.0+0x00000002617a)
    #1 _TwCcOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e0fa)

  Previous write of size 8 at 0x7d9000006028 by main thread:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Location is heap block of size 8032 at 0x7d9000006000 allocated by main
thread:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T23 (tid=30924, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 memcpy

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Write of size 8 at 0x7d900002e000 by thread T19:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TZFSa11_copyBufferfRGVs22_ContiguousArrayBufferx_T_ <null>
(libswiftCore.so+0x000000108859)

  Previous write of size 8 at 0x7d900002e000 by thread T20:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T19 (tid=30920, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

  Thread T20 (tid=30921, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free

==================
WARNING: ThreadSanitizer: data race (pid=30720)
  Write of size 8 at 0x7d9000004000 by thread T17:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TZFSa11_copyBufferfRGVs22_ContiguousArrayBufferx_T_ <null>
(libswiftCore.so+0x00000010884e)

  Previous write of size 8 at 0x7d9000004000 by main thread:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T17 (tid=30918, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free

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

--
-Dave


(Guillaume Lessard) #3

The assignments to array elements are where the race lies.

I don’t know about the libswiftcore part, but: assigning to a shared Array concurrently from multiple threads won't work, because of Array's copy-on-write behaviour. You could do

let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: 1)
items.initialize(to: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
  items[$0].initialize([UInt8](repeating: 7, count: 10))
}

// you’ll be able to see here that they’re all initialized

items.deallocate(capacity: count)

Cheers,
Guillaume Lessard

···

On Mar 1, 2017, at 3:21 PM, Edward Connell via swift-users <swift-users@swift.org> wrote:

The thread sanitizer on Linux is reporting that I have race conditions in libswiftcore. I eliminated enough code down to this trivial example. Is there really a race condition here or are these bogus errors?

  let count = 1000
  var items = [[UInt8]?](repeating: nil, count: count)

  DispatchQueue.concurrentPerform(iterations: count) {
    items[$0] = [UInt8](repeating: 7, count: 10)
  }

My real scenario is retrieving data asynchronously, so I just threw in a buffer assignment.


(Edward Connell) #4

Ahh! thank you. That makes sense.

···

On Wed, Mar 1, 2017 at 3:29 PM, Guillaume Lessard < glessard@tffenterprises.com> wrote:

> On Mar 1, 2017, at 3:21 PM, Edward Connell via swift-users < > swift-users@swift.org> wrote:
>
> The thread sanitizer on Linux is reporting that I have race conditions
in libswiftcore. I eliminated enough code down to this trivial example. Is
there really a race condition here or are these bogus errors?
>
> let count = 1000
> var items = [[UInt8]?](repeating: nil, count: count)
>
> DispatchQueue.concurrentPerform(iterations: count) {
> items[$0] = [UInt8](repeating: 7, count: 10)
> }
>
> My real scenario is retrieving data asynchronously, so I just threw in a
buffer assignment.

The assignments to array elements are where the race lies.

I don’t know about the libswiftcore part, but: assigning to a shared Array
concurrently from multiple threads won't work, because of Array's
copy-on-write behaviour. You could do

let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: 1)
items.initialize(to: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
  items[$0].initialize([UInt8](repeating: 7, count: 10))
}

// you’ll be able to see here that they’re all initialized

items.deallocate(capacity: count)

Cheers,
Guillaume Lessard


(Edward Connell) #5

Hi Guillaume,
There is still a race condition report, but I think maybe we are almost
there. I had to modify your example because it didn't quite build, and a
loop to do it twice since it randomly complains if you only do it once.
Btw, this is on Linux.
The warning is triggered when deinitialize is called. It wasn't in your
example, but it seems that it is required since the Elements are not a
trivial type like Int.

Thanks, Ed

for _ in 0..<2 {
let count = 1000
let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: count)
items.initialize(to: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
items[$0] = [UInt8](repeating: 7, count: 10)
}

items.deinitialize(count: count)
items.deallocate(capacity: count)
}

···

==================
WARNING: ThreadSanitizer: data race (pid=24076)
  Write of size 8 at 0x7d0c00005fa0 by main thread:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TwXxOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e071)

  Previous write of size 8 at 0x7d0c00005fa0 by thread T20:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T20 (tid=24288, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem
/home/buildnode/disk2/workspace/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815
(libdispatch.so+0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free

ThreadSanitizer: reported 1 warnings

On Wed, Mar 1, 2017 at 6:48 PM, Edward Connell <ewconnell@gmail.com> wrote:

Ahh! thank you. That makes sense.

On Wed, Mar 1, 2017 at 3:29 PM, Guillaume Lessard < > glessard@tffenterprises.com> wrote:

> On Mar 1, 2017, at 3:21 PM, Edward Connell via swift-users < >> swift-users@swift.org> wrote:
>
> The thread sanitizer on Linux is reporting that I have race conditions
in libswiftcore. I eliminated enough code down to this trivial example. Is
there really a race condition here or are these bogus errors?
>
> let count = 1000
> var items = [[UInt8]?](repeating: nil, count: count)
>
> DispatchQueue.concurrentPerform(iterations: count) {
> items[$0] = [UInt8](repeating: 7, count: 10)
> }
>
> My real scenario is retrieving data asynchronously, so I just threw in
a buffer assignment.

The assignments to array elements are where the race lies.

I don’t know about the libswiftcore part, but: assigning to a shared
Array concurrently from multiple threads won't work, because of Array's
copy-on-write behaviour. You could do

let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: 1)
items.initialize(to: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
  items[$0].initialize([UInt8](repeating: 7, count: 10))
}

// you’ll be able to see here that they’re all initialized

items.deallocate(capacity: count)

Cheers,
Guillaume Lessard


(Zhao Xin) #6

I am sorry if this bothers you. I just put the original code in Xcode and
it works. Anyone knows why this works in Xcode or in macOS? I thought it
should show the same warnings as Linux.

Zhaoxin

···

On Fri, Mar 3, 2017 at 2:51 AM, Edward Connell via swift-users < swift-users@swift.org> wrote:

Hi Guillaume,
There is still a race condition report, but I think maybe we are almost
there. I had to modify your example because it didn't quite build, and a
loop to do it twice since it randomly complains if you only do it once.
Btw, this is on Linux.
The warning is triggered when deinitialize is called. It wasn't in your
example, but it seems that it is required since the Elements are not a
trivial type like Int.

Thanks, Ed

for _ in 0..<2 {
let count = 1000
let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: count)
items.initialize(to: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
items[$0] = [UInt8](repeating: 7, count: 10)
}

items.deinitialize(count: count)
items.deallocate(capacity: count)
}

==================
WARNING: ThreadSanitizer: data race (pid=24076)
  Write of size 8 at 0x7d0c00005fa0 by main thread:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TwXxOs31_ClosedRangeIndexRepresentation <null> (libswiftCore.so+
0x00000027e071)

  Previous write of size 8 at 0x7d0c00005fa0 by thread T20:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T20 (tid=24288, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem /home/buildnode/disk2/
workspace/oss-swift-3.0-package-linux-ubuntu-16_04/
swift-corelibs-libdispatch/libpwq/src/posix/manager.c:815 (libdispatch.so+
0x00000007c6b1)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free

ThreadSanitizer: reported 1 warnings

On Wed, Mar 1, 2017 at 6:48 PM, Edward Connell <ewconnell@gmail.com> > wrote:

Ahh! thank you. That makes sense.

On Wed, Mar 1, 2017 at 3:29 PM, Guillaume Lessard < >> glessard@tffenterprises.com> wrote:

> On Mar 1, 2017, at 3:21 PM, Edward Connell via swift-users < >>> swift-users@swift.org> wrote:
>
> The thread sanitizer on Linux is reporting that I have race conditions
in libswiftcore. I eliminated enough code down to this trivial example. Is
there really a race condition here or are these bogus errors?
>
> let count = 1000
> var items = [[UInt8]?](repeating: nil, count: count)
>
> DispatchQueue.concurrentPerform(iterations: count) {
> items[$0] = [UInt8](repeating: 7, count: 10)
> }
>
> My real scenario is retrieving data asynchronously, so I just threw in
a buffer assignment.

The assignments to array elements are where the race lies.

I don’t know about the libswiftcore part, but: assigning to a shared
Array concurrently from multiple threads won't work, because of Array's
copy-on-write behaviour. You could do

let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: 1)
items.initialize(to: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
  items[$0].initialize([UInt8](repeating: 7, count: 10))
}

// you’ll be able to see here that they’re all initialized

items.deallocate(capacity: count)

Cheers,
Guillaume Lessard

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


(Edward Connell) #7

Not at all, thank you for trying it out.
When I run my code on the Mac in Xcode with thread sanitizer on, I don't
get any warnings or problems at all. I only find problems on Linux. I have
noticed that for the same release, the compiler and libraries are not
identical between Mac and Linux. I am currently using what I believe is the
latest release for both

$ swift --version
Swift version 3.0.2 (swift-3.0.2-RELEASE)
Target: x86_64-unknown-linux-gnu

···

On Thu, Mar 2, 2017 at 3:32 PM, Zhao Xin <owenzx@gmail.com> wrote:

I am sorry if this bothers you. I just put the original code in Xcode and
it works. Anyone knows why this works in Xcode or in macOS? I thought it
should show the same warnings as Linux.

Zhaoxin

On Fri, Mar 3, 2017 at 2:51 AM, Edward Connell via swift-users < > swift-users@swift.org> wrote:

Hi Guillaume,
There is still a race condition report, but I think maybe we are almost
there. I had to modify your example because it didn't quite build, and a
loop to do it twice since it randomly complains if you only do it once.
Btw, this is on Linux.
The warning is triggered when deinitialize is called. It wasn't in your
example, but it seems that it is required since the Elements are not a
trivial type like Int.

Thanks, Ed

for _ in 0..<2 {
let count = 1000
let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: count)
items.initialize(to: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
items[$0] = [UInt8](repeating: 7, count: 10)
}

items.deinitialize(count: count)
items.deallocate(capacity: count)
}

==================
WARNING: ThreadSanitizer: data race (pid=24076)
  Write of size 8 at 0x7d0c00005fa0 by main thread:
    #0 free <null> (libtsan.so.0+0x000000025819)
    #1 _TwXxOs31_ClosedRangeIndexRepresentation <null>
(libswiftCore.so+0x00000027e071)

  Previous write of size 8 at 0x7d0c00005fa0 by thread T20:
    #0 malloc <null> (libtsan.so.0+0x0000000254a3)
    #1 swift_slowAlloc <null> (libswiftCore.so+0x0000002ee3e5)

  Thread T20 (tid=24288, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027577)
    #1 manager_workqueue_additem /home/buildnode/disk2/workspac
e/oss-swift-3.0-package-linux-ubuntu-16_04/swift-corelibs-
libdispatch/libpwq/src/posix/manager.c:815 (libdispatch.so+0x00000007c6b1
)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_free

ThreadSanitizer: reported 1 warnings

On Wed, Mar 1, 2017 at 6:48 PM, Edward Connell <ewconnell@gmail.com> >> wrote:

Ahh! thank you. That makes sense.

On Wed, Mar 1, 2017 at 3:29 PM, Guillaume Lessard < >>> glessard@tffenterprises.com> wrote:

> On Mar 1, 2017, at 3:21 PM, Edward Connell via swift-users < >>>> swift-users@swift.org> wrote:
>
> The thread sanitizer on Linux is reporting that I have race
conditions in libswiftcore. I eliminated enough code down to this trivial
example. Is there really a race condition here or are these bogus errors?
>
> let count = 1000
> var items = [[UInt8]?](repeating: nil, count: count)
>
> DispatchQueue.concurrentPerform(iterations: count) {
> items[$0] = [UInt8](repeating: 7, count: 10)
> }
>
> My real scenario is retrieving data asynchronously, so I just threw
in a buffer assignment.

The assignments to array elements are where the race lies.

I don’t know about the libswiftcore part, but: assigning to a shared
Array concurrently from multiple threads won't work, because of Array's
copy-on-write behaviour. You could do

let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: 1)
items.initialize(to: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
  items[$0].initialize([UInt8](repeating: 7, count: 10))
}

// you’ll be able to see here that they’re all initialized

items.deallocate(capacity: count)

Cheers,
Guillaume Lessard

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