[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-panel-devel
Subject:    Re: Threading in Plasma applets
From:       "Richard Dale" <richard.j.dale () gmail ! com>
Date:       2008-04-07 10:23:17
Message-ID: 491684420804070323n11d1adb1r2aed934e34dfce46 () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


2008/2/19 Sebastian Sauer <mail@dipe.org>:

> On Tuesday 19 February 2008, Aaron J. Seigo wrote:
> > On Tuesday 19 February 2008, Richard Dale wrote:
> > > were having problems too, which makes me think it might be some sort
> > > of Ruby problem, rather than a QtRuby specific problem. Is that
> > > possible?
> >
> > could be.. and yes, the kross based ScripEngines were dieing badly in
> > threading related deaths while the same engines when running python
> scripts
> > work fine.
>
> well, threading should work. The reason why it was failing, is that there
> is
> still a bit of testingcode within krossruby that doesn't seem to be
> thread-safe (yet). Someone is able to work around this by removing the
> #define KROSS_RUBY_EXPLICIT_GC
> in kdebindings/ruby/krossruby/rubyconfig.h (should also increase the speed
> a
> lot, that code does run the garbage collector at each possible step to
> discover problems faster, but seems the gc is not very thread-friendly ;)
>
> @richard; normaly it should be enough to;
> const int critical = rb_thread_critical;
> rb_thread_critical = Qtrue;
> e.g. rb_funcall() ... (and while on that code, it may also an idea to wrap
> rb_funcall's into rb_rescue2's to catch exceptions and prevent
> rb_bug's/crashes and, not sure if that's really needed, to ruby_in_eval++
> and
> ruby_in_eval-- to prevent infinite loop's)
> rb_thread_critical = critical;
>
> Anyway. I still try to get the
> playground/base/plasma/scriptengines/kross/examples/example_ruby_runner
> working, but seems it still fails somehow. So, I am not able to test it
> aka
> look if there are probably more bugs related to threading :-/
>
> Attached is the patch I applied. I guess atm the problem is, that the
> match+exec methods in kdebase/libs/plasma/scripting/runnerscript.h arn't
> virtual any longer. So, somehow I miss how it needs to be changed to work
> again :-/

The patch didn't actually have the rb_thread_critical change, but I got
enough from your description above to try it out. I also added rb_protect()
to the virtual method callbacks and slot invocations in qtruby. If there was
an error I used rb_backtrace() to print where the ruby runtime failed.

I couldn't see that rb_thread_critical made any difference for me, however
I  have found what the problem is for qtruby/plasma - it keeps running out
of stack and throwing sysstack_error exceptions. It might be that
rb_thread_critical makes ruby only run in one thread which would minimise
stack use perhaps.

I added some diagnostics to my version of ruby in gc.c:

#define CHECK_STACK(ret) do {\
    SET_STACK_END;\
    (ret) = (STACK_LENGTH > STACK_LEVEL_MAX + GC_WATER_MARK);\
    printf("CHECK_STACK ret: %d STACK_LENGTH: %d > STACK_LEVEL_MAX: %u +
GC_WATER_MARK: %d\n", \
            ret, STACK_LENGTH, STACK_LEVEL_MAX, GC_WATER_MARK); \
} while (0)

So that it prints out the numbers everytime it does a stack check. The
output from Plasma when running the Ruby clock looks like this:

..
CHECK_STACK ret: 0 STACK_LENGTH: 4120 > STACK_LEVEL_MAX: 15987856d +
GC_WATER_MARK: 512
1117CHECK_STACK ret: 0 STACK_LENGTH: 2384 > STACK_LEVEL_MAX: 15987856 +
GC_WATER_MARK: 512
0CHECK_STACK ret: 1 STACK_LENGTH: -236 > STACK_LEVEL_MAX: 15987856 +
GC_WATER_MARK: 512
stack_check() raising a sysstack_error
        from clock.rb

Most of the time the stack length is 2500-4000 (not sure what the units
are), but every now and then it goes negative and Ruby throws an exception.
I tried the ruby cannon game tutorial t14 and its STACK_LENGTH numbers were
about 1500 higher and they never went negative.

ruby t14.rb |
> grep STACK_LENGTH |
>  awk 'BEGIN { min = 99999 }  \
> { total_stack_length += $5 ; if ($5 < min)  min = $5 } \
> END { print total_stack_length / NR ; print min }'
4239.56
1400

mardigras rdale 586% cat plasma.log |
> grep STACK_LENGTH |
>  awk 'BEGIN { min = 99999 }  \
> { total_stack_length += $5 ; if ($5 < min)  min = $5 } \
> END { print total_stack_length / NR ; print min }'
2494.53
-236

I tried a setrlimit to change the stack size in the initialization of the
ruby plugin:

struct rlimit rlim;
rlim.rlim_cur = 65000000;
int status = setrlimit(RLIMIT_STACK, &rlim);

Although it made the STACK_LEVEL_MAX figure bigger (15987856 in the above
example), it didn't make any difference. I wonder if Ruby is getting the
stack direction wrong, I've no idea - so I'll do a bit of googling and
investigate further.

-- Richard

[Attachment #5 (text/html)]

<br><br><div class="gmail_quote">2008/2/19 Sebastian Sauer &lt;<a \
href="mailto:mail@dipe.org">mail@dipe.org</a>&gt;:<br><blockquote class="gmail_quote" \
style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: \
1ex;"> <div class="Ih2E3d">On Tuesday 19 February 2008, Aaron J. Seigo wrote:<br>
&gt; On Tuesday 19 February 2008, Richard Dale wrote:<br>
&gt; &gt; were having problems too, which makes me think it might be some sort<br>
&gt; &gt; of Ruby problem, rather than a QtRuby specific problem. Is that<br>
&gt; &gt; possible?<br>
&gt;<br>
&gt; could be.. and yes, the kross based ScripEngines were dieing badly in<br>
&gt; threading related deaths while the same engines when running python scripts<br>
&gt; work fine.<br>
<br>
</div>well, threading should work. The reason why it was failing, is that there is<br>
still a bit of testingcode within krossruby that doesn&#39;t seem to be<br>
thread-safe (yet). Someone is able to work around this by removing the<br>
#define KROSS_RUBY_EXPLICIT_GC<br>
in kdebindings/ruby/krossruby/rubyconfig.h (should also increase the speed a<br>
lot, that code does run the garbage collector at each possible step to<br>
discover problems faster, but seems the gc is not very thread-friendly ;)<br>
<br>
@richard; normaly it should be enough to;<br>
const int critical = rb_thread_critical;<br>
rb_thread_critical = Qtrue;<br>
e.g. rb_funcall() ... (and while on that code, it may also an idea to wrap<br>
rb_funcall&#39;s into rb_rescue2&#39;s to catch exceptions and prevent<br>
rb_bug&#39;s/crashes and, not sure if that&#39;s really needed, to ruby_in_eval++ and<br>
ruby_in_eval-- to prevent infinite loop&#39;s)<br>
rb_thread_critical = critical;<br>
<br>
Anyway. I still try to get the<br>
playground/base/plasma/scriptengines/kross/examples/example_ruby_runner<br>
working, but seems it still fails somehow. So, I am not able to test it aka<br>
look if there are probably more bugs related to threading :-/<br>
<br>
Attached is the patch I applied. I guess atm the problem is, that the<br>
match+exec methods in kdebase/libs/plasma/scripting/runnerscript.h arn&#39;t<br>
virtual any longer. So, somehow I miss how it needs to be changed to work<br>
again :-/</blockquote><div>The patch didn&#39;t actually have the rb_thread_critical change, \
but I got enough from your description above to try it out. I also added rb_protect() to the \
virtual method callbacks and slot invocations in qtruby. If there was an error I used \
rb_backtrace() to print where the ruby runtime failed.<br> <br>I couldn&#39;t see that \
rb_thread_critical made any difference for me, however I&nbsp; have found what the problem is \
for qtruby/plasma - it keeps running out of stack and throwing sysstack_error exceptions. It \
might be that rb_thread_critical makes ruby only run in one thread which would minimise stack \
use perhaps.<br> <br>I added some diagnostics to my version of ruby in gc.c:<br><br>#define \
CHECK_STACK(ret) do {\<br>&nbsp;&nbsp;&nbsp; SET_STACK_END;\<br>&nbsp;&nbsp;&nbsp; (ret) = \
(STACK_LENGTH &gt; STACK_LEVEL_MAX + GC_WATER_MARK);\<br>&nbsp;&nbsp;&nbsp; \
printf(&quot;CHECK_STACK ret: %d STACK_LENGTH: %d &gt; STACK_LEVEL_MAX: %u + GC_WATER_MARK: \
%d\n&quot;, \<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret, \
STACK_LENGTH, STACK_LEVEL_MAX, GC_WATER_MARK); \<br>} while (0)<br><br>So that it prints out \
the numbers everytime it does a stack check. The output from Plasma when running the Ruby clock \
looks like this:<br> <br>..<br>CHECK_STACK ret: 0 STACK_LENGTH: 4120 &gt; STACK_LEVEL_MAX: \
15987856d + GC_WATER_MARK: 512<br>1117CHECK_STACK ret: 0 STACK_LENGTH: 2384 &gt; \
STACK_LEVEL_MAX: 15987856 + GC_WATER_MARK: 512<br>0CHECK_STACK ret: 1 STACK_LENGTH: -236 &gt; \
STACK_LEVEL_MAX: 15987856 + GC_WATER_MARK: 512<br> stack_check() raising a \
sysstack_error<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from clock.rb<br><br>Most of the \
time the stack length is 2500-4000 (not sure what the units are), but every now and then it \
goes negative and Ruby throws an exception. I tried the ruby cannon game tutorial t14 and its \
STACK_LENGTH numbers were about 1500 higher and they never went negative.<br> <br>ruby t14.rb \
|<br>&gt; grep STACK_LENGTH |<br>&gt;&nbsp; awk &#39;BEGIN { min = 99999 }&nbsp; \<br>&gt; { \
total_stack_length += $5 ; if ($5 &lt; min)&nbsp; min = $5 } \<br>&gt; END { print \
total_stack_length / NR ; print min }&#39;<br> 4239.56<br>1400<br><br>mardigras rdale 586% cat \
plasma.log |<br>&gt; grep STACK_LENGTH |<br>&gt;&nbsp; awk &#39;BEGIN { min = 99999 }&nbsp; \
\<br>&gt; { total_stack_length += $5 ; if ($5 &lt; min)&nbsp; min = $5 } \<br>&gt; END { print \
total_stack_length / NR ; print min }&#39;<br> 2494.53<br>-236<br><br>I tried a setrlimit to \
change the stack size in the initialization of the ruby plugin:<br><br>struct rlimit \
rlim;<br>rlim.rlim_cur = 65000000;<br>int status = setrlimit(RLIMIT_STACK, &amp;rlim);<br> \
<br>Although it made the STACK_LEVEL_MAX figure bigger (15987856 in the above example), it \
didn&#39;t make any difference. I wonder if Ruby is getting the stack direction wrong, I&#39;ve \
no idea - so I&#39;ll do a bit of googling and investigate further.<br> <br>-- \
Richard<br><br></div></div><br>



_______________________________________________
Panel-devel mailing list
Panel-devel@kde.org
https://mail.kde.org/mailman/listinfo/panel-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic