Great catch! Can something similar be also the reason SHTextStyler>>styleInBackgroundProcess: spawns zombie processes? Even with this fix script [1] blocks in testBenchFor. If I apply the fix proposed by ben in this thread or the slice for issue 17050 <https://pharo.fogbugz.com/f/cases/17050/SHTextStyler-styleInBackgroundProces...> then [1] does not block in testBenchFor. [1] ./pharo Pharo.image eval "CommandLineTestRunner runClasses: {GTInspectorExamplesTest} named: 'x'. CommandLineTestRunner runClasses: {BlockClosureTest} named: 'y'" On Fri, Nov 20, 2015 at 12:46 PM, Martin Dias <tinchodias@gmail.com> wrote:
Hi!
With Guille and Pablo this morning we found what is the problem and apparently fixed it. The problem is that there is a process in priority 10 that takes the delay lock (accessProtect semaphore) and go to sleep. Then the #benchFor: launches another process in priority 79 that tries to take the delay lock but, since it's taken by the other process, it goes to sleep. But the UI process is in priority 40 so it will always have priority over the one that has the lock. Consequence: the process in priority 10 has the delay lock and will never be awaken until the UI process gets suspended.
More in detail, the following method makes the assumption that once the delay process finishes the handling of the delay to schedule, it will return to same process. But that is not true if there is another process with more priority.
schedule: aDelay | scheduled | scheduled := false. aDelay schedulerBeingWaitedOn ifTrue: [^self error: 'This Delay has already been scheduled.']. accessProtect critical: [ scheduledDelay := aDelay. timingSemaphore signal. "#handleTimerEvent: sets scheduledDelay:=nil" scheduled := (scheduledDelay == nil). ]. ^scheduled.
Our solution is to run the critical section in a higher priority to ensure that always comes back to the same process to release the delay lock.
schedule: aDelay | scheduled | scheduled := false. aDelay schedulerBeingWaitedOn ifTrue: [ ^ self error: 'This Delay has already been scheduled.' ]. [ accessProtect critical: [ scheduledDelay := aDelay. timingSemaphore signal. "#handleTimerEvent: sets scheduledDelay:=nil" scheduled := scheduledDelay == nil ]. ^ scheduled ] valueAt: Processor timingPriority - 1
Also, to not have interference with the benchmarking process we reduce the priority of the process used in benchFor:
benchFor: duration "Run me for duration and return a BenchmarkResult" "[ 100 factorial ] benchFor: 2 seconds" | count run started | count := 0. run := true. [ duration wait. run := false ] forkAt: Processor timingPriority *- 2*. started := Time millisecondClockValue. [ run ] whileTrue: [ self value. count := count + 1 ]. ^ BenchmarkResult new iterations: count; elapsedTime: (Time millisecondsSince: started) milliSeconds; yourself
We will create an entry in fogbugz and submit the change.
Regards, Martin, Guille and Pablo
On Wed, Nov 18, 2015 at 8:33 PM, Max Leske <maxleske@gmail.com> wrote:
I went ahead and implemented a simple fix for the styler. Not sure how well it performs but in my simple experiments it seems to work fine. Please test it and let me know what you think.
https://pharo.fogbugz.com/f/cases/17050/SHTextStyler-styleInBackgroundProces...
Cheers, Max
On 18 Nov 2015, at 19:02, Andreas Wacknitz <A.Wacknitz@gmx.de> wrote:
Am 18.11.15 um 11:48 schrieb Andrei Chis:
Can you try the script below in the latest Pharo image and let me know how much does it take to execute on your machine:
|duration benchmarkResult| 100 timesRepeat: [ RubScrolledTextMorph new model: (RubScrolledTextModel new setInitialText: '1+1'; yourself); beForSmalltalkScripting; yourself ] .
duration := 100 milliSeconds. benchmarkResult := [ 100 factorial ] benchFor: duration.
In my case it takes around 1 minute. The inner loop finishes immediately and then most time is spend executing the benchmark.
At the end I get the following result: "a BenchmarkResult(2,060,386 iterations in 1 minute 7 seconds 498 milliseconds. 30,525 per second)"
So the benchmark is executed for over one minute before the delay expires.
"a BenchmarkResult(1,263,573 iterations in 37 seconds 689 milliseconds. 33,526 per second)" (HP Z420 with Xeon E5-1620 under OpenIndiana).
Regards Andreas