The Inbox: Kernel-ul.1151.mcz

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

The Inbox: Kernel-ul.1151.mcz

commits-2
Levente Uzonyi uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-ul.1151.mcz

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

Name: Kernel-ul.1151
Author: ul
Time: 5 February 2018, 8:36:45.002788 pm
UUID: 42deff55-7552-442b-ac97-a046ece97558
Ancestors: Kernel-tonyg.1150

Monitor changes:
- copied the missing methods used by the debugger:
primitiveEnterCriticalSectionOnBehalfOf: and primitiveTestAndSetOwnershipOfCriticalSectionOnBehalfOf:
- queuesMutex is now a Mutex instead of a Semaphore
- removed the unused mutex variable
- the next step could be to make Monitor a subclass of Mutex

- improved Integer >> #isPrime's performance in 64-bit images
- ScaledDecimal >> #printOn: rounds the number instead of truncating it

=============== Diff against Kernel-tonyg.1150 ===============

Item was changed:
  ----- Method: Integer>>isPrime (in category 'testing') -----
  isPrime
  "Answer true if the receiver is a prime number. See isProbablyPrime for a probabilistic
  implementation that is much faster for large integers, and that is correct to an extremely
  high statistical level of confidence (effectively deterministic)."
 
  self <= 1 ifTrue: [ ^false ].
  self even ifTrue: [ ^self = 2].
+ self <= 1073741823 ifFalse: [ "1 << 30 - 1. For numbers larger than this, the calculation takes longer than #isProbablyPrime when the receiver is a prime. The absolue turning point is about at 1 << 35 - 1."
+ ^self isProbablyPrime ].
  3 to: self sqrtFloor by: 2 do: [ :each |
  self \\ each = 0 ifTrue: [ ^false ] ].
  ^true!

Item was changed:
  LinkedList subclass: #Monitor
+ instanceVariableNames: 'ownerProcess defaultQueue queueDict queuesMutex nestingLevel'
- instanceVariableNames: 'ownerProcess defaultQueue queueDict queuesMutex mutex 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 changed:
  ----- Method: Monitor>>initialize (in category 'initialize-release') -----
  initialize
+ queuesMutex := Mutex new!
- queuesMutex := Semaphore forMutualExclusion!

Item was added:
+ ----- 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 added:
+ ----- 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!

Item was changed:
  ----- Method: ScaledDecimal>>printOn: (in category 'printing') -----
  printOn: stream
 
  self
+ printOn: stream showingDecimalPlaces: scale;
- printFractionAsDecimalOn: stream;
  printScaleOn: stream!