Opened 15 years ago

Closed 4 months ago

#4576 closed enhancement (fixed)

BMessageRunner granularity is too high

Reported by: joeyadams Owned by: nobody
Priority: normal Milestone: Unscheduled
Component: Kits/Application Kit Version:
Keywords: Cc: e.ahlback@…, mdisreali@…
Blocked By: Blocking:
Platform: All

Description

While porting a game of mine to Haiku, I reached a point where I needed a periodic timer to update the game state at roughly 60 frames per second. The closest things I could find to this in the API were Pulse() and BMessageRunner. Though these do send messages periodically, they have a granularity limit of around 10 intervals per second. I then looked in the Media kit and BTimeSource, and was confused quite quickly. Lastly, I asked on the mailing list how to do what I want, and the solution I arrived at was to implement it manually using threads, semaphores, and callbacks.

Other GUI toolkits I've seen have Timers which can be set to periodically send messages at arbitrary rates. I believe the Haiku API should also have this feature, most likely in the form of a BTimer.

To this end, I have attached a working draft and example for a BTimer system. It provides a convenient interface for scheduling messages and callbacks to run at periodic intervals. It would be nice to see it included in the Haiku API, most likely in the Support kit. However, it would need to be reviewed by more experienced eyes.

Attachments (8)

btimer.tar.bz2 (4.7 KB ) - added by joeyadams 15 years ago.
First draft implementation of a BTimer API
TimerTest (BMessageRunner).log (127.0 KB ) - added by X512 4 years ago.
Benchmark result for BMessageRunner, X: delay, Y: error, units: seconds
TimerTest (snooze_until, 1 thread).log (127.0 KB ) - added by X512 4 years ago.
Benchmark result for snooze_until, single thread.
TimerTest.png (70.3 KB ) - added by X512 4 years ago.
Scatter plot,red: BMessageRunner, blue: snooze_until (single thread)
TimerTest (BMessageRunner).cpp (1.5 KB ) - added by X512 4 years ago.
TimerTest (snooze_until, 1 thread).cpp (1.1 KB ) - added by X512 4 years ago.
TimerTest8Threads.png (70.6 KB ) - added by X512 3 years ago.
X: requested delay, Y: difference between requested and actual delay. Red: 8 test threads, blue: 1 thread.
TimerTest16Vs32Threads.png (160.1 KB ) - added by X512 3 years ago.

Download all attachments as: .zip

Change History (20)

by joeyadams, 15 years ago

Attachment: btimer.tar.bz2 added

First draft implementation of a BTimer API

comment:1 by axeld, 14 years ago

Component: KitsKits/Application Kit
Milestone: R1Unscheduled
Owner: changed from axeld to nobody
Version: R1/alpha1

comment:2 by eml, 14 years ago

I'm not a dev, but I had a quick look at the patch anyways. Seems to me that the implementation does what it should do, however I think you should review the coding guidelines: Haiku Coding Guidelines

Some examples of 'violations' include member variable names and that a functions return type should be on its own line before the actual declaration. Generally header files use the extension '.h', not '.hpp'. I would suggest putting the public interface first in your class definition as that is the general way it's done throughout the Haiku source code from what I gather. Even though this is a first draft as you say, I would suggest that you write your functions in source files and not in header files.

comment:3 by eml, 14 years ago

Cc: e.ahlback@… added

comment:4 by stippi, 14 years ago

patch: 01

comment:5 by stippi, 14 years ago

In the current form, the patch provides these adventages over BMessageRunner:

  • Finer granularity,
  • With the callback version, one does not need a BHandler/BLooper as the target for the timer events.

Recently, we've been discussing a possibility how the first problem could be fixed for BMessageRunner while significantly reducing the overhead (no extra thread). Not introducing another API is of course more elegant. It would not offer the callback feature, but perhaps this one is tricky anyway, since the callback is called in the timer thread. Application developers may not be expecting this, since it's not what happens in other frameworks like Qt or Gtk.

As for the code of the patch, it indeed does not follow the coding style, but it also has too little error checking for my taste. For example the indication of the running of the timer and quitting of the thread is error prone. Instead of checking the running variable, it could instead check an error from acquiring the semaphore. Then the master thread could destroy the semaphore and then also wait for the timer thread to exit, which is another problem of the patch. I also think the BTimerList should be internal.

comment:6 by nielx, 12 years ago

patch: 10

comment:7 by nielx, 12 years ago

Obsoleted patch because of reviews. See comment:2 and comment:5.

Feel free to attach an updated version.

comment:8 by Disreali, 12 years ago

Cc: mdisreali@… added

comment:9 by pulkomandy, 4 years ago

Summary: There should be a BTimerBMessageRunner granularity is too high

by X512, 4 years ago

Benchmark result for BMessageRunner, X: delay, Y: error, units: seconds

by X512, 4 years ago

Benchmark result for snooze_until, single thread.

by X512, 4 years ago

Attachment: TimerTest.png added

Scatter plot,red: BMessageRunner, blue: snooze_until (single thread)

comment:10 by X512, 4 years ago

I attached results of some tests when https://review.haiku-os.org/c/haiku/+/2888 is applied.

BMessageRunner:

Average: 4.58E-05
Std dev: 1.33567E-05
Min: 2.00E-05

snooze_until (single thread):

Average: 1.11E-05
Std dev: 9.7624E-06
Min: 2.00E-06
Last edited 4 years ago by X512 (previous) (diff)

by X512, 4 years ago

comment:11 by axeld, 4 years ago

Thanks! Have you looked into how these numbers change if there are more users of the API? As a simple test one could just run multiple instances of those tests at the same time, also both of them.

Besides this, I'm too dumb to read the exponential notation ;-)

by X512, 3 years ago

Attachment: TimerTest8Threads.png added

X: requested delay, Y: difference between requested and actual delay. Red: 8 test threads, blue: 1 thread.

by X512, 3 years ago

Attachment: TimerTest16Vs32Threads.png added

comment:12 by tqh, 4 months ago

Resolution: fixed
Status: newclosed

The granularity has now been reduced a lot in hrev57498, so considering this fixed.

Note: See TracTickets for help on using tickets.