JavaMonitor.st
changeset 3777 971961e59d5e
parent 3773 f2fdd527603f
child 3778 2297f9daef8a
--- a/JavaMonitor.st	Fri Aug 11 11:34:41 2017 +0100
+++ b/JavaMonitor.st	Fri May 05 17:52:31 2017 +0200
@@ -23,8 +23,8 @@
 "{ NameSpace: Smalltalk }"
 
 Object subclass:#JavaMonitor
-	instanceVariableNames:'owningProcess processesEntered monitorSema count waitingSema
-		processesWaiting waitEnabled ownerPrintString'
+	instanceVariableNames:'owningProcess monitorSema count waitingSema waitEnabled
+		ownerPrintString'
 	classVariableNames:'instVarAccess'
 	poolDictionaries:''
 	category:'Languages-Java-Support'
@@ -81,72 +81,29 @@
 
 !JavaMonitor methodsFor:'accessing'!
 
-activeProcess
-    ^ Processor activeProcess
-!
-
-copyProcessesEntered
-    ^ processesEntered copy.
-
-    "Created: / 20-11-2011 / 14:45:24 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-!
-
 count
     ^ count
 !
 
 processesEntered
-    "dont do anything to me, access needs to be sync'd"
-    ^ processesEntered.
+    "Return a alist of processes that entered the monitor. For testing / debugging purposes only!!"
+
+    ^ owningProcess isNil 
+        ifTrue:[ #() ]
+        ifFalse:[ (Array with: owningProcess) , monitorSema waitingProcesses ]
 
     "Created: / 20-11-2011 / 13:22:15 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified (format): / 03-06-2017 / 23:10:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaMonitor methodsFor:'atomic'!
 
-addProcess: aProcess 
-    instVarAccess critical: [ processesEntered add: aProcess ].
-
-    "Created: / 20-11-2011 / 20:30:07 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-!
-
-clearOwningProcess
-    instVarAccess critical: [ owningProcess := nil ].
-
-    "Created: / 20-11-2011 / 20:34:27 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-!
-
-decrement
-    "owning process released monitor, let's lower our counter so we know how many times
-     we have to release it"
-    
-    "/ the lock is probably not helping here to protect against problems with
-    "/ increment/decrement:
-    "/ the write-access (in reinitCOunter) will be either done before incrementing/decrementing or after.
-    "/ if after, everything is ok;
-    "/ if before, the decremented value will be zero, which is probably wrong.
-
-    "/ without the critical region, we might also get possible inconsistencies:
-    "/ if written before, the counter will drop to zero
-    "/ if written in-between, the counter wil ahve the old value decremented;
-    "/ if written afterwards, everything is ok.
-
-    "/ so, the lock should be really elsewhere, making sure that noone will count
-    "/ the monitor at-all and the monitor is reininialized without anyone depending on the
-    "/ count at all.
-    "/ but then, no critical section is needed in reinitCounter!!.
-
-    instVarAccess critical: [ count := count - 1 ].
-
-    "Created: / 22-11-2011 / 10:49:33 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-!
-
 disableWait
     JavaVM monitorTrace ifTrue:[
         Logger log: ('Waiting is disabled on monitor for %1' bindWith: ownerPrintString) severity:Logger severityDEBUG facility:#JVM.
     ].
     "/ critical region not needed here
-    "/ instVarAccess critical: [ waitEnabled := false ].
+    "/ self instVarAccessCritical: [ waitEnabled := false ].
     waitEnabled := false.
 
     "Created: / 30-11-2011 / 20:34:40 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
@@ -155,125 +112,23 @@
 
 enableWait
     "/ critical region not needed here
-    "/ instVarAccess critical: [waitEnabled := true].
+    "/ self instVarAccessCritical: [waitEnabled := true].
     waitEnabled := true
     
     "Created: / 30-11-2011 / 20:34:31 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
     "Modified (format): / 11-10-2013 / 11:17:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-increment
-    "owning process entered monitor again (recursion ...), lets raise our counter so we know how many times
-     do we have to release it"
-    
-    "/ the lock is probably not helping here to protect against problems with
-    "/ increment/decrement:
-    "/ the write-access (in reinitCOunter) will be either done before incrementing/decrementing or after.
-    "/ if after, everything is ok;
-    "/ if before, the decremented value will be zero, which is probably wrong.
-
-    "/ without the critical region, we might also get possible inconsistencies:
-    "/ if written before, the counter will drop to zero
-    "/ if written in-between, the counter wil ahve the old value decremented;
-    "/ if written afterwards, everything is ok.
-
-    "/ so, the lock should be really elsewhere, making sure that noone will count
-    "/ the monitor at-all and the monitor is reininialized without anyone depending on the
-    "/ count at all.
-    "/ but then, no critical section is needed in reinitCounter!!.
-
-    instVarAccess critical: [ count := count + 1 ].
-
-    "Created: / 22-11-2011 / 10:49:07 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 27-08-2012 / 10:42:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-owningProcess: aProcess 
-    instVarAccess critical: [ owningProcess := aProcess ].
-
-    "Created: / 20-11-2011 / 20:32:26 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-!
-
-processesWaitingAdd: aProcess 
-    instVarAccess 
-        critical: [
-            self assert: (processesWaiting includesKey: aProcess) not.
-            processesWaiting at: aProcess put: count
-        ].
-
-    "Created: / 22-11-2011 / 11:57:50 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-!
-
-processesWaitingRestore: aProcess 
-    instVarAccess 
-        critical: [
-            self assert: (processesWaiting includesKey: aProcess).
-            self reinitCounter: (processesWaiting at: aProcess).
-            processesWaiting removeKey: aProcess
-        ].
-
-    "Created: / 22-11-2011 / 12:59:14 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-!
+instVarAccessCritical: aBlock
+    ^ instVarAccess critical: aBlock.
 
-reinitCounter
-    "owning process is different from previous, lets start counting from beginning"
-
-    "/ the lock is probably not helping here to protect against problems with
-    "/ increment/decrement:
-    "/ the write-access here will be either done before incrementing/decrementing or after.
-    "/ if after, everything is ok;
-    "/ if before, the decremented value will be zero, which is probably wrong.
-
-    "/ without the critical region, we might also get possible inconsistencies:
-    "/ if written before, the counter will drop to zero
-    "/ if written in-between, the counter wil ahve the old value decremented;
-    "/ if written afterwards, everything is ok.
-    
-    "/ so, the lock should be really elsewhere, making sure that noone will count
-    "/ the monitor at-all and the monitor is reininialized without anyone depending on the
-    "/ count at all.
-    "/ but then, no critical section is needed!!.
-    
-    instVarAccess critical: [ count := 1 ].
-
-    "Created: / 22-11-2011 / 10:51:09 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-!
-
-reinitCounter: newCount 
-    "/ the lock is probably not helping here to protect against problems with
-    "/ increment/decrement:
-    "/ the write-access here will be either done before incrementing/decrementing or after.
-    "/ if after, everything is ok;
-    "/ if before, the decremented value will be zero, which is probably wrong.
-
-    "/ without the critical region, we might also get possible inconsistencies:
-    "/ if written before, the counter will drop to zero
-    "/ if written in-between, the counter wil ahve the old value decremented;
-    "/ if written afterwards, everything is ok.
-
-    "/ so, the lock should be really elsewhere, making sure that noone will count
-    "/ the monitor at-all and the monitor is reininialized without anyone depending on the
-    "/ count at all.
-    "/ but then, no critical section is needed!!.
-
-    instVarAccess critical: [ count := newCount ].
-
-    "Created: / 22-11-2011 / 13:00:51 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-!
-
-removeProcess: aProcess 
-    instVarAccess 
-        critical: [
-            self assert: processesEntered last == aProcess.
-            processesEntered remove: aProcess
-        ].
-
-    "Created: / 20-11-2011 / 20:28:37 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Created: / 03-06-2017 / 22:09:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-06-2017 / 23:15:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 waitEnabled
     "/ critical region not needed here
-    "/ instVarAccess critical: [ ^ waitEnabled].
+    "/ self instVarAccessCritical: [ ^ waitEnabled].
     ^ waitEnabled.
 
     "Created: / 30-11-2011 / 20:34:56 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
@@ -281,19 +136,6 @@
 
 !JavaMonitor methodsFor:'initialization'!
 
-initialize
-    "Q: is this ever called?"
-    
-    owningProcess := nil.
-    processesEntered := OrderedCollection new.
-    monitorSema := Semaphore new: 1.
-    processesWaiting := Dictionary new.
-    waitingSema := Semaphore new: 0.
-    waitEnabled := true.
-
-    "Created: / 20-11-2011 / 13:28:28 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-!
-
 initializeFor: owningObject
     self initializeFor: owningObject thread: 0 nestedLockCount: 0.
 
@@ -305,9 +147,7 @@
 
 "/    self assert: (owningObject isJavaObject or:[owningObject isJavaClass]).
 
-    processesEntered := OrderedCollection new.
     waitEnabled := true.
-    processesWaiting := Dictionary new.
     waitingSema := Semaphore new:0.
     ownerPrintString := owningObject class name , '@' , owningObject identityHash printString.
 
@@ -322,7 +162,6 @@
 
         owningProcess := ObjectMemory processesKnownInVM detect:[:p|p id == threadId] ifNone:[nil].
         self assert: owningProcess notNil.
-        processesEntered add: owningProcess.  
         cnt timesRepeat:[
 "/            JavaVM enteredMonitorsOf:  owningProcess add: owningObject.
 "/            JavaVM acquiredMonitorsOf: owningProcess add: owningObject.
@@ -332,42 +171,60 @@
     ].
 
     "Created: / 26-08-2012 / 17:02:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-06-2017 / 23:10:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaMonitor methodsFor:'public'!
 
 acquire
     | thisProcess |
-    thisProcess := self activeProcess.
+    thisProcess := Processor activeProcess.
     (self isOwnedBy: thisProcess) ifTrue: [
-        self increment.
+        "/ the lock is probably not helping here to protect against problems with
+        "/ increment/decrement:
+        "/ the write-access (in reinitCOunter) will be either done before incrementing/decrementing or after.
+        "/ if after, everything is ok;
+        "/ if before, the decremented value will be zero, which is probably wrong.
+
+        "/ without the critical region, we might also get possible inconsistencies:
+        "/ if written before, the counter will drop to zero
+        "/ if written in-between, the counter wil ahve the old value decremented;
+        "/ if written afterwards, everything is ok.
+
+        "/ so, the lock should be really elsewhere, making sure that noone will count
+        "/ the monitor at-all and the monitor is reininialized without anyone depending on the
+        "/ count at all.
+        "/ but then, no critical section is needed in reinitCounter!!.
+
+        self instVarAccessCritical: [ count := count + 1 ].
         ^ self
     ].
     monitorSema wait.
-    self owningProcess: thisProcess.
+    owningProcess := thisProcess. 
     count := 1.
 
     "Created: / 20-11-2011 / 13:21:46 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 27-08-2012 / 11:45:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-06-2017 / 22:36:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 enter
-    | thisProcess |
-    thisProcess := self activeProcess.
-    self addProcess: thisProcess.
     self acquire.
 
     "Created: / 20-11-2011 / 13:21:42 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 03-06-2017 / 23:11:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 exit
     | thisProcess |
-    thisProcess := self activeProcess.
-    (self isOwnedBy: thisProcess) ifTrue: [ self release. ].    
-    processesEntered remove: thisProcess ifAbsent: nil.
+
+    "JV@2017-06-03: Question: Is it legal (i.e., is the good reason to) call #exit 
+     on a monitor by a process that does not own it? Shouldn't we rather throw an 
+     error"
+    thisProcess := Processor activeProcess.
+    (self isOwnedBy: thisProcess) ifTrue: [ self release. ].
 
     "Created: / 20-11-2011 / 13:21:54 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 26-08-2012 / 19:54:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 03-06-2017 / 23:13:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 notify
@@ -379,7 +236,7 @@
     JavaVM monitorTrace ifTrue:[
         Logger 
             log: ('%1: notifying %2 processes' bindWith: thisProcess printString
-                    with: processesWaiting size)
+                    with: waitingSema waitingProcesses size)
             severity: Logger severityDEBUG
             facility: #JVM.
     ].
@@ -387,7 +244,7 @@
     Processor yield.
 
     "Created: / 22-11-2011 / 12:14:23 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 02-03-2015 / 14:06:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 05-05-2017 / 17:27:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 notifyAll
@@ -399,7 +256,7 @@
     JavaVM monitorTrace ifTrue:[
         Logger 
             log: ('%1: notifying all %2 processes' bindWith: thisProcess printString
-                    with: processesWaiting size)
+                    with: waitingSema waitingProcesses size)
             severity: Logger severityDEBUG
             facility: #JVM.
     ].
@@ -407,27 +264,37 @@
     Processor yield.
 
     "Created: / 22-11-2011 / 12:14:36 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 02-03-2015 / 14:06:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 05-05-2017 / 17:28:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 release
     self assert: (self isOwnedBy: owningProcess).
     count == 1 ifTrue: [
-        self clearOwningProcess.
+        self instVarAccessCritical: [ owningProcess := nil ].  
         count := 0.
         monitorSema signal.
     ] ifFalse: [
-        self decrement.       
+        "/ the lock is probably not helping here to protect against problems with
+        "/ increment/decrement:
+        "/ the write-access (in reinitCOunter) will be either done before incrementing/decrementing or after.
+        "/ if after, everything is ok;
+        "/ if before, the decremented value will be zero, which is probably wrong.
+
+        "/ without the critical region, we might also get possible inconsistencies:
+        "/ if written before, the counter will drop to zero
+        "/ if written in-between, the counter wil ahve the old value decremented;
+        "/ if written afterwards, everything is ok.
+
+        "/ so, the lock should be really elsewhere, making sure that noone will count
+        "/ the monitor at-all and the monitor is reininialized without anyone depending on the
+        "/ count at all.
+        "/ but then, no critical section is needed in reinitCounter!!.
+
+        self instVarAccessCritical: [ count := count - 1 ].
     ]
 
     "Created: / 20-11-2011 / 13:21:52 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 11-10-2013 / 11:18:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-releaseAll
-    count timesRepeat: [self release].
-
-    "Created: / 22-11-2011 / 13:05:20 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 03-06-2017 / 22:24:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 wait
@@ -464,9 +331,8 @@
             severity: #debug
             facility: #JVM.
     ].
-    self processesWaitingAdd: thisProcess.
     countBeforeWait :=  count.
-    self releaseAll.
+    count timesRepeat: [self release].
      "JV@2011-11-25: zero timeout means wait without timeout!!!!!!"
     timeOut == 0 ifTrue: [ waitingSema wait ] ifFalse: [
         waitingSema waitWithTimeoutMs: timeOut
@@ -481,23 +347,21 @@
     self acquire.
     count := countBeforeWait.
 
-    self processesWaitingRestore: thisProcess.
-
     "Created: / 22-11-2011 / 12:52:45 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
     "Modified: / 01-12-2011 / 10:57:52 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 02-03-2015 / 14:06:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-06-2017 / 22:52:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaMonitor methodsFor:'queries'!
 
 isAcquired
-    ^ instVarAccess critical: [ owningProcess notNil ].
+    ^ self instVarAccessCritical: [ owningProcess notNil ].
 
     "Created: / 20-11-2011 / 13:22:26 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
 !
 
 isOwnedBy: aProcess 
-    ^ instVarAccess critical: [ owningProcess == aProcess ].
+    ^ self instVarAccessCritical: [ owningProcess == aProcess ].
 
     "Created: / 20-11-2011 / 13:23:14 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
 ! !