Levente Uzonyi uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-ul.1152.mcz ==================== Summary ==================== Name: Kernel-ul.1152 Author: ul Time: 5 February 2018, 8:47:28.262652 pm UUID: ae7053df-0c5e-489e-b14c-46ab4fd00986 Ancestors: Kernel-ul.1151 Monitor changes: - Monitor is now a subclass of Mutex. - All methods implemented by Mutex have been removed from Monitor. - The ownerProcess instance variable has been removed, because Mutex has its own owner instance variable. It was not referenced from Monitor's code. =============== Diff against Kernel-ul.1151 =============== Item was changed: + Mutex subclass: #Monitor + instanceVariableNames: 'defaultQueue queueDict queuesMutex nestingLevel' - LinkedList subclass: #Monitor - instanceVariableNames: 'ownerProcess defaultQueue queueDict queuesMutex nestingLevel' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Processes'! !Monitor commentStamp: 'eem 1/7/2016 11:38' prior: 0! A monitor provides process synchronization that is more high level than the one provided by a Semaphore. Similar to the classical definition of a Monitor it has the following properties: 1) At any time, only one process can execute code inside a critical section of a monitor. 2) A monitor is reentrant, which means that the active process in a monitor never gets blocked when it enters a (nested) critical section of the same monitor. For example a monitor will not block when trying the following: | m | m := Monitor new. m critical: [m critical: [#yes]] whereas a Semaphore will deadlock: | s | s := Semaphore forMutualExclusion. s critical: [s critical: [#no]] 3) Inside a critical section, a process can wait for an event that may be coupled to a certain condition. If the condition is not fulfilled, the process leaves the monitor temporarily (in order to let other processes enter) and waits until another process signals the event. Then, the original process checks the condition again (this is often necessary because the state of the monitor could have changed in the meantime) and continues if it is fulfilled. 4) The monitor is fair, which means that the process that is waiting on a signaled condition the longest gets activated first. 5) The monitor allows you to define timeouts after which a process gets activated automatically. Basic usage: Monitor>>critical: aBlock Critical section. Executes aBlock as a critical section. At any time, only one process can execute code in a critical section. NOTE: All the following synchronization operations are only valid inside the critical section of the monitor!! Monitor>>wait Unconditional waiting for the default event. The current process gets blocked and leaves the monitor, which means that the monitor allows another process to execute critical code. When the default event is signaled, the original process is resumed. Monitor>>waitWhile: aBlock Conditional waiting for the default event. The current process gets blocked and leaves the monitor only if the argument block evaluates to true. This means that another process can enter the monitor. When the default event is signaled, the original process is resumed, which means that the condition (argument block) is checked again. Only if it evaluates to false, does execution proceed. Otherwise, the process gets blocked and leaves the monitor again... Monitor>>waitUntil: aBlock Conditional waiting for the default event. See Monitor>>waitWhile: aBlock. Monitor>>signal One process waiting for the default event is woken up. Monitor>>signalAll All processes waiting for the default event are woken up. Using non-default (specific) events: Monitor>>waitFor: aSymbol Unconditional waiting for the non-default event represented by the argument symbol. Same as Monitor>>wait, but the process gets only reactivated by the specific event and not the default event. Monitor>>waitWhile: aBlock for: aSymbol Confitional waiting for the non-default event represented by the argument symbol. Same as Monitor>>waitWhile:for:, but the process gets only reactivated by the specific event and not the default event. Monitor>>waitUntil: aBlock for: aSymbol Confitional waiting for the non-default event represented by the argument symbol. See Monitor>>waitWhile:for: aBlock. Monitor>>signal: aSymbol One process waiting for the given event is woken up. If there is no process waiting for this specific event, a process waiting for the default event gets resumed. Monitor>>signalAll: aSymbol All process waiting for the given event or the default event are woken up. Monitor>>signalReallyAll All processes waiting for any events (default or specific) are woken up. Using timeouts Monitor>>waitMaxMilliseconds: anInteger Monitor>>waitFor: aSymbol maxMilliseconds: anInteger Same as Monitor>>wait (resp. Monitor>>waitFor:), but the process gets automatically woken up when the specified time has passed. Monitor>>waitWhile: aBlock maxMilliseconds: anInteger Monitor>>waitWhile: aBlock for: aSymbol maxMilliseconds: anInteger Same as Monitor>>waitWhile: (resp. Monitor>>waitWhile:for:), but the process gets automatically woken up when the specified time has passed. Monitor>>waitUntil: aBlock maxMilliseconds: anInteger Monitor>>waitUntil: aBlock for: aSymbol maxMilliseconds: anInteger Same as Monitor>>waitUntil: (resp. Monitor>>waitUntil:for:), but the process gets automatically woken up when the specified time has passed.! Item was removed: - ----- Method: Monitor>>critical: (in category 'mutual exclusion') ----- - critical: aBlock - "Evaluate aBlock protected by the receiver." - <criticalSection> - ^self primitiveEnterCriticalSection - ifTrue: [aBlock value] - ifFalse: [aBlock ensure: [self primitiveExitCriticalSection]]! Item was removed: - ----- Method: Monitor>>critical:ifLocked: (in category 'mutual exclusion') ----- - critical: aBlock ifLocked: lockedBlock - "Answer the evaluation of aBlock protected by the receiver. If it is already in a critical - section on behalf of some other process answer the evaluation of lockedBlock." - <criticalSection> - ^self primitiveTestAndSetOwnershipOfCriticalSection - ifNil: [lockedBlock value] - ifNotNil: - [:alreadyOwner| - alreadyOwner - ifTrue: [aBlock value] - ifFalse: [aBlock ensure: [self primitiveExitCriticalSection]]]! Item was removed: - ----- Method: Monitor>>primitiveEnterCriticalSection (in category 'private-primitives') ----- - primitiveEnterCriticalSection - "Primitive. The receiver must be unowned or owned by the current process to proceed. - Answer if the process is owned by the current process. - - Copyright (c) 2016 - 3D Immersive Collaboration Consulting, LLC." - <primitive: 186> - self primitiveFailed - "In the spirit of the following" - "[owner ifNil: - [owner := Processor activeProcess. - ^false]. - owner = Processor activeProcess ifTrue: - [^true]. - self addLast: Processor activeProcess. - Processor activeProcess suspend] valueUnpreemptively"! Item was removed: - ----- Method: Monitor>>primitiveEnterCriticalSectionOnBehalfOf: (in category 'system simulation') ----- - primitiveEnterCriticalSectionOnBehalfOf: effectiveProcess - "Primitive. Simulate primitiveEnterCriticalSection. The receiver - must be unowned or owned by the effectiveProcess to proceed. - Answer if the process is already owned by the current process." - <primitive: 186> - ^Context primitiveFailTokenFor: nil! Item was removed: - ----- Method: Monitor>>primitiveExitCriticalSection (in category 'private-primitives') ----- - primitiveExitCriticalSection - "Primitive. Set the receiver to unowned and if any processes are waiting on - the receiver then proceed the first one, indicating that the receiver is unowned. - - Copyright (c) 2016 - 3D Immersive Collaboration Consulting, LLC." - <primitive: 185> - self primitiveFailed - "In the spirit of the following" - "[owner := nil. - self isEmpty ifFalse: - [process := self removeFirst. - process resume]] valueUnpreemptively"! Item was removed: - ----- Method: Monitor>>primitiveTestAndSetOwnershipOfCriticalSection (in category 'private-primitives') ----- - primitiveTestAndSetOwnershipOfCriticalSection - "Primitive. Attempt to set the ownership of the receiver. - If the receiver is unowned set its owningProcess to the - activeProcess and answer false. If the receiver is owned - by the activeProcess answer true. If the receiver is owned - by some other process answer nil. - - Copyright (c) 2016 - 3D Immersive Collaboration Consulting, LLC." - <primitive: 187> - self primitiveFailed - "In the spirit of the following" - "[owner ifNil: - [owningProcess := Processor activeProcess. - ^false]. - owner = Processor activeProcess ifTrue: [^true]. - ^nil] valueUnpreemptively"! Item was removed: - ----- Method: Monitor>>primitiveTestAndSetOwnershipOfCriticalSectionOnBehalfOf: (in category 'system simulation') ----- - primitiveTestAndSetOwnershipOfCriticalSectionOnBehalfOf: effectiveProcess - "Primitive. Simulate primitiveEnterCriticalSection. Attempt to set the ownership - of the receiver. If the receiver is unowned set its owningProcess to the - effectiveProcess and answer false. If the receiver is owned by the effectiveProcess - answer true. If the receiver is owned by some other process answer nil." - <primitive: 187> - ^Context primitiveFailTokenFor: nil! |
Free forum by Nabble | Edit this page |