aboutsummaryrefslogtreecommitdiff
path: root/lib/base
diff options
context:
space:
mode:
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>2006-06-17 15:23:50 +0000
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>2006-06-17 15:23:50 +0000
commit9c3098c8667241d18d2551a9a37ce7fbce396b71 (patch)
tree6f5091be55ccf279c031237e4bcc7885ff9e1dfa /lib/base
parentedd6a4323551d1ad246b0e31c0485acc8353e1cb (diff)
downloadenigma2-9c3098c8667241d18d2551a9a37ce7fbce396b71.tar.gz
enigma2-9c3098c8667241d18d2551a9a37ce7fbce396b71.zip
I/O priority support with cfq scheduler (needs new kernel patch)
Diffstat (limited to 'lib/base')
-rw-r--r--lib/base/Makefile.am2
-rw-r--r--lib/base/filepush.cpp26
-rw-r--r--lib/base/filepush.h4
-rw-r--r--lib/base/ioprio.cpp78
-rw-r--r--lib/base/ioprio.h14
5 files changed, 111 insertions, 13 deletions
diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am
index cd1a1571..6ea9d03f 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 d12b8efa..554c7845 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 35671cd6..0749cd43 100644
--- a/lib/base/filepush.h
+++ b/lib/base/filepush.h
@@ -2,6 +2,7 @@
#define __lib_base_filepush_h
#include <lib/base/thread.h>
+#include <lib/base/ioprio.h>
#include <libsig_comp.h>
#include <lib/base/message.h>
#include <sys/types.h>
@@ -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 00000000..2ada7361
--- /dev/null
+++ b/lib/base/ioprio.cpp
@@ -0,0 +1,78 @@
+#include <lib/base/ioprio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <sys/ptrace.h>
+#include <asm/unistd.h>
+
+#include <lib/base/eerror.h>
+
+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 00000000..498a473e
--- /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_