part-cw / lambdanative

LambdaNative is a cross-platform development environment written in Scheme, supporting Android, iOS, BlackBerry 10, OS X, Linux, Windows, OpenBSD, NetBSD, FreeBSD and OpenWrt.
http://www.lambdanative.org
Other
1.39k stars 86 forks source link

thread-sleep! on (my) Android: takes between 15 and 33 ms _itself_ #232

Open recumbentbirder opened 5 years ago

recumbentbirder commented 5 years ago

I try to time space sampling from the accelerometer, at the moment on Android. To get a sampling rate of 50 Hz, I need a sleep of +/- 0.02 ms (depending on data fetching from the accelerometer, but that is fast).

I now found, that the call to thread-sleep! itself takes between 15 and 33 ms, even for very small values of the parameter:

(time (thread-sleep! 0.000000000000001))

Not so, though, for (thread-sleep! 0, which probably just returns immediately.

Is there an alternative to thread-sleep! or some hint on how to get a reliable sleep for small values?

mgorges commented 5 years ago

To get this correct in Android is probably quite tricky due to the moving between C and Java, thus I am not surprised by your observation. If you look at the same for a desktop platform, which natively runs C-compiled code, you should be able to do much smaller periods.

  1. I am wondering, if in this case your sleeping would need to be done on the Java side, akin to the piece following loaders/android/bootstrap.java.in#L78 and loaders/android/bootstrap.java.in#L116, which specified the interval?
  2. Next, we do also disable the heartbeat in Scheme, as it causes crashes in some cases. The code for this is at languages/scm.c#L34. It might be interesting for you to look at re-enabling it for your purposes?
  3. Furthermore, I am wondering if your performance goal can actually not be met in software, but you would need to use an external hardware piece, given that Android itself is not really a realtime application?
  4. Finally, this might be something better to ask on the Gambit mailing list, see the Gambit Wiki and Github issue tracker
recumbentbirder commented 5 years ago

Thanks so far! Will look into it.

For now, I use this:

(define (wait msec)
  (do ((t (current-milliseconds)))
    ((>= (current-milliseconds) (+ t msec)))                                 
    ))

Which isn't a work of beauty because of CPU load. But does what it's supposed to.

mgorges commented 5 years ago

I can't think of anything else to suggest at the moment, but if I do I'll let you know. Similarly, if you could share any better ideas you come across this would be appreciated!