From: Andreas Monzner Date: Sat, 17 Jun 2006 15:23:50 +0000 (+0000) Subject: I/O priority support with cfq scheduler (needs new kernel patch) X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=commitdiff_plain;h=9c3098c8667241d18d2551a9a37ce7fbce396b71 I/O priority support with cfq scheduler (needs new kernel patch) --- diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am index cd1a157..6ea9d03 100644 --- a/lib/base/Makefile.am +++ b/lib/base/Makefile.am @@ -8,5 +8,5 @@ libenigma_base_a_SOURCES = \ init.cpp message.cpp thread.cpp \ smartptr.cpp estring.cpp connection.cpp \ filepush.cpp encoding.cpp console.cpp rawfile.cpp \ - nconfig.cpp + nconfig.cpp ioprio.cpp diff --git a/lib/base/filepush.cpp b/lib/base/filepush.cpp index d12b8ef..554c784 100644 --- a/lib/base/filepush.cpp +++ b/lib/base/filepush.cpp @@ -6,7 +6,8 @@ #define PVR_COMMIT 1 -eFilePushThread::eFilePushThread(): m_messagepump(eApp, 0) +eFilePushThread::eFilePushThread(int io_prio_class, int io_prio_level) + :prio_class(io_prio_class), prio(io_prio_level), m_messagepump(eApp, 0) { m_stop = 0; m_sg = 0; @@ -21,6 +22,8 @@ static void signal_handler(int x) void eFilePushThread::thread() { + setIoPrio(prio_class, prio); + off_t dest_pos = 0, source_pos = 0; size_t bytes_read = 0; @@ -28,7 +31,7 @@ void eFilePushThread::thread() size_t current_span_remaining = 0; size_t written_since_last_sync = 0; - + int already_empty = 0; eDebug("FILEPUSH THREAD START"); @@ -40,7 +43,6 @@ void eFilePushThread::thread() hasStarted(); - dest_pos = lseek(m_fd_dest, 0, SEEK_CUR); source_pos = m_raw_source.lseek(0, SEEK_CUR); /* m_stop must be evaluated after each syscall. */ @@ -61,15 +63,16 @@ void eFilePushThread::thread() // ... we would stop the thread } -// posix_fadvise(m_fd_dest, dest_pos, w, POSIX_FADV_DONTNEED); - - dest_pos += w; written_since_last_sync += w; - - if (written_since_last_sync >= 2048*1024) + + if (written_since_last_sync >= 512*1024) { - fdatasync(m_fd_dest); - written_since_last_sync = 0; + int toflush = written_since_last_sync > 2*1024*1024 ? + 2*1024*1024 : written_since_last_sync &~ 4095; // write max 2MB at once + dest_pos = lseek(m_fd_dest, 0, SEEK_CUR); + dest_pos -= toflush; + posix_fadvise(m_fd_dest, dest_pos, toflush, POSIX_FADV_DONTNEED); + written_since_last_sync -= toflush; } // printf("FILEPUSH: wrote %d bytes\n", w); @@ -145,7 +148,8 @@ void eFilePushThread::thread() } // printf("FILEPUSH: read %d bytes\n", m_buf_end); } - + fdatasync(m_fd_dest); + eDebug("FILEPUSH THREAD STOP"); } diff --git a/lib/base/filepush.h b/lib/base/filepush.h index 35671cd..0749cd4 100644 --- a/lib/base/filepush.h +++ b/lib/base/filepush.h @@ -2,6 +2,7 @@ #define __lib_base_filepush_h #include +#include #include #include #include @@ -16,8 +17,9 @@ public: class eFilePushThread: public eThread, public Object { + int prio_class, prio; public: - eFilePushThread(); + eFilePushThread(int prio_class=IOPRIO_CLASS_BE, int prio_level=0); void thread(); void stop(); void start(int sourcefd, int destfd); diff --git a/lib/base/ioprio.cpp b/lib/base/ioprio.cpp new file mode 100644 index 0000000..2ada736 --- /dev/null +++ b/lib/base/ioprio.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern "C" int sys_ioprio_set(int, int, int); +extern "C" int sys_ioprio_get(int, int); + +#if defined(__i386__) +#define __NR_ioprio_set 289 +#define __NR_ioprio_get 290 +#elif defined(__ppc__) +#define __NR_ioprio_set 273 +#define __NR_ioprio_get 274 +#elif defined(__x86_64__) +#define __NR_ioprio_set 251 +#define __NR_ioprio_get 252 +#elif defined(__ia64__) +#define __NR_ioprio_set 1274 +#define __NR_ioprio_get 1275 +#elif defined(__mips__) +#define __NR_ioprio_set 4284 +#define __NR_ioprio_get 4285 +#else +#error "Unsupported arch" +#endif + +_syscall3(int, ioprio_set, int, which, int, who, int, ioprio); +_syscall2(int, ioprio_get, int, which, int, who); + +#define IOPRIO_CLASS_SHIFT 13 + +enum { + IOPRIO_WHO_PROCESS = 1, + IOPRIO_WHO_PGRP, + IOPRIO_WHO_USER, +}; + +const char *to_prio[] = { "none", "realtime", "best-effort", "idle", }; + +void setIoPrio(int prio_class, int prio) +{ + if (prio_class < 0 || prio_class > 3) + { + eDebug("prio class(%d) out of valid range (0..3)", prio_class); + return; + } + if (prio < 0 || prio > 7) + { + eDebug("prio level(%d) out of range (0..7)", prio); + return; + } + if (ioprio_set(IOPRIO_WHO_PROCESS, 0 /*pid 0 .. current process*/, prio | prio_class << IOPRIO_CLASS_SHIFT) == -1) + eDebug("setIoPrio failed (%m) !"); + else + eDebug("setIoPrio %s level %d ok", to_prio[prio_class], prio); +} + +void printIoPrio() +{ + int pid = 0, ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid); + + eDebug("pid=%d, %d", pid, ioprio); + + if (ioprio == -1) + eDebug("ioprio_get(%m)"); + else { + int ioprio_class = ioprio >> IOPRIO_CLASS_SHIFT; + ioprio = ioprio & 0xff; + eDebug("%s: prio %d", to_prio[ioprio_class], ioprio); + } +} diff --git a/lib/base/ioprio.h b/lib/base/ioprio.h new file mode 100644 index 0000000..498a473 --- /dev/null +++ b/lib/base/ioprio.h @@ -0,0 +1,14 @@ +#ifndef __LIB_BASE_IOPRIO_H_ +#define __LIB_BASE_IOPRIO_H_ + +void setIoPrio(int prio_class, int prio=7); +void printIoPrio(); + +enum { + IOPRIO_CLASS_NONE, + IOPRIO_CLASS_RT, + IOPRIO_CLASS_BE, + IOPRIO_CLASS_IDLE, +}; + +#endif // __LIB_BASE_IOPRIO_H_ diff --git a/lib/components/file_eraser.cpp b/lib/components/file_eraser.cpp index 6cacf04..ea68eb4 100644 --- a/lib/components/file_eraser.cpp +++ b/lib/components/file_eraser.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -33,9 +34,15 @@ eBackgroundFileEraser::~eBackgroundFileEraser() void eBackgroundFileEraser::thread() { hasStarted(); + nice(5); + + setIoPrio(IOPRIO_CLASS_BE, 7); + reset(); + runLoop(); + stop_thread_timer.stop(); } @@ -68,7 +75,7 @@ void eBackgroundFileEraser::gotMessage(const Message &msg ) eDebug("file %s erased", msg.filename); free((char*)msg.filename); } - stop_thread_timer.start(2000, true); // stop thread in two seconds + stop_thread_timer.start(1000, true); // stop thread in one seconds break; case Message::quit: quit(0); diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp index c6d3b10..b0d9b40 100644 --- a/lib/dvb/demux.cpp +++ b/lib/dvb/demux.cpp @@ -412,7 +412,7 @@ private: }; eDVBRecordFileThread::eDVBRecordFileThread() - : m_ts_parser(m_stream_info) + :eFilePushThread(IOPRIO_CLASS_RT, 7), m_ts_parser(m_stream_info) { m_current_offset = 0; } diff --git a/lib/dvb/pvrparse.cpp b/lib/dvb/pvrparse.cpp index 4b8da89..a611332 100644 --- a/lib/dvb/pvrparse.cpp +++ b/lib/dvb/pvrparse.cpp @@ -63,7 +63,7 @@ void eMPEGStreamInformation::fixupDiscontinuties() if (!m_access_points.size()) return; - eDebug("Fixing discontinuities ..."); +// eDebug("Fixing discontinuities ..."); /* if we have no delta at the beginning, extrapolate it */ if ((m_access_points.find(0) == m_access_points.end()) && (m_access_points.size() > 1)) @@ -77,7 +77,7 @@ void eMPEGStreamInformation::fixupDiscontinuties() tdiff *= first->first; tdiff /= diff; m_timestamp_deltas[0] = first->second - tdiff; - eDebug("first delta is %08llx", first->second - tdiff); +// eDebug("first delta is %08llx", first->second - tdiff); } } @@ -92,16 +92,16 @@ void eMPEGStreamInformation::fixupDiscontinuties() if (llabs(diff) > (90000*5)) // 5sec diff { - eDebug("%llx < %llx, have discont. new timestamp is %llx (diff is %llx)!", current, lastpts_t, i->second, diff); +// eDebug("%llx < %llx, have discont. new timestamp is %llx (diff is %llx)!", current, lastpts_t, i->second, diff); currentDelta = i->second - lastpts_t; /* FIXME: should be the extrapolated new timestamp, based on the current rate */ - eDebug("current delta now %llx, making current to %llx", currentDelta, i->second - currentDelta); +// eDebug("current delta now %llx, making current to %llx", currentDelta, i->second - currentDelta); m_timestamp_deltas[i->first] = currentDelta; } lastpts_t = i->second - currentDelta; } - eDebug("ok, found %d disconts.", m_timestamp_deltas.size()); +// eDebug("ok, found %d disconts.", m_timestamp_deltas.size()); #if 0 for (off_t x=0x25807E34ULL; x < 0x25B3CF70; x+= 100000) diff --git a/lib/dvb/tstools.cpp b/lib/dvb/tstools.cpp index 4ee2626..87791c9 100644 --- a/lib/dvb/tstools.cpp +++ b/lib/dvb/tstools.cpp @@ -36,7 +36,7 @@ int eDVBTSTools::openFile(const char *filename) m_use_streaminfo = 1; else { - eDebug("no recorded stream information available"); +// eDebug("no recorded stream information available"); m_use_streaminfo = 0; } @@ -267,7 +267,7 @@ void eDVBTSTools::calcEnd() m_end_valid = 0; m_futile = 0; - eDebug("file size changed, recalc length"); +// eDebug("file size changed, recalc length"); } int maxiter = 10; diff --git a/main/enigma.cpp b/main/enigma.cpp index 0600062..5a22110 100644 --- a/main/enigma.cpp +++ b/main/enigma.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -191,7 +192,9 @@ int main(int argc, char **argv) printf("executing main\n"); bsodCatchSignals(); - + + setIoPrio(IOPRIO_CLASS_BE, 3); + python.execute("mytest", "__main__"); if (exit_code == 5) /* python crash */