nanosleep() alternative?


7 posts
by devon » Sat Jul 07, 2012 1:32 am
I've recently received my Pi, and I've begun working on a test c++ OpenGL ES program. I have a thread for simulation updates, however my current options are to have it run at full speed 50,000+ times/sec, pushing system load to 100%, or to use nanosleep() which seems to only implement down to 10ms, giving me 100 times/sec, which is better than the 60 times/sec I was getting on the main thread with rendering, but not as often as I would like (in order to save myself the work of implementing robust collision detection.)

Ideas?
Posts: 5
Joined: Wed Jun 13, 2012 4:43 pm
by dom » Sat Jul 07, 2012 11:15 am
Last time I tested usleep could sleep with microsecond resolution.
Does the code here work:
viewtopic.php?f=68&t=8067&p=96770
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4064
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by devon » Sat Jul 07, 2012 2:50 pm
Like nanosleep(), usleep() guarantees it won't return before its specified duration, but makes no promises about how soon after it will return. Unfortunately it behaves with the same 10ms resolution.
Posts: 5
Joined: Wed Jun 13, 2012 4:43 pm
by dom » Sat Jul 07, 2012 3:15 pm
I don't agree. I've just run the code I linked to.

./a.out 1000000
Elapsed 1000117

usleeps for 1000000 useconds. There's 117us of overhead in the sleep.

./a.out 1000100
Elapsed 1000214

So, I've asked for a sleep that is 100us longer, and I get it. If there was a 10ms resolution problem, I would have got 1010114.

Can you run "uname -a"?
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4064
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge
by jojopi » Sat Jul 07, 2012 4:16 pm
devon wrote:Like nanosleep(), usleep() guarantees it won't return before its specified duration, but makes no promises about how soon after it will return. Unfortunately it behaves with the same 10ms resolution.
Traditionally this was true. Except for nanosleeps of less than 2ms in a process with real-time scheduling priority (which were implemented as busy-waits) all sleeps had a resolution of 1/HZ.

However, the current Pi kernel binaries have CONFIG_HIGH_RES_TIMERS=y, so as long as there is nothing else fighting for CPU, nanosleep should return very soon after the exact time you ask for.
User avatar
Posts: 2122
Joined: Tue Oct 11, 2011 8:38 pm
by devon » Sat Jul 07, 2012 4:25 pm
I actually just finished a pacman -Syyu (Took a while, I had an older archlinux distro) and it seems to have a new kernel configured with CONFIG_HIGH_RES_TIMERS=y as you mention, so my 1ms nanosleep now looks to be giving my cpu a break, while maintaining several hundred simulation loops / second.

Thanks for the suggestions everybody!
Posts: 5
Joined: Wed Jun 13, 2012 4:43 pm
by Grumpy Mike » Sat Jul 07, 2012 5:20 pm
You can use the Timer (ARM side) on page 196 of the data sheet. This gives you access to a 32 bit free running counter. By setting the divide value to 249 (in the control register) this then runs at a rate of 1MHz. This will allow you to make a delay function that works down to the micro second. Note due to other interrupts this will not return until at least the set time has elapsed but might return some time later.
User avatar
Posts: 791
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)