mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Further improvements to cUnbufferedFile
This commit is contained in:
parent
b6920cd2d8
commit
204f4a322e
4
cutter.c
4
cutter.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: cutter.c 1.13 2006/02/04 13:40:20 kls Exp $
|
* $Id: cutter.c 1.14 2006/02/05 11:06:47 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cutter.h"
|
#include "cutter.h"
|
||||||
@ -125,7 +125,6 @@ void cCuttingThread::Action(void)
|
|||||||
error = "toFile 1";
|
error = "toFile 1";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
toFile->SetReadAhead(MEGABYTE(20));
|
|
||||||
FileSize = 0;
|
FileSize = 0;
|
||||||
}
|
}
|
||||||
LastIFrame = 0;
|
LastIFrame = 0;
|
||||||
@ -166,7 +165,6 @@ void cCuttingThread::Action(void)
|
|||||||
error = "toFile 2";
|
error = "toFile 2";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
toFile->SetReadAhead(MEGABYTE(20));
|
|
||||||
FileSize = 0;
|
FileSize = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
37
tools.c
37
tools.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.c 1.113 2006/02/04 14:07:30 kls Exp $
|
* $Id: tools.c 1.114 2006/02/05 11:05:56 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
@ -1133,6 +1133,7 @@ ssize_t cUnbufferedFile::Read(void *Data, size_t Size)
|
|||||||
#ifdef USE_FADVISE
|
#ifdef USE_FADVISE
|
||||||
off_t jumped = curpos-lastpos; // nonzero means we're not at the last offset
|
off_t jumped = curpos-lastpos; // nonzero means we're not at the last offset
|
||||||
if ((cachedstart < cachedend) && (curpos < cachedstart || curpos > cachedend)) {
|
if ((cachedstart < cachedend) && (curpos < cachedstart || curpos > cachedend)) {
|
||||||
|
// current position is outside the cached window -- invalidate it.
|
||||||
FadviseDrop(cachedstart, cachedend-cachedstart);
|
FadviseDrop(cachedstart, cachedend-cachedstart);
|
||||||
cachedstart = curpos;
|
cachedstart = curpos;
|
||||||
cachedend = curpos;
|
cachedend = curpos;
|
||||||
@ -1151,7 +1152,7 @@ ssize_t cUnbufferedFile::Read(void *Data, size_t Size)
|
|||||||
// Trigger the readahead IO, but only if we've used at least
|
// Trigger the readahead IO, but only if we've used at least
|
||||||
// 1/2 of the previously requested area. This avoids calling
|
// 1/2 of the previously requested area. This avoids calling
|
||||||
// fadvise() after every read() call.
|
// fadvise() after every read() call.
|
||||||
if (ahead - curpos < (off_t)(readahead - readahead / 2)) {
|
if (ahead - curpos < (off_t)(readahead / 2)) {
|
||||||
posix_fadvise(fd, curpos, readahead, POSIX_FADV_WILLNEED);
|
posix_fadvise(fd, curpos, readahead, POSIX_FADV_WILLNEED);
|
||||||
ahead = curpos + readahead;
|
ahead = curpos + readahead;
|
||||||
cachedend = max(cachedend, ahead);
|
cachedend = max(cachedend, ahead);
|
||||||
@ -1161,15 +1162,17 @@ ssize_t cUnbufferedFile::Read(void *Data, size_t Size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ahead = curpos; // jumped -> we really don't want any readahead. otherwise eg fast-rewind gets in trouble.
|
ahead = curpos; // jumped -> we really don't want any readahead, otherwise e.g. fast-rewind gets in trouble.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cachedstart < cachedend) {
|
if (cachedstart < cachedend) {
|
||||||
if (curpos - cachedstart > READCHUNK * 2) {
|
if (curpos - cachedstart > READCHUNK * 2) {
|
||||||
|
// current position has moved forward enough, shrink tail window.
|
||||||
FadviseDrop(cachedstart, curpos - READCHUNK - cachedstart);
|
FadviseDrop(cachedstart, curpos - READCHUNK - cachedstart);
|
||||||
cachedstart = curpos - READCHUNK;
|
cachedstart = curpos - READCHUNK;
|
||||||
}
|
}
|
||||||
else if (cachedend > ahead && cachedend - curpos > READCHUNK * 2) {
|
else if (cachedend > ahead && cachedend - curpos > READCHUNK * 2) {
|
||||||
|
// current position has moved back enough, shrink head window.
|
||||||
FadviseDrop(curpos + READCHUNK, cachedend - curpos + READCHUNK);
|
FadviseDrop(curpos + READCHUNK, cachedend - curpos + READCHUNK);
|
||||||
cachedend = curpos + READCHUNK;
|
cachedend = curpos + READCHUNK;
|
||||||
}
|
}
|
||||||
@ -1193,20 +1196,32 @@ ssize_t cUnbufferedFile::Write(const void *Data, size_t Size)
|
|||||||
lastpos = max(lastpos, curpos);
|
lastpos = max(lastpos, curpos);
|
||||||
if (written > WRITE_BUFFER) {
|
if (written > WRITE_BUFFER) {
|
||||||
if (lastpos > begin) {
|
if (lastpos > begin) {
|
||||||
|
// Now do three things:
|
||||||
|
// 1) Start writeback of begin..lastpos range
|
||||||
|
// 2) Drop the already written range (by the previous fadvise call)
|
||||||
|
// 3) Handle nonpagealigned data.
|
||||||
|
// This is why we double the WRITE_BUFFER; the first time around the
|
||||||
|
// last (partial) page might be skipped, writeback will start only after
|
||||||
|
// second call; the third call will still include this page and finally
|
||||||
|
// drop it from cache.
|
||||||
off_t headdrop = min(begin, WRITE_BUFFER * 2L);
|
off_t headdrop = min(begin, WRITE_BUFFER * 2L);
|
||||||
posix_fadvise(fd, begin - headdrop, lastpos - begin + headdrop, POSIX_FADV_DONTNEED);
|
posix_fadvise(fd, begin - headdrop, lastpos - begin + headdrop, POSIX_FADV_DONTNEED);
|
||||||
}
|
}
|
||||||
begin = lastpos = max(0L, curpos - (KILOBYTE(4) - 1));
|
begin = lastpos = curpos;
|
||||||
totwritten += written;
|
totwritten += written;
|
||||||
written = 0;
|
written = 0;
|
||||||
// The above fadvise() works when writing slowly (recording), but could
|
// The above fadvise() works when writing slowly (recording), but could
|
||||||
// leave cached data around when writing at a high rate (cutting).
|
// leave cached data around when writing at a high rate, e.g. when cutting,
|
||||||
// Also, it seems in some setups, the above does not trigger any I/O and
|
// because by the time we try to flush the cached pages (above) the data
|
||||||
// the fdatasync() call below has to do all the work (reiserfs with some
|
// can still be dirty - we are faster than the disk I/O.
|
||||||
// kind of write gathering enabled).
|
// So we do another round of flushing, just like above, but at larger
|
||||||
// We add 'readahead' to the threshold in an attempt to increase cutting
|
// intervals -- this should catch any pages that couldn't be released
|
||||||
// speed; it's a tradeoff -- speed vs RAM-used.
|
// earlier.
|
||||||
if (totwritten > MEGABYTE(32) + readahead) {
|
if (totwritten > MEGABYTE(32)) {
|
||||||
|
// It seems in some setups, fadvise() does not trigger any I/O and
|
||||||
|
// a fdatasync() call would be required do all the work (reiserfs with some
|
||||||
|
// kind of write gathering enabled), but the syncs cause (io) load..
|
||||||
|
// Uncomment the next line if you think you need them.
|
||||||
//fdatasync(fd);
|
//fdatasync(fd);
|
||||||
off_t headdrop = min(curpos - totwritten, totwritten * 2L);
|
off_t headdrop = min(curpos - totwritten, totwritten * 2L);
|
||||||
posix_fadvise(fd, curpos - totwritten - headdrop, totwritten + headdrop, POSIX_FADV_DONTNEED);
|
posix_fadvise(fd, curpos - totwritten - headdrop, totwritten + headdrop, POSIX_FADV_DONTNEED);
|
||||||
|
Loading…
Reference in New Issue
Block a user