<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">I have a (stupid) question.<div>Is the code running without the primitives?</div><div>Are the code below the primitives correct?</div><div>I asked that because we can have 100 eyes and brains on the smalltalk level and far less on the VM primitive level.</div><div><br></div><div>Stef</div><div><br></div><div><br></div><div><br><div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir="ltr">Hi Ben,<br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 7, 2016 at 10:39 AM, Ben Coman<span class="Apple-converted-space">&nbsp;</span><span dir="ltr">&lt;<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>&gt;</span>wrote:<br><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div class="HOEnZb"><div class="h5"><br>On Fri, Jan 8, 2016 at 1:20 AM, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt; wrote:<br>&gt;<br>&gt; and here's a version with a better class comment<br>&gt;<br>&gt; On Thu, Jan 7, 2016 at 9:12 AM, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt; wrote:<br>&gt;&gt;<br>&gt;&gt; Hi Denis, Hi Clément,&nbsp; Hi Frank,<br>&gt;&gt;<br>&gt;&gt; On Thu, Jan 7, 2016 at 5:34 AM, Clément Bera &lt;<a href="mailto:bera.clement@gmail.com">bera.clement@gmail.com</a>&gt; wrote:<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; Hello,<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; Eliot, please, you told me you had the code and Denis is interested.<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; It uses 3 primitives for performance.<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; Forgive the delay.&nbsp; I thought it proper to ask permission since the code was written while I was at Qwaq. I'm attaching the code in a fairly raw state, see the attached.&nbsp; The code is MIT, but copyright 3DICC.<br>&gt;&gt;<br>&gt;&gt; It is a plugin replacement for Squeak's Mutex, and with a little ingenuity could be a replacement for Squeak's Monitor.&nbsp; It is quicker because it uses three new primitives to manage entering a critical section and setting the owner, exiting the critical section and releasing the owner, and testing if a critical section, entering if the section is unowned.&nbsp; The use of the primitives means fewer block activations and ensure: blocks in entering and exiting the critical section, and that's the actual cause of the speed-up.<br>&gt;&gt;<br>&gt;&gt; You can benchmark the code as is.&nbsp; Here are some results on 32-bit Spur, on my 2.2GHz Core i7<br>&gt;&gt;<br>&gt;&gt; {Mutex new. Monitor new. CriticalSection new} collect:<br>&gt;&gt; [:cs| | n |<br>&gt;&gt; n := 0.<br>&gt;&gt; [cs critical: [n := n + 1]. cs critical: [n := n + 1]. cs critical: [n := n + 1]. cs critical: [n := n + 1]. cs critical: [n := n + 1].<br>&gt;&gt; cs critical: [n := n - 1]. cs critical: [n := n - 1]. cs critical: [n := n - 1]. cs critical: [n := n - 1]. cs critical: [n := n - 1].<br>&gt;&gt; n ] bench]<br>&gt;&gt;<br>&gt;&gt; {Mutex new. Monitor new. CriticalSection new} collect:<br>&gt;&gt; [:cs| | n |<br>&gt;&gt; n := 0.<br>&gt;&gt; cs class name, ' -&gt; ',<br>&gt;&gt; [cs critical: [n := n + 1]. cs critical: [n := n + 1]. cs critical: [n := n + 1]. cs critical: [n := n + 1]. cs critical: [n := n + 1].<br>&gt;&gt; cs critical: [n := n - 1]. cs critical: [n := n - 1]. cs critical: [n := n - 1]. cs critical: [n := n - 1]. cs critical: [n := n - 1].<br>&gt;&gt; n ] bench]<br>&gt;&gt;<br>&gt;&gt; #( 'Mutex -&gt; 440,000 per second. 2.27 microseconds per run.'<br>&gt;&gt; 'Monitor -&gt; 688,000 per second. 1.45 microseconds per run.'<br>&gt;&gt; 'CriticalSection -&gt; 1,110,000 per second. 900 nanoseconds per run.')<br>&gt;&gt;<br><br></div></div>This is great Eliot. Thank you and 3DICC.&nbsp; After loading the changeset<br>into Pharo-50515 (32 bit Spur) I get the following results on my<br>laptop i5-2520M @ 2.50GHz<br><br>#('Mutex -&gt; 254,047 per second'<br>&nbsp;'Monitor -&gt; 450,442 per second'<br>&nbsp;'CriticalSection -&gt; 683,393 per second')<br><br>In a fresh Image "Mutex allInstances basicInspect" lists just two mutexes...<br>1. NetNameResolver--&gt;ResolverMutex<br>2. ThreadSafeTranscript--&gt;accessSemaphore<br></blockquote><div><br></div><div>I hate myself for getting distracted but I'm finding this is un.&nbsp; One can migrate to the new representation using normal Monticello loads by</div><div><br></div><div>In the first version redefine Mutex and Monitor to subclass LinkedList and have their owner/ownerProcess inst var first (actually third after firstLink &amp; lastLink), and add the primitives.</div><div><br></div><div>In the next version check that all Mutex and Monitor instanes are unowned and then redefine to discard excess inst vars</div><div><br></div><div>Let me test this before committing, and see that all tests are ok.</div><div><br></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><br>cheers -ben<br><div class="HOEnZb"><div class="h5"><br>&gt;&gt; Replacement is probably trivial; rename Mutex to OldMutex, rename CriticalSection to Mutex, recompile.&nbsp; But there are lots of mutexes in the system and these are potentially owned.&nbsp; Transforming unowned ones is trivial, but transforming owned ones is, I think, impossible.&nbsp; But at least in my system there are no owned mutexes or monitors.<br>&gt;&gt;<br>&gt;&gt; Frank (or anyone else), would you be interested in creating a replacement for Squeak's Monitor based on CriticalSection?<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; Here are the two business methods:<br>&gt;&gt; CriticalSection methods for mutual exclusion<br>&gt;&gt; critical: aBlock<br>&gt;&gt; "Evaluate aBlock protected by the receiver."<br>&gt;&gt; ^self primitiveEnterCriticalSection<br>&gt;&gt; ifTrue: [aBlock value]<br>&gt;&gt; ifFalse: [aBlock ensure: [self primitiveExitCriticalSection]]<br>&gt;&gt;<br>&gt;&gt; critical: aBlock ifLocked: lockedBlock<br>&gt;&gt; "Answer the evaluation of aBlock protected by the receiver.&nbsp; If it is already in a critical<br>&gt;&gt; section on behalf of some other process answer the evaluation of lockedBlock."<br>&gt;&gt; ^self primitiveTestAndSetOwnershipOfCriticalSection<br>&gt;&gt; ifNil: [lockedBlock value]<br>&gt;&gt; ifNotNil:[:alreadyOwner|<br>&gt;&gt; alreadyOwner<br>&gt;&gt; ifTrue: [aBlock value]<br>&gt;&gt; ifFalse: [aBlock ensure: [self primitiveExitCriticalSection]]]<br>&gt;&gt;<br>&gt;&gt; and the primitives:<br>&gt;&gt; CriticalSection methods for private-primitives<br>&gt;&gt; primitiveEnterCriticalSection<br>&gt;&gt; "Primitive. The receiver must be unowned or owned by the current process to proceed.<br>&gt;&gt; Answer if the process is owned by the current process."<br>&gt;&gt; &lt;primitive: 186&gt;<br>&gt;&gt; self primitiveFailed<br>&gt;&gt; "In the spirit of the following"<br>&gt;&gt; "[owner ifNil:<br>&gt;&gt; [owner := Processor activeProcess.<br>&gt;&gt; ^false].<br>&gt;&gt;&nbsp; owner = Processor activeProcess ifTrue:<br>&gt;&gt; [^true].<br>&gt;&gt;&nbsp; self addLast: Processor activeProcess.<br>&gt;&gt;&nbsp; Processor activeProcess suspend] valueUnpreemptively"<br>&gt;&gt;<br>&gt;&gt; primitiveExitCriticalSection<br>&gt;&gt; "Primitive. Set te receiver to unowned and if any processes are waiting on<br>&gt;&gt; the receiver then proceed the first one, indicating that the receiver is unowned."<br>&gt;&gt; &lt;primitive: 185&gt;<br>&gt;&gt; self primitiveFailed<br>&gt;&gt; "In the spirit of the following"<br>&gt;&gt; "[owner := nil.<br>&gt;&gt;&nbsp; self isEmpty ifFalse:<br>&gt;&gt; [process := self removeFirst.<br>&gt;&gt; process resume]] valueUnpreemptively"<br>&gt;&gt;<br>&gt;&gt; primitiveTestAndSetOwnershipOfCriticalSection<br>&gt;&gt; "Primitive. Attempt to set the ownership of the receiver.<br>&gt;&gt; If the receiver is unowned set its owningProcess to the<br>&gt;&gt; activeProcess and answer false.&nbsp; If the receiver is owned<br>&gt;&gt; by the activeProcess answer true.&nbsp; If the receiver is owned<br>&gt;&gt; by some other process answer nil."<br>&gt;&gt; &lt;primitive: 187&gt;<br>&gt;&gt; self primitiveFail<br>&gt;&gt; "In the spirit of the following"<br>&gt;&gt; "[owner ifNil:<br>&gt;&gt; [owningProcess := Processor activeProcess.<br>&gt;&gt; ^false].<br>&gt;&gt;&nbsp; owner = Processor activeProcess ifTrue: [^true].<br>&gt;&gt;&nbsp; ^nil] valueUnpreemptively"<br>&gt;&gt;<br>&gt;&gt;&gt; 2016-01-07 13:24 GMT+01:00 Denis Kudriashov &lt;<a href="mailto:dionisiydk@gmail.com">dionisiydk@gmail.com</a>&gt;:<br>&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt; Hello.<br>&gt;&gt;&gt;&gt;<br>&gt;&gt;&gt;&gt; I hear about new Monitor implementation based on new primitives.<br>&gt;&gt;&gt;&gt; Where to get it?<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; _,,,^..^,,,_<br>&gt;&gt; best, Eliot<br>&gt;<br>&gt;<br>&gt;<br>&gt;<br>&gt; --<br>&gt; _,,,^..^,,,_<br>&gt; best, Eliot<br>&gt;<br></div></div></blockquote></div><br><br clear="all"><div><br></div>--<span class="Apple-converted-space">&nbsp;</span><br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size: small; border-collapse: separate;"><div>_,,,^..^,,,_<br></div><div>best,&nbsp;Eliot</div></span></div></div></div></div></div></div></blockquote></div><br></div></body></html>