summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2017-02-01 23:57:12 +0100
committerRichard Braun <rbraun@sceen.net>2017-02-01 23:58:26 +0100
commitd09b913612712c7d58e5ee3ee20703cce63ad0b0 (patch)
tree22a91096a6c83295cd339ec77171ffd7738b1f60
parent07a677e3c52e6af05ad15f47f95d7174103ee42a (diff)
kern/thread: introduce global priorities
-rw-r--r--kern/thread.c40
-rw-r--r--kern/thread.h6
2 files changed, 46 insertions, 0 deletions
diff --git a/kern/thread.c b/kern/thread.c
index c3a4fe73..0cb5008b 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -138,6 +138,17 @@
#define THREAD_NR_SCHED_CLASSES 3
/*
+ * Global priority bases for each scheduling class.
+ *
+ * Global priorities are only used to determine which of two threads
+ * has the higher priority, and should only matter for priority
+ * inheritance.
+ */
+#define THREAD_SCHED_GLOBAL_PRIO_RT (THREAD_SCHED_FS_PRIO_MAX + 2)
+#define THREAD_SCHED_GLOBAL_PRIO_FS 1
+#define THREAD_SCHED_GLOBAL_PRIO_IDLE 0
+
+/*
* Default time slice for real-time round-robin scheduling.
*/
#define THREAD_DEFAULT_RR_TIME_SLICE (HZ / 10)
@@ -251,6 +262,7 @@ struct thread_sched_ops {
void (*put_prev)(struct thread_runq *runq, struct thread *thread);
struct thread * (*get_next)(struct thread_runq *runq);
void (*set_priority)(struct thread *thread, unsigned short priority);
+ unsigned int (*get_global_priority)(const struct thread *thread);
void (*set_next)(struct thread_runq *runq, struct thread *thread);
void (*tick)(struct thread_runq *runq, struct thread *thread);
};
@@ -719,6 +731,12 @@ thread_sched_rt_get_next(struct thread_runq *runq)
return thread;
}
+static unsigned int
+thread_sched_rt_get_global_priority(const struct thread *thread)
+{
+ return THREAD_SCHED_GLOBAL_PRIO_RT + thread_priority(thread);
+}
+
static void
thread_sched_rt_set_next(struct thread_runq *runq, struct thread *thread)
{
@@ -1126,6 +1144,12 @@ thread_sched_fs_set_priority(struct thread *thread, unsigned short priority)
}
}
+static unsigned int
+thread_sched_fs_get_global_priority(const struct thread *thread)
+{
+ return THREAD_SCHED_GLOBAL_PRIO_FS + thread_priority(thread);
+}
+
static void
thread_sched_fs_set_next(struct thread_runq *runq, struct thread *thread)
{
@@ -1476,6 +1500,13 @@ thread_sched_idle_get_next(struct thread_runq *runq)
return runq->idler;
}
+static unsigned int
+thread_sched_idle_get_global_priority(const struct thread *thread)
+{
+ (void)thread;
+ return THREAD_SCHED_GLOBAL_PRIO_IDLE;
+}
+
static const struct thread_sched_ops thread_sched_ops[THREAD_NR_SCHED_CLASSES] = {
[THREAD_SCHED_CLASS_RT] = {
.init_sched = thread_sched_rt_init_sched,
@@ -1485,6 +1516,7 @@ static const struct thread_sched_ops thread_sched_ops[THREAD_NR_SCHED_CLASSES] =
.put_prev = thread_sched_rt_put_prev,
.get_next = thread_sched_rt_get_next,
.set_priority = NULL,
+ .get_global_priority = thread_sched_rt_get_global_priority,
.set_next = thread_sched_rt_set_next,
.tick = thread_sched_rt_tick,
},
@@ -1496,6 +1528,7 @@ static const struct thread_sched_ops thread_sched_ops[THREAD_NR_SCHED_CLASSES] =
.put_prev = thread_sched_fs_put_prev,
.get_next = thread_sched_fs_get_next,
.set_priority = thread_sched_fs_set_priority,
+ .get_global_priority = thread_sched_fs_get_global_priority,
.set_next = thread_sched_fs_set_next,
.tick = thread_sched_fs_tick,
},
@@ -1507,6 +1540,7 @@ static const struct thread_sched_ops thread_sched_ops[THREAD_NR_SCHED_CLASSES] =
.put_prev = NULL,
.get_next = thread_sched_idle_get_next,
.set_priority = NULL,
+ .get_global_priority = thread_sched_idle_get_global_priority,
.set_next = NULL,
.tick = NULL,
},
@@ -2306,6 +2340,12 @@ thread_schedclass_to_str(const struct thread *thread)
}
}
+unsigned int
+thread_global_priority(const struct thread *thread)
+{
+ return thread_get_sched_ops(thread)->get_global_priority(thread);
+}
+
void
thread_setscheduler(struct thread *thread, unsigned char policy,
unsigned short priority)
diff --git a/kern/thread.h b/kern/thread.h
index 0d9c7861..14fd8669 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -266,6 +266,12 @@ thread_priority(const struct thread *thread)
return thread->sched_data.priority;
}
+/*
+ * The global priority of a thread is meant to be compared against
+ * another global priority to determine which thread has higher priority.
+ */
+unsigned int thread_global_priority(const struct thread *thread);
+
static inline struct thread *
thread_from_tcb(struct tcb *tcb)
{