Could you try the various DelayExperimentalXXXSchedulers?  Under
System > Settings > System > Delay Scheduler.

I believe there's a good chance one of them may fix also the problem.
I had planned to push one of these as the default in Pharo 5 but
hadn't decided which, got distracted and stretched a bit thin IRL. I
believe these experimental schedulers are better than the current
mutex based scheduler, since passing Delays from your normal-priority
process to the timing-priority delay scheduling process is a
signalling paradigm more than a shared memory paradigm.  I came to
this conclusion reading [2] which says...

"The correct use of a semaphore is for signalling from one task to
another. A mutex is meant to be taken and released, always in that
order, by [the same task using] the shared resource it protects. By
contrast, tasks that use semaphores either signal or wait—not both.
... Another important distinction between a mutex and a semaphore is
that the proper use of a mutex to protect a shared resource can have a
dangerous unintended side effect ... any two tasks that operate at
different priorities and coordinate via a mutex, create the
opportunity for priority inversion ... Fortunately ... semaphores ...
do not cause priority inversion when used for signalling."

A mutex makes   DelayXXXScheduler>>#schedule:   susceptible to
priority inversion since it is used by many processes at different
priority levels.  Using a signalling-semaphore might avoid the
problem.

The experimental delay schedulers were developed to address the
problem reported in the "super fast delay" [2], but there may also
have been a fix for that through another means.

[1] http://www.barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore
[2] http://forum.world.st/Super-fast-delay-td4787257.html

cheers -ben

On Fri, Nov 20, 2015 at 8:03 PM, Thierry Goubier
<thierry.goub...@gmail.com> wrote:
>
>
> 2015-11-20 12:46 GMT+01:00 Martin Dias <tinchod...@gmail.com>:
>>
>> 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.
>
>
> I believe this is a text book example of priority inversion.
>
> Kudo's for finding it!
>
> Thierry
>
>>
>>
>> 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 <maxle...@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-styleInBackgroundProcess-spawns-too-many-processes
>>>
>>> Cheers,
>>> Max
>>>
>>>
>>> > On 18 Nov 2015, at 19:02, Andreas Wacknitz <a.wackn...@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
>>>
>>>
>>
>

Reply via email to