On Fri, Mar 31, 2017 at 4:54 PM, Alistair Grant <akgrant0710@gmail.com> wrote:
On 31 March 2017 at 10:14, Alistair Grant <akgrant0710@gmail.com> wrote:
> Hi Eliot,
>
> On 31 March 2017 at 05:31, Eliot Miranda <eliot.miranda@gmail.com> wrote:
>>
>>
>> On Thu, Mar 30, 2017 at 8:20 PM, Eliot Miranda <eliot.miranda@gmail.com>
>> wrote:
>>>
>>> Hi Alistair,
>>>
>>> On Thu, Mar 30, 2017 at 9:32 AM, Alistair Grant <akgrant0710@gmail.com>
>>> wrote:
>>>>
>>>> Hi Eliot,
>>>>
>>>> On 30 March 2017 at 18:15, Eliot Miranda <eliot.miranda@gmail.com> wrote:
>>>> >
>>>> > On Mar 30, 2017, at 2:58 AM, Pavel Krivanek <pavel.krivanek@gmail.com>
>>>> > wrote:
>>>> >>
>>>> >> Yes, the same priority. See:
>>>> >>
>>>> >> The VM may have issues with clock jitter due to the heartbeat thread
>>>> >> not running at elevated priority.
>>>> >
>>>> >
>>>> > It better /not/ be.�� This is wrong.�� The heartbeat thread /must/ run at
>>>> > a
>>>> > higher priority for the VM not to lock up when it becomes compute
>>>> > bound.�� I
>>>> > thought the resolution was that the VM /will/ try and raise the
>>>> > priority if
>>>> > the heartbeat thread but will /not/ exit if it fails.�� This is /very/
>>>> > different from not trying to raise the priority at all.
>>>>
>>>> As Esteban wrote, the vm is trying to raise the priority.�� You can see
>>>> the change at:
>>>>
>>>>
>>>> https://github.com/pharo-project/pharo-vm/commit/32f321583c69ca27e61ffaff6decc2a3e4b6ca5e
>>>>
>>>> I'd like to just make sure I understand your comment correctly:
>>>>
>>>> Are you saying that the VM will lock up if it gets in to, e.g., an
>>>> endless loop, so that Ctrl-. fails to interrupt.�� Or is it more
>>>> serious than that?�� Can the VM become locked up for just a long
>>>> running process (I guess it will be locked while the process is
>>>> running, but will eventually go back to normal once the process
>>>> completes)?
>>>
>>>
>>> The issue is that delays are recognized by periodically checking the time
>>> against the next delay expiry.�� It is the heartbeat thread that causes JITed
>>> Smalltalk code to break out of its execution to check for events, including
>>> the next delay expiry.�� So if the heartbeat is at the same priority as the
>>> JITed Smalltalk code, and the Smalltalk code is in tight enough a loop (one
>>> that does not provoke a GC, does not do any process switches) the heartbeat
>>> thread will not run and the delay expiry will never be tested for.
>>
>>
>> Something like the following should run forever if the heartbeat has the
>> same priority as the VM thread (and should be tried in a headless
>> configuration too):
>>
>> [| infiniteLoop |
>> infiniteLoop := [| sum | sum := 0. [sum < 10] whileTrue: [sum := sum + (sum
>> even ifTrue: [1] ifFalse: [-1])]] newProcess.
>> infiniteLoop resume.
>> Processor activeProcess priority: Processor activePriority + 1.
>> (Delay forSeconds: 1) wait.
>> infiniteLoop terminate.
>> Processor activeProcess priority: Processor activePriority - 1] timeToRun
>> 1001
>
> I get the same result regardless of thread priority, UI or headless.
> I've just shown the output from the headless VM with the heartbeat
> thread at normal priority (I haven't incorporated Ben's comments in to
> the text yet):
>
>
> $ pharo Pharo.image --quit ~/pharo6/pharo/heartbeatTest.st
> pthread_setschedparam failed: Operation not permitted
> This VM uses a separate heartbeat thread to update the internal clock.
> For best operation, this thread should run at real-time priority,
> however the VM was unable to change the priority.�� The effect is that
> the clock may experience some jitter.�� To avoid clock jitter, please
> create the appropriate configuration file in /etc/security/limits.d
> by executing the following:
>
> cat <<END | sudo tee /etc/security/limits.d/pharo.conf
> *�� �� �� ��hard�� �� rtprio�� 2
> *�� �� �� ��soft�� �� rtprio�� 2
> END
>
> You will need to log out and log back in for the limits to take effect.
> For more information please see
> https://github.com/OpenSmalltalk/opensmalltalk-vm/releases/tag/r3732#linux
> Time to run: 0:00:00:01
>
>
> heartbeatTest.st:
>
> | time |
>
> time := [| infiniteLoop |
> infiniteLoop := [| sum | sum := 0. [sum < 10] whileTrue: [sum := sum +
> (sum even ifTrue: [1] ifFalse: [-1])]] newProcess.
> infiniteLoop resume.
> Processor activeProcess priority: Processor activePriority + 1.
> (Delay forSeconds: 1) wait.
> infiniteLoop terminate.
> Processor activeProcess priority: Processor activePriority - 1] timeToRun.
> FileStream stdout
> nextPutAll: 'Time to run: ';
> nextPutAll: time printString; cr.
> time

P.S It would be great is someone could reproduce this.�� Eliot and Ben's
descriptions make sense, so I can't help feeling I've done something
stupid here.


Eliot, thanks for the test case.

Using VM ��pharo-linux-i386threaded-201703281011 on an idle PC
with pharo UI �� I get timeToRun of "0:00:00:01.001".

From the command line...
$ vi heatbeatTestIdle.st
| time |
time := [ (Delay forSeconds: 1) wait ] timeToRun.
FileStream stdout
nextPutAll: 'Time to run: ';
nextPutAll: time printString; cr.

$ pharo-linux-i386threaded-201703281011/lib/pharo/5.0-201703281011/pharo \
�� �� ��60453.image �� `pwd`/heatbeatTestIdle.st��
Time to run: 0:00:00:01.002

$ pharo-linux-i386threaded-201703281011/lib/pharo/5.0-201703281011/pharo \
�� �� ��60453.image `pwd`/heatbeatTest.st��
Time to run: 0:00:00:01.001

Stressing the system per my test.c from [1] compiled to `fib`,��
on my four CPUs starting fifteen processes doing �� fibonnachi of��10E10 ��
spread across three process priorities 0, 1 & 19, ����
and then running ��heatbeatTest.st.

$ N=$((10**10)) ; for NPROC in 1 2 3 4 5 ; do (./fib 19 $N &) && (./fib 1 $N &) && (./fib 0 $N &) ; done && \
�� �� ��pharo-linux-i386threaded-201703281011/lib/pharo/5.0-201703281011/pharo \
�� �� �� ��60453.image `pwd`/heatbeatTest.st��
Time to run: 0:00:00:01.002
14758 @ 0 ==> execution time 23:341844995
14734 @ 0 ==> execution time 23:957766684
14746 @ 0 ==> execution time 24:425043841
14740 @ 0 ==> execution time 24:458788284
14752 @ 0 ==> execution time 24:899062965
14750 @ 1 ==> execution time 26:118315887
14732 @ 1 ==> execution time 26:302822374
14756 @ 1 ==> execution time 26:398550194
14738 @ 1 ==> execution time 26:605458137
14744 @ 1 ==> execution time 26:655449934
14736 @ 19 ==> execution time 36:799776693
14754 @ 19 ==> execution time 37:564087310
14742 @ 19 ==> execution time 39:511492537
14748 @ 19 ==> execution time 39:714399199
14730 @ 19 ==> execution time 39:748212349

Output format is... ����
PID @ nicePriority ==> execution time

After output completes, `cat /proc/loadavg`��
reports a 1 minute load average (i.e. average processes waiting) of��6.36.

So to me it looks like the un-raised *static* priority heatbeat-thread is working okay :)

cheers -ben

[1] http://forum.world.st/Unix-heartbeat-thread-vs-itimer-tp4928943p4938456.html