Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loop without consuming too many CPU cycles and without sleep()?

I am doing a VoIP program which continously checks whether the audio-recording buffer has anything in it (FMOD library, whenever the function getRecordPosition > 0, then the buffer has data in it).

So it would be something along the lines of:

while (true) {
    if(getRecordPosition>0) {
     process data....
    }
}

However this would cause a very high CPU usage. One version would be to use sleep() but I'd rather not use it if possible. For example the win32 messagehandling with its event-driven loop dosn't consume many cpu cycles and it's something I'm trying to emulate. At the same time I understand the function getRecordPosition() would have to be called frequently to see if the return value gets above 0.

Am I stuck with doing a while(true) loop and sleep() for some small amount of time in order to keep low-CPU usage?

I've googled and done some lookup but most returns either using sleep() or some POSIX synchronization with mutex. (I am doing a c++ win32 app)

Cheers

---EDIT: Forgot to mention I dont have access to fmod source corde :/ ---

like image 594
KaiserJohaan Avatar asked Jan 10 '11 16:01

KaiserJohaan


2 Answers

The best thing to do, if you can, is to not emulate an event-driven architecture as you say, but to actually use an event-driven architecture. I don't know anything about your code, in particular whether you're in control of the audio-recording buffer's code or not. But if you do control the code that writes to the buffer, then you can trigger an event when you have written to the buffer:

(psudocude follows)

Main Thread:

HANDLE buf_event = CreateEvent(...);
// ...
CreateThread(BufferControl, ...);

Buffer-Write Thread:

OnWriteToBuffer()
{
  buffer.Write(...);
  SetEvent(buf_event);
}

And then in the thread where you want to do something when there's data in the buffer waiting, wait for the event to be signaled:

Buffer-Read Thread

rc = WaitForSingleObject(buf_event, INFINITE);
if( rc == WAIT_OBJECT_0 )
{
  // there's somethign in the buffer
}
like image 85
John Dibling Avatar answered Sep 25 '22 16:09

John Dibling


You could use 'SwitchToThread' to yield the processor to another thread, and check the return value. If it is true, you yielded, and if not, there are no other threads that need running. If I remember correctly, FMOD runs a thread, so you would likely be yielding to that thread.

If it fails to yield or if it continues to use up a lot of CPU time, you could use some combination of yielding and sleeping.

like image 21
James Avatar answered Sep 22 '22 16:09

James