summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--tumblerd/tumbler-group-scheduler.c16
-rw-r--r--tumblerd/tumbler-scheduler.c67
-rw-r--r--tumblerd/tumbler-scheduler.h2
4 files changed, 85 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 813954a..e17d512 100644
--- a/configure.ac
+++ b/configure.ac
@@ -105,7 +105,7 @@ dnl ***************************************
dnl *** Check for standard header files ***
dnl ***************************************
AC_HEADER_STDC()
-AC_CHECK_HEADERS([fcntl.h sys/mman.h sys/stat.h])
+AC_CHECK_HEADERS([sched.h linux/sched.h syscall.h])
dnl ************************************
dnl *** Check for standard functions ***
diff --git a/tumblerd/tumbler-group-scheduler.c b/tumblerd/tumbler-group-scheduler.c
index 8429cfa..f133d90 100644
--- a/tumblerd/tumbler-group-scheduler.c
+++ b/tumblerd/tumbler-group-scheduler.c
@@ -94,6 +94,7 @@ struct _TumblerGroupScheduler
GMutex *mutex;
GList *requests;
guint group;
+ gboolean prioritized;
gchar *name;
};
@@ -150,6 +151,13 @@ tumbler_group_scheduler_init (TumblerGroupScheduler *scheduler)
scheduler->mutex = g_mutex_new ();
scheduler->requests = NULL;
+ /* Note that unless we convert this boolean to a TLS (thread-local), that
+ * we can only do this 'prioritized' flag with a thread-pool that is set to
+ * exclusive: because then the one thread keeps running until the pool is
+ * freed. */
+
+ scheduler->prioritized = FALSE;
+
/* allocate a pool with one thread for all requests */
scheduler->pool = g_thread_pool_new (tumbler_group_scheduler_thread,
scheduler, 1, TRUE, NULL);
@@ -360,12 +368,18 @@ tumbler_group_scheduler_thread (gpointer data,
GList *thumbnails;
GList *lp;
guint n;
- guint i;
gint error_code;
g_return_if_fail (TUMBLER_IS_GROUP_SCHEDULER (scheduler));
g_return_if_fail (request != NULL);
+ /* Set I/O priority for the exclusive ThreadPool's thread */
+ if (!scheduler->prioritized)
+ {
+ tumbler_scheduler_thread_use_lower_priority ();
+ scheduler->prioritized = TRUE;
+ }
+
/* notify others that we're starting to process this request */
g_signal_emit_by_name (request->scheduler, "started", request->handle);
diff --git a/tumblerd/tumbler-scheduler.c b/tumblerd/tumbler-scheduler.c
index 897cbaf..2897e3d 100644
--- a/tumblerd/tumbler-scheduler.c
+++ b/tumblerd/tumbler-scheduler.c
@@ -22,10 +22,46 @@
#include <config.h>
#endif
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+#ifdef HAVE_LINUX_SCHED_H
+#include <linux/sched.h>
+#endif
+#ifdef HAVE_SYSCALL_H
+#include <syscall.h>
+#endif
+
#include <tumbler/tumbler.h>
#include <tumblerd/tumbler-scheduler.h>
+
+#define IOPRIO_CLASS_SHIFT 13
+
+#ifndef SCHED_IDLE
+#define SCHED_IDLE 5
+#endif
+
+
+
+enum
+{
+ IOPRIO_CLASS_NONE,
+ IOPRIO_CLASS_RT,
+ IOPRIO_CLASS_BE,
+ IOPRIO_CLASS_IDLE,
+};
+
+
+
+enum
+{
+ IOPRIO_WHO_PROCESS = 1,
+ IOPRIO_WHO_PGRP,
+ IOPRIO_WHO_USER,
+};
+
/* signal identifiers */
enum
{
@@ -252,3 +288,34 @@ tumbler_scheduler_request_compare (gconstpointer a,
return request_b->handle - request_a->handle;
}
+
+static int
+ioprio_set (int which, int who, int ioprio_val)
+{
+#if defined(__NR_ioprio_set) && defined(HAVE_SYS_SYSCALL_H)
+ return syscall (__NR_ioprio_set, which, who, ioprio_val);
+#else
+ return 0;
+#endif
+}
+
+
+void
+tumbler_scheduler_thread_use_lower_priority (void)
+{
+#ifdef HAVE_SCHED_H
+ struct sched_param sp;
+#endif
+ int ioprio;
+ int ioclass;
+
+ ioprio = 7; /* priority is ignored with idle class */
+ ioclass = IOPRIO_CLASS_IDLE << IOPRIO_CLASS_SHIFT;
+
+ ioprio_set (IOPRIO_WHO_PROCESS, 0, ioprio | ioclass);
+
+#ifdef HAVE_SCHED_H
+ if (sched_getparam (0, &sp) == 0)
+ sched_setscheduler (0, SCHED_IDLE, &sp);
+#endif
+}
diff --git a/tumblerd/tumbler-scheduler.h b/tumblerd/tumbler-scheduler.h
index 733e5aa..db5445e 100644
--- a/tumblerd/tumbler-scheduler.h
+++ b/tumblerd/tumbler-scheduler.h
@@ -81,6 +81,8 @@ gint tumbler_scheduler_request_compare (gconstpointer
gconstpointer b,
gpointer user_data);
+void tumbler_scheduler_thread_use_lower_priority (void);
+
struct _TumblerSchedulerRequest
{
TumblerThumbnailer **thumbnailers;