mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 15:41:54 +00:00
Fix loop dropping routines
This commit is contained in:
parent
a95141111c
commit
e0c09e6bee
@ -631,14 +631,12 @@ birdloop_set_thread(struct birdloop *loop, struct bird_thread *thr, struct birdl
|
|||||||
/* Put into appropriate lists */
|
/* Put into appropriate lists */
|
||||||
if (thr)
|
if (thr)
|
||||||
{
|
{
|
||||||
add_tail(&thr->loops, &loop->n);
|
|
||||||
thr->loop_count++;
|
thr->loop_count++;
|
||||||
|
add_tail(&thr->loops, &loop->n);
|
||||||
ev_send_loop(loop->thread->meta, &loop->event);
|
ev_send_loop(loop->thread->meta, &loop->event);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
old->loop_count--;
|
|
||||||
|
|
||||||
/* Unschedule from Meta */
|
/* Unschedule from Meta */
|
||||||
ev_postpone(&loop->event);
|
ev_postpone(&loop->event);
|
||||||
tm_stop(&loop->timer);
|
tm_stop(&loop->timer);
|
||||||
@ -686,18 +684,27 @@ birdloop_take(struct birdloop_pickup_group *group)
|
|||||||
if (drop)
|
if (drop)
|
||||||
{
|
{
|
||||||
UNLOCK_DOMAIN(resource, group->domain);
|
UNLOCK_DOMAIN(resource, group->domain);
|
||||||
|
|
||||||
node *n;
|
node *n;
|
||||||
WALK_LIST2(loop, n, this_thread->loops, n)
|
WALK_LIST2(loop, n, this_thread->loops, n)
|
||||||
|
{
|
||||||
|
birdloop_enter(loop);
|
||||||
if (ev_active(&loop->event))
|
if (ev_active(&loop->event))
|
||||||
{
|
{
|
||||||
LOOP_TRACE(loop, "Moving to another thread");
|
LOOP_TRACE(loop, "Moving to another thread");
|
||||||
|
|
||||||
/* Pass to another thread */
|
/* Pass to another thread */
|
||||||
rem_node(&loop->n);
|
rem_node(&loop->n);
|
||||||
|
this_thread->loop_count--;
|
||||||
|
|
||||||
|
/* This also unschedules the loop from Meta */
|
||||||
birdloop_set_thread(loop, NULL, group);
|
birdloop_set_thread(loop, NULL, group);
|
||||||
|
|
||||||
|
birdloop_leave(loop);
|
||||||
bird_thread_pickup_next(group);
|
bird_thread_pickup_next(group);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
birdloop_leave(loop);
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -731,37 +738,36 @@ poll_timeout(struct birdloop *loop)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bird_thread_busy_update(struct bird_thread *thr, int val)
|
bird_thread_busy_set(struct bird_thread *thr, int val)
|
||||||
{
|
{
|
||||||
if (thr->busy_active == val)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (val)
|
|
||||||
thr->busy_counter++;
|
|
||||||
else
|
|
||||||
thr->busy_counter--;
|
|
||||||
|
|
||||||
switch (thr->busy_counter)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
thr->busy_active = 0;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
thr->busy_active = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCK_DOMAIN(resource, thr->group->domain);
|
LOCK_DOMAIN(resource, thr->group->domain);
|
||||||
if (val)
|
if (thr->busy_active = val)
|
||||||
thr->group->thread_busy_count++;
|
thr->group->thread_busy_count++;
|
||||||
else
|
else
|
||||||
thr->group->thread_busy_count--;
|
thr->group->thread_busy_count--;
|
||||||
|
ASSERT_DIE(thr->group->thread_busy_count <= thr->group->thread_count);
|
||||||
UNLOCK_DOMAIN(resource, thr->group->domain);
|
UNLOCK_DOMAIN(resource, 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)
|
||||||
{
|
{
|
||||||
@ -847,10 +853,10 @@ bird_thread_main(void *arg)
|
|||||||
ASSERT_DIE(pfd.loop.used == pfd.pfd.used);
|
ASSERT_DIE(pfd.loop.used == pfd.pfd.used);
|
||||||
}
|
}
|
||||||
/* Nothing to do in at least 5 seconds, flush local hot page cache */
|
/* Nothing to do in at least 5 seconds, flush local hot page cache */
|
||||||
else if (timeout > 5000)
|
else if ((timeout > 5000) && (timeout < 0))
|
||||||
flush_local_pages();
|
flush_local_pages();
|
||||||
|
|
||||||
bird_thread_busy_update(thr, (timeout == 0));
|
bird_thread_busy_update(thr, timeout);
|
||||||
|
|
||||||
account_to(&this_thread->idle);
|
account_to(&this_thread->idle);
|
||||||
poll_retry:;
|
poll_retry:;
|
||||||
@ -893,11 +899,12 @@ bird_thread_cleanup(void *_thr)
|
|||||||
struct bird_thread *thr = _thr;
|
struct bird_thread *thr = _thr;
|
||||||
ASSERT_DIE(birdloop_inside(&main_birdloop));
|
ASSERT_DIE(birdloop_inside(&main_birdloop));
|
||||||
|
|
||||||
|
/* Free the meta loop */
|
||||||
|
thr->meta->thread = NULL;
|
||||||
|
birdloop_free(thr->meta);
|
||||||
|
|
||||||
/* Thread attributes no longer needed */
|
/* Thread attributes no longer needed */
|
||||||
pthread_attr_destroy(&thr->thread_attr);
|
pthread_attr_destroy(&thr->thread_attr);
|
||||||
|
|
||||||
/* Free all remaining memory */
|
|
||||||
rp_free(thr->pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bird_thread *
|
static struct bird_thread *
|
||||||
@ -958,6 +965,13 @@ static struct birdloop *thread_dropper;
|
|||||||
static event *thread_dropper_event;
|
static event *thread_dropper_event;
|
||||||
static uint thread_dropper_goal;
|
static uint thread_dropper_goal;
|
||||||
|
|
||||||
|
static void
|
||||||
|
bird_thread_dropper_free(void *data)
|
||||||
|
{
|
||||||
|
struct birdloop *tdl_stop = data;
|
||||||
|
birdloop_free(tdl_stop);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bird_thread_shutdown(void * _ UNUSED)
|
bird_thread_shutdown(void * _ UNUSED)
|
||||||
{
|
{
|
||||||
@ -980,35 +994,37 @@ bird_thread_shutdown(void * _ UNUSED)
|
|||||||
|
|
||||||
if (tdl_stop)
|
if (tdl_stop)
|
||||||
{
|
{
|
||||||
birdloop_stop_self(tdl_stop, NULL, NULL);
|
birdloop_stop_self(tdl_stop, bird_thread_dropper_free, tdl_stop);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bird_thread *thr = this_thread;
|
struct bird_thread *thr = this_thread;
|
||||||
|
|
||||||
/* Leave the thread-picker list to get no more loops */
|
|
||||||
LOCK_DOMAIN(resource, group->domain);
|
LOCK_DOMAIN(resource, group->domain);
|
||||||
|
/* Leave the thread-picker list to get no more loops */
|
||||||
rem_node(&thr->n);
|
rem_node(&thr->n);
|
||||||
group->thread_count--;
|
group->thread_count--;
|
||||||
|
|
||||||
|
/* Fix the busy count */
|
||||||
|
if (thr->busy_active)
|
||||||
|
group->thread_busy_count--;
|
||||||
|
|
||||||
UNLOCK_DOMAIN(resource, group->domain);
|
UNLOCK_DOMAIN(resource, group->domain);
|
||||||
|
|
||||||
|
/* Leave the thread-dropper loop as we aren't going to return. */
|
||||||
|
birdloop_leave(thread_dropper);
|
||||||
|
|
||||||
/* Drop loops including the thread dropper itself */
|
/* Drop loops including the thread dropper itself */
|
||||||
while (!EMPTY_LIST(thr->loops))
|
while (!EMPTY_LIST(thr->loops))
|
||||||
{
|
{
|
||||||
struct birdloop *loop = HEAD(thr->loops);
|
struct birdloop *loop = HEAD(thr->loops);
|
||||||
|
|
||||||
/* Remove loop from this thread's list */
|
/* Remove loop from this thread's list */
|
||||||
|
this_thread->loop_count--;
|
||||||
rem_node(&loop->n);
|
rem_node(&loop->n);
|
||||||
|
|
||||||
/* Unset loop's thread */
|
/* Unset loop's thread */
|
||||||
if (birdloop_inside(loop))
|
birdloop_set_thread(loop, NULL, group);
|
||||||
birdloop_set_thread(loop, NULL, group);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
birdloop_enter(loop);
|
|
||||||
birdloop_set_thread(loop, NULL, group);
|
|
||||||
birdloop_leave(loop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let others know about new loops */
|
/* Let others know about new loops */
|
||||||
@ -1017,13 +1033,8 @@ bird_thread_shutdown(void * _ UNUSED)
|
|||||||
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(resource, group->domain);
|
UNLOCK_DOMAIN(resource, group->domain);
|
||||||
|
|
||||||
/* Leave the thread-dropper loop as we aren't going to return. */
|
|
||||||
birdloop_leave(thread_dropper);
|
|
||||||
|
|
||||||
/* Stop the meta loop */
|
/* Stop the meta loop */
|
||||||
birdloop_leave(thr->meta);
|
birdloop_leave(thr->meta);
|
||||||
domain_free(thr->meta->time.domain);
|
|
||||||
rp_free(thr->meta->pool);
|
|
||||||
|
|
||||||
/* Local pages not needed anymore */
|
/* Local pages not needed anymore */
|
||||||
flush_local_pages();
|
flush_local_pages();
|
||||||
@ -1038,7 +1049,6 @@ bird_thread_shutdown(void * _ UNUSED)
|
|||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
bird_thread_commit(struct config *new, struct config *old UNUSED)
|
bird_thread_commit(struct config *new, struct config *old UNUSED)
|
||||||
{
|
{
|
||||||
@ -1069,6 +1079,7 @@ bird_thread_commit(struct config *new, struct config *old UNUSED)
|
|||||||
if ((dif > 0) && !thread_dropper_running)
|
if ((dif > 0) && !thread_dropper_running)
|
||||||
{
|
{
|
||||||
struct birdloop *tdl = birdloop_new(&root_pool, DOMAIN_ORDER(control), group->max_latency, "Thread dropper");
|
struct birdloop *tdl = birdloop_new(&root_pool, DOMAIN_ORDER(control), group->max_latency, "Thread dropper");
|
||||||
|
birdloop_enter(tdl);
|
||||||
event *tde = ev_new_init(tdl->pool, bird_thread_shutdown, NULL);
|
event *tde = ev_new_init(tdl->pool, bird_thread_shutdown, NULL);
|
||||||
|
|
||||||
LOCK_DOMAIN(resource, group->domain);
|
LOCK_DOMAIN(resource, group->domain);
|
||||||
@ -1077,6 +1088,7 @@ bird_thread_commit(struct config *new, struct config *old UNUSED)
|
|||||||
UNLOCK_DOMAIN(resource, group->domain);
|
UNLOCK_DOMAIN(resource, group->domain);
|
||||||
|
|
||||||
ev_send_loop(thread_dropper, thread_dropper_event);
|
ev_send_loop(thread_dropper, thread_dropper_event);
|
||||||
|
birdloop_leave(tdl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -1148,7 +1160,7 @@ bird_thread_show(void *data)
|
|||||||
|
|
||||||
LOCK_DOMAIN(control, tsd->lock);
|
LOCK_DOMAIN(control, tsd->lock);
|
||||||
if (tsd->show_loops)
|
if (tsd->show_loops)
|
||||||
tsd_append("Thread %p", this_thread);
|
tsd_append("Thread %p%s (busy counter %d)", this_thread, this_thread->busy_active ? " [busy]" : "", this_thread->busy_counter);
|
||||||
|
|
||||||
u64 total_time_ns = 0;
|
u64 total_time_ns = 0;
|
||||||
struct birdloop *loop;
|
struct birdloop *loop;
|
||||||
|
Loading…
Reference in New Issue
Block a user