mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Threads: smoothening loop pickup and less aggressive dropping
This commit is contained in:
parent
8ad9c946e1
commit
1180f25123
@ -573,7 +573,7 @@ sockets_fire(struct birdloop *loop)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void bird_thread_start_event(void *_data);
|
static void bird_thread_start_event(void *_data);
|
||||||
static void bird_thread_busy_update(struct bird_thread *thr, int timeout_ms);
|
static void bird_thread_busy_set(struct bird_thread *thr, int val);
|
||||||
|
|
||||||
struct birdloop_pickup_group {
|
struct birdloop_pickup_group {
|
||||||
DOMAIN(attrs) domain;
|
DOMAIN(attrs) domain;
|
||||||
@ -652,6 +652,8 @@ birdloop_set_thread(struct birdloop *loop, struct bird_thread *thr, struct birdl
|
|||||||
group->loop_unassigned_count++;
|
group->loop_unassigned_count++;
|
||||||
UNLOCK_DOMAIN(attrs, group->domain);
|
UNLOCK_DOMAIN(attrs, group->domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loop->last_transition_ns = ns_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -666,6 +668,14 @@ bird_thread_pickup_next(struct birdloop_pickup_group *group)
|
|||||||
wakeup_do_kick(SKIP_BACK(struct bird_thread, n, HEAD(group->threads)));
|
wakeup_do_kick(SKIP_BACK(struct bird_thread, n, HEAD(group->threads)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static _Bool
|
||||||
|
birdloop_hot_potato(struct birdloop *loop)
|
||||||
|
{
|
||||||
|
if (!loop) return 0;
|
||||||
|
if (!NODE_VALID(&loop->n)) return 0;
|
||||||
|
return ns_now() - loop->last_transition_ns < 1 S TO_NS;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
birdloop_take(struct birdloop_pickup_group *group)
|
birdloop_take(struct birdloop_pickup_group *group)
|
||||||
{
|
{
|
||||||
@ -675,7 +685,8 @@ birdloop_take(struct birdloop_pickup_group *group)
|
|||||||
|
|
||||||
if (this_thread->busy_active &&
|
if (this_thread->busy_active &&
|
||||||
(group->thread_busy_count < group->thread_count) &&
|
(group->thread_busy_count < group->thread_count) &&
|
||||||
(this_thread->loop_count > 1))
|
(this_thread->loop_count > 1) &&
|
||||||
|
birdloop_hot_potato(HEAD(group->loops)))
|
||||||
{
|
{
|
||||||
THREAD_TRACE(DL_SCHEDULING, "Loop drop requested (tbc=%d, tc=%d, lc=%d)",
|
THREAD_TRACE(DL_SCHEDULING, "Loop drop requested (tbc=%d, tc=%d, lc=%d)",
|
||||||
group->thread_busy_count, group->thread_count, this_thread->loop_count);
|
group->thread_busy_count, group->thread_count, this_thread->loop_count);
|
||||||
@ -686,7 +697,7 @@ birdloop_take(struct birdloop_pickup_group *group)
|
|||||||
WALK_LIST2(loop, n, this_thread->loops, n)
|
WALK_LIST2(loop, n, this_thread->loops, n)
|
||||||
{
|
{
|
||||||
birdloop_enter(loop);
|
birdloop_enter(loop);
|
||||||
if (ev_active(&loop->event) && !loop->stopped)
|
if (ev_active(&loop->event) && !loop->stopped && !birdloop_hot_potato(loop))
|
||||||
{
|
{
|
||||||
LOOP_TRACE(loop, DL_SCHEDULING, "Dropping from thread");
|
LOOP_TRACE(loop, DL_SCHEDULING, "Dropping from thread");
|
||||||
/* Pass to another thread */
|
/* Pass to another thread */
|
||||||
@ -710,7 +721,8 @@ birdloop_take(struct birdloop_pickup_group *group)
|
|||||||
if (dropped)
|
if (dropped)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bird_thread_busy_update(this_thread, -1);
|
this_thread->busy_counter = 0;
|
||||||
|
bird_thread_busy_set(this_thread, 0);
|
||||||
LOCK_DOMAIN(attrs, group->domain);
|
LOCK_DOMAIN(attrs, group->domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -773,25 +785,6 @@ bird_thread_busy_set(struct bird_thread *thr, int val)
|
|||||||
UNLOCK_DOMAIN(attrs, thr->group->domain);
|
UNLOCK_DOMAIN(attrs, thr->group->domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
bird_thread_busy_update(struct bird_thread *thr, int timeout_ms)
|
|
||||||
{
|
|
||||||
int idle_force = (timeout_ms < 0);
|
|
||||||
int val = (timeout_ms < 5) && !idle_force;
|
|
||||||
|
|
||||||
if (val == thr->busy_active)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (val && (++thr->busy_counter == 4))
|
|
||||||
return bird_thread_busy_set(thr, 1);
|
|
||||||
|
|
||||||
if (!val && (idle_force || (--thr->busy_counter == 0)))
|
|
||||||
{
|
|
||||||
thr->busy_counter = 0;
|
|
||||||
bird_thread_busy_set(thr, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
bird_thread_main(void *arg)
|
bird_thread_main(void *arg)
|
||||||
{
|
{
|
||||||
@ -880,11 +873,31 @@ bird_thread_main(void *arg)
|
|||||||
ASSERT_DIE(pfd.loop.used == pfd.pfd.used);
|
ASSERT_DIE(pfd.loop.used == pfd.pfd.used);
|
||||||
THREAD_TRACE(DL_SOCKETS, "Total %d sockets", pfd.pfd.used);
|
THREAD_TRACE(DL_SOCKETS, "Total %d sockets", pfd.pfd.used);
|
||||||
}
|
}
|
||||||
/* Nothing to do in at least 5 seconds, flush local hot page cache */
|
|
||||||
else if ((timeout > 5000) || (timeout < 0))
|
|
||||||
flush_local_pages();
|
|
||||||
|
|
||||||
bird_thread_busy_update(thr, timeout);
|
/* Check thread busy indicator */
|
||||||
|
int idle_force = (timeout < 0) || (timeout > 300);
|
||||||
|
int busy_now = (timeout < 5) && !idle_force;
|
||||||
|
|
||||||
|
/* Nothing to do right now, flush local hot page cache */
|
||||||
|
if (idle_force)
|
||||||
|
{
|
||||||
|
LOCK_DOMAIN(attrs, thr->group->domain);
|
||||||
|
if (!EMPTY_LIST(thr->group->loops))
|
||||||
|
timeout = 0;
|
||||||
|
UNLOCK_DOMAIN(attrs, thr->group->domain);
|
||||||
|
|
||||||
|
if (timeout)
|
||||||
|
flush_local_pages();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (busy_now && !thr->busy_active && (++thr->busy_counter == 4))
|
||||||
|
bird_thread_busy_set(thr, 1);
|
||||||
|
|
||||||
|
if (!busy_now && thr->busy_active && (idle_force || (--thr->busy_counter == 0)))
|
||||||
|
{
|
||||||
|
thr->busy_counter = 0;
|
||||||
|
bird_thread_busy_set(thr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
account_to(&this_thread->idle);
|
account_to(&this_thread->idle);
|
||||||
birdloop_leave(thr->meta);
|
birdloop_leave(thr->meta);
|
||||||
|
@ -59,6 +59,8 @@ struct birdloop
|
|||||||
#define LTT_PING 1
|
#define LTT_PING 1
|
||||||
#define LTT_MOVE 2
|
#define LTT_MOVE 2
|
||||||
|
|
||||||
|
u64 last_transition_ns;
|
||||||
|
|
||||||
void (*stopped)(void *data);
|
void (*stopped)(void *data);
|
||||||
void *stop_data;
|
void *stop_data;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user