Improved thread locking in the ring buffer to avoid possible race conditions under heavy load

This commit is contained in:
Klaus Schmidinger 2002-04-19 12:40:04 +02:00
parent 849ec98c3d
commit 8ec5c0d926
3 changed files with 40 additions and 32 deletions

View File

@ -157,6 +157,8 @@ Werner Fink <werner@suse.de>
for helping to debug leftover 'zombie' processes when closing a pipe
for making the Dolby Digital thread start only if the recording actually
contains Dolby Digital data
for improving thread locking in the ring buffer to avoid possible race conditions
under heavy load
Rolf Hakenes <hakenes@hippomi.de>
for providing 'libdtv' and adapting the EIT mechanisms to it

View File

@ -1191,7 +1191,7 @@ Video Disk Recorder Revision History
same name was manually deleted on a system with more than one video directory
(thanks to Dirk Wiebel for reporting this one).
2002-04-13: Version 1.0.1
2002-04-19: Version 1.0.1
- Added some DVB-T channels for Berlin (Germany) to channels.conf.terr (thanks to
Andreas Roedl).
@ -1204,3 +1204,5 @@ Video Disk Recorder Revision History
any timers referencing a channel with a number higher than 102 should be
checked and adapted if necessary (this only applies if you are using the default
'channels.conf').
- Improved thread locking in the ring buffer to avoid possible race conditions
under heavy load (thanks to Werner Fink).

View File

@ -7,7 +7,7 @@
* Parts of this file were inspired by the 'ringbuffy.c' from the
* LinuxDVB driver (see linuxtv.org).
*
* $Id: ringbuffer.c 1.5 2001/11/03 09:50:46 kls Exp $
* $Id: ringbuffer.c 1.6 2002/04/19 12:38:44 kls Exp $
*/
#include "ringbuffer.h"
@ -154,7 +154,6 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
Lock();
int rest = Size() - head;
int diff = tail - head;
Unlock();
int free = (diff > 0) ? diff - 1 : Size() + diff - 1;
if (statistics) {
int fill = Size() - free - 1 + Count;
@ -167,22 +166,25 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
dsyslog(LOG_INFO, "buffer usage: %d%%", percent);
}
}
if (free <= 0)
return 0;
if (free < Count)
Count = free;
if (Count > maxFill)
maxFill = Count;
if (Count >= rest) {
memcpy(buffer + head, Data, rest);
if (Count - rest)
memcpy(buffer, Data + rest, Count - rest);
head = Count - rest;
}
else {
memcpy(buffer + head, Data, Count);
head += Count;
if (free > 0) {
if (free < Count)
Count = free;
if (Count > maxFill)
maxFill = Count;
if (Count >= rest) {
memcpy(buffer + head, Data, rest);
if (Count - rest)
memcpy(buffer, Data + rest, Count - rest);
head = Count - rest;
}
else {
memcpy(buffer + head, Data, Count);
head += Count;
}
}
else
Count = 0;
Unlock();
}
return Count;
}
@ -193,22 +195,24 @@ int cRingBufferLinear::Get(uchar *Data, int Count)
Lock();
int rest = Size() - tail;
int diff = head - tail;
Unlock();
int cont = (diff >= 0) ? diff : Size() + diff;
if (rest <= 0)
return 0;
if (cont < Count)
Count = cont;
if (Count >= rest) {
memcpy(Data, buffer + tail, rest);
if (Count - rest)
memcpy(Data + rest, buffer, Count - rest);
tail = Count - rest;
}
else {
memcpy(Data, buffer + tail, Count);
tail += Count;
if (rest > 0) {
if (cont < Count)
Count = cont;
if (Count >= rest) {
memcpy(Data, buffer + tail, rest);
if (Count - rest)
memcpy(Data + rest, buffer, Count - rest);
tail = Count - rest;
}
else {
memcpy(Data, buffer + tail, Count);
tail += Count;
}
}
else
Count = 0;
Unlock();
}
return Count;
}