[squeak-dev] The broken user interrupt, or the saga of 100000 factorial.

Levente Uzonyi leves at elte.hu
Fri Jan 6 13:15:09 UTC 2012


On Fri, 6 Jan 2012, Bert Freudenberg wrote:

>
> On 23.12.2011, at 16:38, David T. Lewis wrote:
>
>> On Fri, Dec 23, 2011 at 10:13:18AM -0500, David T. Lewis wrote:
>>> On Fri, Dec 23, 2011 at 07:39:41AM -0500, Bob Arning wrote:
>>>> I've seen suspicious behavior (tough time interrupting and lots of
>>>> finalization in MessageTally reports) in my 4.2 image, so I thought I'd
>>>> look at applying this fix. One thing I'm a little puzzled about:
>>>> HasNewFinalization is false in my image (I'm using a Cog that's a few
>>>> months old). Under what conditions is it true?
>>>
>>> I think you have spotted a timing problem here. I put the initTestPair
>>> and checkTestPair calls together in a startUp: method, which is
>>> wrong because it does not give the VM an opportunity to do its
>>> updates, so the results of the test are not valid.
>>>
>>> This is not exactly elegant, but if you force a garbage collection
>>> between initTestPair and checkTestPair, the test will work properly.
>>>
>>> WeakArray class>>startUp: resuming
>>> 	resuming ifFalse: [ ^self ].
>>> 	"Check if new finalization is supported by the VM"
>>> 	WeakFinalizationList initTestPair.
>>> 	Smalltalk garbageCollect.
>>> 	WeakFinalizationList checkTestPair.
>>> 	self restartFinalizationProcess.
>>>
>>> A better fix is needed - sorry about that. I'm not sure if I'll
>>> have a chance to look at this today, but the important thing is
>>> to arrange for the check to be done when the image is started,
>>> but not to continue repeating the test after it has been
>>> successfully performed.
>>
>> The following seems to take care of the issue without requiring
>> anything to be done in the startUp: method.
>>
>>  WeakArray class>>finalizationProcess
>>    | initialized |
>>    initialized := false.
>>    [FinalizationSemaphore wait.
>>    initialized ifFalse: ["check VM capability once at image startup time"
>>      WeakFinalizationList initTestPair.
>>      Smalltalk garbageCollect.
>>      WeakFinalizationList checkTestPair.
>>      initialized := true].
>>    FinalizationLock critical:
>>      [FinalizationDependents do:
>>        [ :weakDependent |
>>        weakDependent ifNotNil:
>>          [weakDependent finalizeValues]]]
>>      ifError:
>>      [:msg :rcvr | rcvr error: msg]] repeat
>>
>> I'll update this in the inbox. Bob, thanks for catching the error.
>>
>> Dave
>
>
>
> Guess we should resume this discussion:
>
> This is in trunk now, but if I uncomment the workaround in #openInterrupt:onProcess: I still can't break into 100000 factorial.

Do you mean that it still interrupts the finalization process first?

>
> How to proceed?

I'd mark processes which shouldn't be interrupted by default. The easiest 
thing to do this is to store them in a WeakSet guarded by a Semaphore. 
Then define two different user interrupt methods:
- one that can interrupt all processes
- one that can interrupt all processes except for those, which are stored 
in that set.

This way we could prevent interrupting system processes (finalization, low 
space watcher, idle process, rfb session processes, etc) when a user 
process gets stuck.


Levente

>
> - Bert -
>
>
>
>



More information about the Squeak-dev mailing list