/* * enqueue_hrtimer - internal function to (re)start a timer * * The timer is inserted in expiry order. Insertion into the * red black tree is O(log(n)). Must hold the base lock. */ static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, int reprogram) { struct rb_node **link = &base->active.rb_node; struct rb_node *parent = NULL; struct hrtimer *entry; int leftmost = 1; debug_hrtimer_activate(timer); /* * Find the right place in the rbtree: */ while (*link) { parent = *link; entry = rb_entry(parent, struct hrtimer, node); /* * We dont care about collisions. Nodes with * the same expiry time stay together. */ if (hrtimer_get_expires_tv64(timer) < hrtimer_get_expires_tv64(entry)) { link = &(*link)->rb_left; } else { link = &(*link)->rb_right; leftmost = 0; } } /* * Insert the timer to the rbtree and check whether it * replaces the first pending timer */ if (leftmost) { /* * Reprogram the clock event device. When the timer is already * expired hrtimer_enqueue_reprogram has either called the * callback or added it to the pending list and raised the * softirq. * * This is a NOP for !HIGHRES */ if (reprogram && hrtimer_enqueue_reprogram(timer, base)) return; base->first = &timer->node; } rb_link_node(&timer->node, parent, link); rb_insert_color(&timer->node, &base->active); /* * HRTIMER_STATE_ENQUEUED is or'ed to the current state to preserve the * state of a possibly running callback. */ timer->state |= HRTIMER_STATE_ENQUEUED; }
/* * enqueue_hrtimer - internal function to (re)start a timer * * The timer is inserted in expiry order. Insertion into the * red black tree is O(log(n)). Must hold the base lock. * * Returns 1 when the new timer is the leftmost timer in the tree. */ static int enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base) { struct rb_node **link = &base->active.rb_node; struct rb_node *parent = NULL; struct hrtimer *entry; int leftmost = 1; debug_hrtimer_activate(timer); /* * Find the right place in the rbtree: */ while (*link) { parent = *link; entry = rb_entry(parent, struct hrtimer, node); /* * We dont care about collisions. Nodes with * the same expiry time stay together. */ if (hrtimer_get_expires_tv64(timer) < hrtimer_get_expires_tv64(entry)) { link = &(*link)->rb_left; } else { link = &(*link)->rb_right; leftmost = 0; } } /* * Insert the timer to the rbtree and check whether it * replaces the first pending timer */ if (leftmost) base->first = &timer->node; rb_link_node(&timer->node, parent, link); rb_insert_color(&timer->node, &base->active); /* * HRTIMER_STATE_ENQUEUED is or'ed to the current state to preserve the * state of a possibly running callback. */ timer->state |= HRTIMER_STATE_ENQUEUED; return leftmost; }
static inline void debug_activate(struct hrtimer *timer) { debug_hrtimer_activate(timer); trace_hrtimer_start(timer); }