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