[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 <<a \
href="mailto:mail@dipe.org">mail@dipe.org</a>>:<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>
> On Tuesday 19 February 2008, Richard Dale wrote:<br>
> > were having problems too, which makes me think it might be some sort<br>
> > of Ruby problem, rather than a QtRuby specific problem. Is that<br>
> > possible?<br>
><br>
> could be.. and yes, the kross based ScripEngines were dieing badly in<br>
> threading related deaths while the same engines when running python scripts<br>
> 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'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's into rb_rescue2's to catch exceptions and prevent<br>
rb_bug's/crashes and, not sure if that's really needed, to ruby_in_eval++ and<br>
ruby_in_eval-- to prevent infinite loop'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't<br>
virtual any longer. So, somehow I miss how it needs to be changed to work<br>
again :-/</blockquote><div>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.<br> <br>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.<br> <br>I added some diagnostics to my version of ruby in gc.c:<br><br>#define \
CHECK_STACK(ret) do {\<br> SET_STACK_END;\<br> (ret) = \
(STACK_LENGTH > STACK_LEVEL_MAX + GC_WATER_MARK);\<br> \
printf("CHECK_STACK ret: %d STACK_LENGTH: %d > STACK_LEVEL_MAX: %u + GC_WATER_MARK: \
%d\n", \<br> 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 > STACK_LEVEL_MAX: \
15987856d + GC_WATER_MARK: 512<br>1117CHECK_STACK ret: 0 STACK_LENGTH: 2384 > \
STACK_LEVEL_MAX: 15987856 + GC_WATER_MARK: 512<br>0CHECK_STACK ret: 1 STACK_LENGTH: -236 > \
STACK_LEVEL_MAX: 15987856 + GC_WATER_MARK: 512<br> stack_check() raising a \
sysstack_error<br> 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>> grep STACK_LENGTH |<br>> awk 'BEGIN { min = 99999 } \<br>> { \
total_stack_length += $5 ; if ($5 < min) min = $5 } \<br>> END { print \
total_stack_length / NR ; print min }'<br> 4239.56<br>1400<br><br>mardigras rdale 586% cat \
plasma.log |<br>> grep STACK_LENGTH |<br>> awk 'BEGIN { min = 99999 } \
\<br>> { total_stack_length += $5 ; if ($5 < min) min = $5 } \<br>> END { print \
total_stack_length / NR ; print min }'<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, &rlim);<br> \
<br>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.<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