kernel/sched/fair.c: Use generic rbtree impl
RFC PATCH v3 6/6 kernel/sched/fair.c: Use generic rbtree impl
This is what I'm running on my machine currently
Signed-off-by Daniel Santos <[email protected]>
--- kernel/sched/fair.c | 77 ++++++++++++++++++++++++--------------------------- 1 files changed, 36 insertions(+), 41 deletions(-)
kernel/sched/fair.c +33 -41
@@ -448,6 +448,20 @@ static inline int entity_before(struct sched_entity *a,return (s64)(a->vruntime - b->vruntime) <0 ; } +static inline long compare_vruntime(u64 *a, u64 *b) +{ +#if __BITS_PER_LONG >=64 +return (long )((s64)*a - (s64)*b); +#else +/* This is hacky, but is done to reduce instructions -- we wont use this for +* rbtree lookups, only inserts, and since our relationship is defined as +* non-unique, we only need to return positive if a > b and any other value +* means less than. +*/ +return (long )(*a > *b); +#endif +} +static void update_min_vruntime (struct cfs_rq *cfs_rq) {u64 vruntime = cfs_rq->min_vruntime;
@@ -473,57 +487,38 @@ static void update_min_vruntime(struct cfs_rq *cfs_rq)#endif } +RB_DEFINE_INTERFACE ( + fair_tree, + struct cfs_rq, tasks_timeline, rb_leftmost, /* no rightmost */, + struct sched_entity, run_node, vruntime, + 0, compare_vruntime, 0) + +#ifndef __flatten +#define __flatten __attribute__((flatten)) +#endif +/* -* Enqueue an entity into the rb-tree: +* Enqueue an entity into the rb-tree:(these are wrappers so that inline +* expansion happens in only one place) +* +* NOTE: When compiling under gcc 4.5 and 4.6 (amd64), it decided to inline +* these anyway. I would be interested in profiling this as-is and declaring +* each function __flatten noinline (forcing all in-lining in the function, but +* preventing them from being inlined themselves). Also, it may not do this on +* other archs where the (not sure, gcc docs don't seem to say anything about +* arch influence). */ static void __enqueue_entity (struct cfs_rq *cfs_rq,struct sched_entity *se) { -struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; -struct rb_node *parent =NULL ; -struct sched_entity *entry; -int leftmost =1 ; - -/* -* Find the right place in the rbtree: -*/ -while (*link) { - parent = *link; - entry = rb_entry(parent, struct sched_entity, run_node); -/* -* We dont care about collisions. Nodes with -* the same key stay together. -*/ -if (entity_before (se, entry)) { - link = &parent->rb_left; - }else { - link = &parent->rb_right; - leftmost =0 ; - } - } - -/* -* Maintain a cache of leftmost tree entries (it is frequently -* used): -*/ -if (leftmost) - cfs_rq->rb_leftmost = &se->run_node; - -rb_link_node (&se->run_node, parent, link); -rb_insert_color (&se->run_node, &cfs_rq->tasks_timeline); +fair_tree_insert (cfs_rq, se); }static void __dequeue_entity (struct cfs_rq *cfs_rq,struct sched_entity *se) { -if (cfs_rq->rb_leftmost == &se->run_node) { -struct rb_node *next_node; - - next_node =rb_next (&se->run_node); - cfs_rq->rb_leftmost = next_node; - } - -rb_erase (&se->run_node, &cfs_rq->tasks_timeline); +fair_tree_remove (cfs_rq, se); } + struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq) {struct rb_node *left = cfs_rq->rb_leftmost;
Signature · 1 line
1.7.3.4