diff options
Diffstat (limited to 'ringbuffer.c')
-rw-r--r-- | ringbuffer.c | 95 |
1 files changed, 22 insertions, 73 deletions
diff --git a/ringbuffer.c b/ringbuffer.c index 3918297..421f19f 100644 --- a/ringbuffer.c +++ b/ringbuffer.c @@ -1,5 +1,5 @@ /* - * ringbuffer.c: A threaded ring buffer + * ringbuffer.c: A ring buffer * * See the main source file 'vdr.c' for copyright information and * how to reach the author. @@ -7,50 +7,25 @@ * Parts of this file were inspired by the 'ringbuffy.c' from the * LinuxDVB driver (see linuxtv.org). * - * $Id: ringbuffer.c 1.7 2002/05/13 16:31:46 kls Exp $ + * $Id: ringbuffer.c 1.9 2002/06/16 11:24:40 kls Exp $ */ #include "ringbuffer.h" +#include <unistd.h> #include "tools.h" -// --- cRingBufferInputThread ------------------------------------------------- - -class cRingBufferInputThread : public cThread { -private: - cRingBuffer *ringBuffer; -protected: - virtual void Action(void) { ringBuffer->Input(); } -public: - cRingBufferInputThread(cRingBuffer *RingBuffer) { ringBuffer = RingBuffer; } - }; - -// --- cRingBufferOutputThread ------------------------------------------------ - -class cRingBufferOutputThread : public cThread { -private: - cRingBuffer *ringBuffer; -protected: - virtual void Action(void) { ringBuffer->Output(); } -public: - cRingBufferOutputThread(cRingBuffer *RingBuffer) { ringBuffer = RingBuffer; } - }; - -// --- cRingBuffer ------------------------------------------------------------ +// --- cRingBuffer ----------------------------------------------------------- cRingBuffer::cRingBuffer(int Size, bool Statistics) { size = Size; statistics = Statistics; - inputThread = NULL; - outputThread = NULL; - busy = false; maxFill = 0; + lastPercent = 0; } cRingBuffer::~cRingBuffer() { - delete inputThread; - delete outputThread; if (statistics) dsyslog("buffer stats: %d (%d%%) used", maxFill, maxFill * 100 / (size - 1)); } @@ -79,45 +54,13 @@ void cRingBuffer::EnableGet(void) readyForGet.Broadcast(); } -bool cRingBuffer::Start(void) -{ - if (!busy) { - busy = true; - outputThread = new cRingBufferOutputThread(this); - if (!outputThread->Start()) - DELETENULL(outputThread); - inputThread = new cRingBufferInputThread(this); - if (!inputThread->Start()) { - DELETENULL(inputThread); - DELETENULL(outputThread); - } - busy = outputThread && inputThread; - } - return busy; -} - -bool cRingBuffer::Active(void) -{ - return outputThread && outputThread->Active() && inputThread && inputThread->Active(); -} - -void cRingBuffer::Stop(void) -{ - busy = false; - for (time_t t0 = time(NULL) + 3; time(NULL) < t0; ) { - if (!((outputThread && outputThread->Active()) || (inputThread && inputThread->Active()))) - break; - } - DELETENULL(inputThread); - DELETENULL(outputThread); -} - -// --- cRingBufferLinear ---------------------------------------------------- +// --- cRingBufferLinear ----------------------------------------------------- cRingBufferLinear::cRingBufferLinear(int Size, bool Statistics) :cRingBuffer(Size, Statistics) { buffer = NULL; + getThreadPid = -1; if (Size > 1) { // 'Size - 1' must not be 0! buffer = new uchar[Size]; if (!buffer) @@ -146,6 +89,8 @@ void cRingBufferLinear::Clear(void) Lock(); head = tail = 0; Unlock(); + EnablePut(); + EnableGet(); } int cRingBufferLinear::Put(const uchar *Data, int Count) @@ -159,11 +104,13 @@ int cRingBufferLinear::Put(const uchar *Data, int Count) int fill = Size() - free - 1 + Count; if (fill >= Size()) fill = Size() - 1; - if (fill > maxFill) { + if (fill > maxFill) maxFill = fill; - int percent = maxFill * 100 / (Size() - 1); + int percent = maxFill * 100 / (Size() - 1) / 5 * 5; + if (abs(lastPercent - percent) >= 5) { if (percent > 75) - dsyslog("buffer usage: %d%%", percent); + dsyslog("buffer usage: %d%% (pid=%d)", percent, getThreadPid); + lastPercent = percent; } } if (free > 0) { @@ -185,6 +132,7 @@ int cRingBufferLinear::Put(const uchar *Data, int Count) else Count = 0; Unlock(); + EnableGet(); } return Count; } @@ -193,6 +141,8 @@ int cRingBufferLinear::Get(uchar *Data, int Count) { if (Count > 0) { Lock(); + if (getThreadPid < 0) + getThreadPid = getpid(); int rest = Size() - tail; int diff = head - tail; int cont = (diff >= 0) ? diff : Size() + diff; @@ -213,6 +163,8 @@ int cRingBufferLinear::Get(uchar *Data, int Count) else Count = 0; Unlock(); + if (Count == 0) + WaitForGet(); } return Count; } @@ -239,7 +191,7 @@ cFrame::~cFrame() // --- cRingBufferFrame ------------------------------------------------------ -cRingBufferFrame::cRingBufferFrame(int Size, bool Statistics = false) +cRingBufferFrame::cRingBufferFrame(int Size, bool Statistics) :cRingBuffer(Size, Statistics) { head = NULL; @@ -255,7 +207,7 @@ void cRingBufferFrame::Clear(void) { Lock(); const cFrame *p; - while ((p = Get(false)) != NULL) + while ((p = Get()) != NULL) Drop(p); Unlock(); EnablePut(); @@ -279,17 +231,14 @@ bool cRingBufferFrame::Put(cFrame *Frame) EnableGet(); return true; } - WaitForPut(); return false; } -const cFrame *cRingBufferFrame::Get(bool Wait) +const cFrame *cRingBufferFrame::Get(void) { Lock(); cFrame *p = head ? head->next : NULL; Unlock(); - if (!p && Wait) - WaitForGet(); return p; } |