From: Ian Main Date: 2000-02-23T13:42:21-08:00 Subject: [ruby-talk:01550] Re: Ruby/GTK and the mainloop On Wed, Feb 23, 2000 at 02:56:10AM -0500, Yasushi Shoji wrote: > Hello Ian, > > sorry for the late post. I'm not the expert of Ruby, Gtk+, nor > threads, but was interested in this topic. Well, I thank you for responding. I was thinking no one was interested ;) > From: Ian Main > Subject: [ruby-talk:01508] Ruby/GTK and the mainloop > Date: Fri, 18 Feb 2000 23:19:56 -0800 > > > Now, this doesn't cause too huge of problems, but I did notice the > > sluggish redraw gtk had when run from ruby (because it only gets control > > to redraw every 100ms). It also makes the applications consume a small > > amount of CPU when idle. > > > > If I were to embed ruby into entity, it would also cause IO handlers to be > > called with a 100ms delay. I realize this could be made into a smaller > > amount (and indeed this is what I did with the Ruby/GTK to make it "feel" > > faster), but this causes more idle CPU usage.. not a big deal on my machine, > > but the actual amount will vary depending on the platform. > > I thought 100ms was the best we could get. > > the problem we had was that, as the source code shows, > > #if 1 > gtk_idle_add((GtkFunction)idle, 0); > #else > /* use timeout to avoid busy wait */ > gtk_timeout_add(100, (GtkFunction)idle, 0); > #endif Yes, what I did was change the idle () function: static gint idle() { struct timeval wait; wait.tv_sec = 0; wait.tv_usec = 1000; /* 100ms */ CHECK_INTS; if (!rb_thread_critical) rb_thread_wait_for(wait); return Qtrue; } If I am correct, what ends up happening in rb_thread_wait_for (), is that it calls thread_schedule with a timeout of (in this case) 100ms. If there are no other active threads, it sits in select for 100ms, and then returns to give gtk a chance to run. Changing the above to 10ms, means that gtk gets control back faster (so long as no other ruby threads are running). > using gtk_timeout_add turns into busy wait and it consumes most of the > cpu time by itself. That was why we, or I should say Masaki > Fukushima, fukusima@goto.info.waseda.ac.jp, changed it to idle_add in > ruby-list:16691. > > the problem, ruby keeps scheduling at least 100ms once it gets, was > already known at the time. He, Masaki Fukushima, also suggested using > only one select but both Ruby and Gtk+ has a chance to wait on I/O, so > he said it's difficult, if not impossible, to do it with current Ruby > and Gtk+. Yeah, it is impossible with the current ruby and gtk, because they both expect to have control over the main loop. What I would propose, is to allow ruby to hook into other mainloops (essentially hook into their select()). Note that this applies not just to gtk, but any other application or toolkit that expects main loop control. GTK has good facilities for this.. from looking through ruby source code again, it looks like ruby needs only: * The ablity watch file descriptors for read/write readiness. * A timeout for sleep() and similar functions. What we can do is extrapolate that in the ruby core, so that when ruby needs these facilities, it calls a specific function in ruby. We then set it up so that in the end these use function pointers, defaulting to the native ruby versions. A function in ruby could then allow us to override these functions inside ruby, and in the case of the gtk bindings, they would provide ruby-compatible wrappers around gdk_input_add (), and gtk_timeout_add (). This will then provide us with a single point of control (inside gtk), and everyone would be happy. The one thing to note on this, is that, in the case of gtk, the call to setup the new select handlers in ruby would have to be called after you call gtk_init(), but this should be fine. Hopefully I am not missing any issues here.. if someone knows something I don't please let me know! :) > > So the point of all this, is that I'm wondering if you would be interested > > in implementing a similar thing in Ruby ? I would be willing to help in any > > way possible, including an attempt at supplying patches if this is what it > > will take. > > I'd like to see if you already have a patch for this one. I don't > think there is any problem to include your patch if it works. I don't have one yet.. I'm busy rewriting parts of entity.. once that's done I'm going to embed ruby, and at that point I'll look into fixing this up. > ps. is that why text widget seems slower on Ruby/Gtk than native Gtk+? Yes, that's exactly why. GTK is only getting a chance to refresh the screen every 100ms, which is noticible when scrolling, or typing etc. The other thing that might be nice is the ability to control the length of the context switches at runtime.. dunno how plausable that is though... Thanks, Ian