Hi Levente,
thanks!!
On Sat, Dec 31, 2016 at 8:48 AM, Levente Uzonyi leves@caesar.elte.hu wrote:
On Sat, 31 Dec 2016, commits@source.squeak.org wrote:
[snip]
Item was changed: ----- Method: StackInterpreterSimulator>>signalSemaphoreWithIndex: (in category 'process primitive support') ----- signalSemaphoreWithIndex: index "This is a non-thread-safe simulation. See platforms/Cross/vm/sqExternalSemaphores.c
It could be made thread safe:
| originalResponses newRequests newResponses | index <= 0 ifTrue: [^false]. index > externalSemaphoreSignalRequests size ifTrue: [ newRequests := Array new: 1 << index highBit withAll: 0. newResponses := newRequests copy ]. originalResponses := externalSemaphoreSignalResponses. [ index > externalSemaphoreSignalRequests size ] whileTrue: [ newRequests replaceFrom: 1 to: externalSemaphoreSignalRequests size with: externalSemaphoreSignalRequests startingAt: 1. newResponses replaceFrom: 1 to: externalSemaphoreSignalResponses size with: externalSemaphoreSignalResponses startingAt: 1. externalSemaphoreSignalResponses == originalResponses
"This should always be true." ifTrue: [ externalSemaphoreSignalRequests := newRequests. externalSemaphoreSignalResponses := newResponses ] ifFalse: [ originalResponses := externalSemaphoreSignalResponses ] ]. externalSemaphoreSignalRequests at: index put: (externalSemaphoreSignalRequests at: index) + 1. ^true
This is also a good example why CAS-style thread safety is a lot less flexible.
Levente
I wonder would you be interested in taking a look at the real code in platforms/Cross/vm/sqExternalSemaphores.c? I have a lock-free implementation of signalling, but no lock-free implementation of growing the sequence of signal requests, and hence the ugly and annoying need to specify a maximum size to the external signal requests table. It would be lovely to say good bye to this :-)
for the real code."
index <= 0 ifTrue: [^false]. index > externalSemaphoreSignalRequests size ifTrue: [| newRequests newResponses | newRequests := Array new: 1 << index highBit withAll: 0. newResponses := newRequests copy. newRequests replaceFrom: 1 to: externalSemaphoreSignalRequests size with: externalSemaphoreSignalRequests startingAt: 1. newResponses replaceFrom: 1 to: externalSemaphoreSignalResponses size with: externalSemaphoreSignalResponses
startingAt: 1.
externalSemaphoreSignalRequests := newRequests.
externalSemaphoreSignalResponses := newResponses].
startingAt: 1]. externalSemaphoreSignalRequests at: index put: (externalSemaphoreSignalRequests at: index) + 1. ^true!
Yes, nice. The final at:put: is not thread-safe but your code is far better than the original. I've included it and will commit soon. Happy new year!
_,,,^..^,,,_ best, Eliot