mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Threads take loops faster
This commit is contained in:
parent
f606f44d1b
commit
6772db3a71
@ -589,8 +589,9 @@ struct birdloop_pickup_group {
|
|||||||
list loops;
|
list loops;
|
||||||
list threads;
|
list threads;
|
||||||
uint thread_count;
|
uint thread_count;
|
||||||
uint loop_count;
|
|
||||||
uint thread_busy_count;
|
uint thread_busy_count;
|
||||||
|
uint loop_count;
|
||||||
|
uint loop_unassigned_count;
|
||||||
btime max_latency;
|
btime max_latency;
|
||||||
event start_threads;
|
event start_threads;
|
||||||
} pickup_groups[2] = {
|
} pickup_groups[2] = {
|
||||||
@ -647,6 +648,9 @@ birdloop_set_thread(struct birdloop *loop, struct bird_thread *thr, struct birdl
|
|||||||
{
|
{
|
||||||
thr->loop_count++;
|
thr->loop_count++;
|
||||||
add_tail(&thr->loops, &loop->n);
|
add_tail(&thr->loops, &loop->n);
|
||||||
|
|
||||||
|
if (!EMPTY_LIST(loop->sock_list))
|
||||||
|
thr->sock_changed = 1;
|
||||||
ev_send_loop(loop->thread->meta, &loop->event);
|
ev_send_loop(loop->thread->meta, &loop->event);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -654,6 +658,7 @@ birdloop_set_thread(struct birdloop *loop, struct bird_thread *thr, struct birdl
|
|||||||
/* Put into pickup list */
|
/* Put into pickup list */
|
||||||
LOCK_DOMAIN(attrs, group->domain);
|
LOCK_DOMAIN(attrs, group->domain);
|
||||||
add_tail(&group->loops, &loop->n);
|
add_tail(&group->loops, &loop->n);
|
||||||
|
group->loop_unassigned_count++;
|
||||||
UNLOCK_DOMAIN(attrs, group->domain);
|
UNLOCK_DOMAIN(attrs, group->domain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -662,17 +667,15 @@ static void
|
|||||||
bird_thread_pickup_next(struct birdloop_pickup_group *group)
|
bird_thread_pickup_next(struct birdloop_pickup_group *group)
|
||||||
{
|
{
|
||||||
/* This thread goes to the end of the pickup list */
|
/* This thread goes to the end of the pickup list */
|
||||||
LOCK_DOMAIN(attrs, group->domain);
|
|
||||||
rem_node(&this_thread->n);
|
rem_node(&this_thread->n);
|
||||||
add_tail(&group->threads, &this_thread->n);
|
add_tail(&group->threads, &this_thread->n);
|
||||||
|
|
||||||
/* If there are more loops to be picked up, wakeup the next thread in order */
|
/* If there are more loops to be picked up, wakeup the next thread in order */
|
||||||
if (!EMPTY_LIST(group->loops))
|
if (!EMPTY_LIST(group->loops))
|
||||||
wakeup_do_kick(SKIP_BACK(struct bird_thread, n, HEAD(group->threads)));
|
wakeup_do_kick(SKIP_BACK(struct bird_thread, n, HEAD(group->threads)));
|
||||||
UNLOCK_DOMAIN(attrs, group->domain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct birdloop *
|
static void
|
||||||
birdloop_take(struct birdloop_pickup_group *group)
|
birdloop_take(struct birdloop_pickup_group *group)
|
||||||
{
|
{
|
||||||
struct birdloop *loop = NULL;
|
struct birdloop *loop = NULL;
|
||||||
@ -704,30 +707,44 @@ birdloop_take(struct birdloop_pickup_group *group)
|
|||||||
birdloop_set_thread(loop, NULL, group);
|
birdloop_set_thread(loop, NULL, group);
|
||||||
|
|
||||||
birdloop_leave(loop);
|
birdloop_leave(loop);
|
||||||
|
|
||||||
|
LOCK_DOMAIN(attrs, group->domain);
|
||||||
bird_thread_pickup_next(group);
|
bird_thread_pickup_next(group);
|
||||||
|
UNLOCK_DOMAIN(attrs, group->domain);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
birdloop_leave(loop);
|
birdloop_leave(loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
else if (take)
|
|
||||||
|
if (take)
|
||||||
|
{
|
||||||
|
/* Take a proportional amount of loops from the pickup list and unlock */
|
||||||
|
uint thread_count = group->thread_count + 1;
|
||||||
|
if (group->thread_busy_count < group->thread_count)
|
||||||
|
thread_count -= group->thread_busy_count;
|
||||||
|
|
||||||
|
uint assign = 1 + group->loop_unassigned_count / thread_count;
|
||||||
|
for (uint i=0; !EMPTY_LIST(group->loops) && i<assign; i++)
|
||||||
{
|
{
|
||||||
/* Take the first loop from the pickup list and unlock */
|
|
||||||
loop = SKIP_BACK(struct birdloop, n, HEAD(group->loops));
|
loop = SKIP_BACK(struct birdloop, n, HEAD(group->loops));
|
||||||
rem_node(&loop->n);
|
rem_node(&loop->n);
|
||||||
|
group->loop_unassigned_count--;
|
||||||
UNLOCK_DOMAIN(attrs, group->domain);
|
UNLOCK_DOMAIN(attrs, group->domain);
|
||||||
|
|
||||||
|
birdloop_enter(loop);
|
||||||
birdloop_set_thread(loop, this_thread, group);
|
birdloop_set_thread(loop, this_thread, group);
|
||||||
|
birdloop_leave(loop);
|
||||||
|
|
||||||
|
LOCK_DOMAIN(attrs, group->domain);
|
||||||
|
}
|
||||||
|
|
||||||
bird_thread_pickup_next(group);
|
bird_thread_pickup_next(group);
|
||||||
return loop;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
UNLOCK_DOMAIN(attrs, group->domain);
|
UNLOCK_DOMAIN(attrs, group->domain);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -800,14 +817,7 @@ bird_thread_main(void *arg)
|
|||||||
int timeout;
|
int timeout;
|
||||||
|
|
||||||
/* Pickup new loops */
|
/* Pickup new loops */
|
||||||
struct birdloop *loop = birdloop_take(thr->group);
|
birdloop_take(thr->group);
|
||||||
if (loop)
|
|
||||||
{
|
|
||||||
birdloop_enter(loop);
|
|
||||||
if (!EMPTY_LIST(loop->sock_list))
|
|
||||||
thr->sock_changed = 1;
|
|
||||||
birdloop_leave(loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Schedule all loops with timed out timers */
|
/* Schedule all loops with timed out timers */
|
||||||
timers_fire(&thr->meta->time, 0);
|
timers_fire(&thr->meta->time, 0);
|
||||||
@ -847,6 +857,7 @@ bird_thread_main(void *arg)
|
|||||||
pipe_pollin(&thr->wakeup, &pfd);
|
pipe_pollin(&thr->wakeup, &pfd);
|
||||||
|
|
||||||
node *nn;
|
node *nn;
|
||||||
|
struct birdloop *loop;
|
||||||
WALK_LIST2(loop, nn, thr->loops, n)
|
WALK_LIST2(loop, nn, thr->loops, n)
|
||||||
{
|
{
|
||||||
birdloop_enter(loop);
|
birdloop_enter(loop);
|
||||||
|
Loading…
Reference in New Issue
Block a user