Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ul.1157.mcz
==================== Summary ====================
Name: Kernel-ul.1157
Author: ul
Time: 5 March 2018, 8:52:06.571627 pm
UUID: d0cb2a27-7e25-44de-9a35-1c498e2083d1
Ancestors: Kernel-ul.1156
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.
- queuesMutex is now a Mutex instead of a Semaphore.
- Removed the unused mutex variable.
=============== Diff against Kernel-ul.1156 ===============
Item was changed:
+ Mutex subclass: #Monitor
+ instanceVariableNames: 'defaultQueue queueDict queuesMutex nestingLevel'
- LinkedList subclass: #Monitor
- 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>>checkOwnerProcess (in category 'private') -----
checkOwnerProcess
"If the receiver is not already the owner of the section raise an error."
+
+ self primitiveTestAndSetOwnershipOfCriticalSection ifNotNil: [ :alreadyOwner |
+ alreadyOwner ifTrue: [ ^self ].
+ self primitiveExitCriticalSection ].
+ self error: 'Monitor access violation'!
- (self primitiveTestAndSetOwnershipOfCriticalSection
- ifNil: [false]
- ifNotNil:
- [:alreadyOwner|
- alreadyOwner
- or: [self primitiveExitCriticalSection.
- false]]) ifFalse:
- [self error: 'Monitor access violation']!
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 changed:
----- Method: Monitor>>initialize (in category 'initialize-release') -----
initialize
+ queuesMutex := Mutex new!
- queuesMutex := Semaphore forMutualExclusion!
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>>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"!
Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.783.mcz
==================== Summary ====================
Name: Collections-ul.783
Author: ul
Time: 5 March 2018, 10:52:44.810023 pm
UUID: 3cb7824b-9833-4ab9-bbac-66e36049b6ed
Ancestors: Collections-ul.782
WeakIdentityKeyDictionary changes:
- implemented #slowSize to be able to count of actually stored associations
- overridden #compact to cut tally back based on #slowSize
- compact the dictionary after removing unreferenced keys in #removeUnreferencedKeys
This all will ensure that if Undeclared is empty, then #isEmpty will return true after Smalltalk cleanOutUndeclared is executed.
=============== Diff against Collections-ul.782 ===============
Item was added:
+ ----- Method: WeakIdentityDictionary>>compact (in category 'private') -----
+ compact
+ "Reduce the size of array so that the load factor will be ~75%."
+
+ | newCapacity |
+ tally := self slowSize.
+ newCapacity := self class goodPrimeAtLeast: tally * 4 // 3.
+ self growTo: newCapacity!
Item was added:
+ ----- Method: WeakIdentityDictionary>>removeUnreferencedKeys (in category 'as yet unclassified') -----
+ removeUnreferencedKeys
+ "Make sure tally is set to the right size by #compact."
+
+ super removeUnreferencedKeys.
+ self compact!
Item was added:
+ ----- Method: WeakIdentityDictionary>>slowSize (in category 'accessing') -----
+ slowSize
+ "Careful!! Answer the maximum amount
+ of elements in the receiver, not the
+ exact amount"
+
+ | count |
+ count := 0.
+ 1 to: array size do: [ :index |
+ (array at: index) ifNotNil: [ :object |
+ object == vacuum ifFalse: [
+ count := count + 1 ] ] ].
+ ^count!
This sort of reminds me of the Swiki but using Json instead of XML. With the template information apart from the data. You night want to give the Swiki code a look. It has lots of ideas.
Chris
Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ul.1156.mcz
==================== Summary ====================
Name: Kernel-ul.1156
Author: ul
Time: 5 March 2018, 8:39:27.154484 pm
UUID: fd37b9ca-0eff-41f7-aa23-a46a2223d482
Ancestors: Kernel-eem.1155
Changed #isCompiledBlock to #isCompiledCode in some implementations of #hasLiteralSuchThat: to avoid DNUs when the literal is not an Array or a CompiledBlock (e.g. string).
Improved Integer >> #isPrime's performance in 64-bit images
=============== Diff against Kernel-eem.1155 ===============
Item was changed:
----- Method: CompiledBlock>>hasLiteralSuchThat: (in category 'literals') -----
hasLiteralSuchThat: litBlock
"Answer true if litBlock returns true for any literal in this method, even if embedded in array structure."
2 to: self numLiterals do:
[:index | | lit |
lit := self objectAt: index.
((litBlock value: lit)
+ or: [(lit isArray or: [lit isCompiledCode]) and: [lit hasLiteralSuchThat: litBlock]]) ifTrue:
- or: [(lit isArray or: [lit isCompiledBlock]) and: [lit hasLiteralSuchThat: litBlock]]) ifTrue:
[^true]].
^false!
Item was changed:
----- Method: CompiledMethod>>hasLiteralSuchThat: (in category 'literals') -----
hasLiteralSuchThat: litBlock
"Answer true if litBlock returns true for any literal in this method, even if embedded in array structure."
(self penultimateLiteral isMethodProperties
and: [self penultimateLiteral hasLiteralSuchThat: litBlock]) ifTrue:
[^true].
2 to: self numLiterals + 1 do:
[:index | | lit |
lit := self objectAt: index.
((litBlock value: lit)
+ or: [(lit isArray or: [lit isCompiledCode]) and: [lit hasLiteralSuchThat: litBlock]]) ifTrue:
- or: [(lit isArray or: [lit isCompiledBlock]) and: [lit hasLiteralSuchThat: litBlock]]) ifTrue:
[^true]].
^false!
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!
On Mar 5, 2018, at 4:00 AM, squeak-dev-request(a)lists.squeakfoundation.org wrote:
>>
>> Video: *https://youtu.be/ou9g1_eLszM <https://youtu.be/ou9g1_eLszM>*
>> (Taken right after running through the TileMap video myself)
>>
>> -CBC
>
> Well that's pretty cool stuff!
>
> Dave
Yes! Thanks Chris! Very cool!
Also, thanks David T Lewis for addressing my bug report!
I have been using Morphic more lately, encouraged by the cool things you folks have been doing with it.
Best,
Tim
Hi.
So, ever since I started actually using Morphic to build things with
drag/drop, I've wanted to build a little tool to turn those morphs back
into code/classes in Squeak. I started out working on that, but got
distracted (especially since I started hand-coding for each and every Morph
how to encode them - and I wasn't going to have the patience for that).
When Tm Jhnsn wrote that he wanted the same thing, I dusted off my old
approach, and made it work - mostly. If you look in
MCHttpRepository
location: 'http://www.squeaksource.com/morphToMethod'
user: 'cbc'
password: ''
and version 9, it should take most simple morphs and encode them. It can
also take some morphs from EToys and encode them as well, although I really
don't know enough about EToys to figure out how to trap the right pieces.
If you do this, please heed the warnings in the class! My first attempt at
the EToys with TileMap morph wound up bringing in the whole TileMaps -
morph and tiles both. At this point, it is more of a spike - is this a
useful direction to go, or not?
Video: *https://youtu.be/ou9g1_eLszM <https://youtu.be/ou9g1_eLszM>*
(Taken right after running through the TileMap video myself)
-CBC