Issue 3428 in pharo: Semaphore Enh

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Issue 3428 in pharo: Semaphore Enh

pharo
Status: FixedWaitingToBePharoed
Owner: stephane.ducasse
CC: siguctua
Labels: Milestone-1.3

New issue 3428 by stephane.ducasse: Semaphore Enh
http://code.google.com/p/pharo/issues/detail?id=3428


Name: Kernel-ul.520
Author: ul
Time: 8 December 2010, 3:19:51.682 am
UUID: da185163-27f6-6a47-8ecb-e00f9fd8dd3a
Ancestors: Kernel-ul.519

A few changes to Semaphore:
- save a block creation + activation + a possible context switch in  
#critical:ifCurtailed:
- save a block creation + activation in #critical:ifError:, this changes  
the behavior when mutuallyExcludedBlock doesn't understand #ifError:
- #critical:ifLocked: is guaranteed to not get locked. The earlier  
implementation sent #critical: which could cause a context switch, so  
another process could enter the critical section before the current. Also  
fixed the comments of this method.

=============== Diff against Kernel-ul.519 ===============

Item was changed:
  ----- Method: Semaphore>>critical:ifCurtailed: (in category 'mutual  
exclusion') -----
  critical: mutuallyExcludedBlock ifCurtailed: terminationBlock
        "Evaluate mutuallyExcludedBlock only if the receiver is not  
currently in
        the process of running the critical: message. If the receiver is,  
evaluate
        mutuallyExcludedBlock after the other critical: message is finished."
+       ^self critical: [ mutuallyExcludedBlock ifCurtailed:  
terminationBlock ]
-       ^self critical:[[mutuallyExcludedBlock value] ifCurtailed:  
terminationBlock]
  !

Item was changed:
  ----- Method: Semaphore>>critical:ifError: (in category 'mutual  
exclusion') -----
  critical: mutuallyExcludedBlock ifError: errorBlock
        "Evaluate mutuallyExcludedBlock only if the receiver is not  
currently in
        the process of running the critical: message. If the receiver is,  
evaluate
        mutuallyExcludedBlock after the other critical: message is finished."
        | blockValue hasError errMsg errRcvr |
        hasError := false.
        blockValue := self critical:[
+               mutuallyExcludedBlock ifError: [ :msg :rcvr |
-               [mutuallyExcludedBlock value] ifError:[:msg :rcvr|
                        hasError := true.
                        errMsg := msg.
                        errRcvr := rcvr
                ].
        ].
        hasError ifTrue:[ ^errorBlock value: errMsg value: errRcvr].
        ^blockValue!

Item was changed:
  ----- Method: Semaphore>>critical:ifLocked: (in category 'mutual  
exclusion') -----
  critical: mutuallyExcludedBlock ifLocked: alternativeBlock
        "Evaluate mutuallyExcludedBlock only if the receiver is not  
currently in
+       the process of running the critical: message. If the receiver is,  
then evaluate
+       alternativeBlock and return."
+       "See the comment of #critical: for the explanation how this pattern  
works
+       before changing the code."
+
+       | caught |
+       caught := false.
+       ^[
+               "We're using #== here instead of #=, because it won't  
introduce a
+               suspension point, while #= may do that."
+               excessSignals == 0
+                       ifTrue: [ alternativeBlock value ]
+                       ifFalse: [
+                               excessSignals := excessSignals - 1.
+                               caught := true.
+                               mutuallyExcludedBlock value ] ]
+               ensure: [ caught ifTrue: [ self signal ] ]!
-       the process of running the critical: message. If the receiver is,  
evaluate
-       mutuallyExcludedBlock after the other critical: message is  
finished."
-
-       "Note: The following is tricky and depends on the fact that the VM  
will not switch between processes while executing byte codes (process  
switches happen only in real sends). The following test is written  
carefully so that it will result in bytecodes only.
-       Do not change the following #== for #=, as #== is not a real  
message send, just a bytecode."
-       excessSignals == 0 ifTrue: [
-               "If we come here, then the semaphore was locked when the  
test executed.
-               Evaluate the alternative block and answer its result."
-               ^alternativeBlock value
-       ].
-       ^self critical: mutuallyExcludedBlock!



Reply | Threaded
Open this post in threaded view
|

Re: Issue 3428 in pharo: Semaphore Enh

pharo

Comment #1 on issue 3428 by stephane.ducasse: Semaphore Enh
http://code.google.com/p/pharo/issues/detail?id=3428

A new version of Kernel was added to project The Inbox:
http://source.squeak.org/inbox/Kernel-ul.523.mcz

==================== Summary ====================

Name: Kernel-ul.523
Author: ul
Time: 8 December 2010, 4:45:41.467 am
UUID: 809ca265-c5de-ac47-b6d6-226f80cf9245
Ancestors: Kernel-ul.522

- added Semaphore >> #waitIfLocked:

=============== Diff against Kernel-ul.522 ===============

Item was added:
+ ----- Method: Semaphore>>waitIfLocked: (in category 'communication') -----
+ waitIfLocked: aBlock
+       "Use a signal if available, otherwise evaluate aBlock"
+
+       excessSignals == 0 ifTrue: [ ^aBlock value ].
+       excessSignals := excessSignals - 1!


Not

eliot proposed

waitIfLocked: aBlock
        "Use a signal if available, otherwise evaluate aBlock"

        excessSignals == 0 ifTrue: [ ^aBlock valueNoContextSwitch ].
        excessSignals := excessSignals - 1

?