extern struct birdloop main_birdloop;
+/* Currently running birdloop */
+extern _Thread_local struct birdloop *this_birdloop;
+
+/* Check that the task has enough time to do a bit more */
+_Bool task_still_in_limit(void);
+
/* Start a new birdloop owned by given pool and domain */
struct birdloop *birdloop_new(pool *p, uint order, btime max_latency, const char *fmt, ...);
#define NSEC_IN_SEC ((u64) (1000 * 1000 * 1000))
-static u64 ns_now(void)
+u64 ns_now(void)
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts))
account_to(&thr->overhead);
birdloop_enter(thr->meta);
+ this_birdloop = thr->meta;
tmp_init(thr->pool, birdloop_domain(thr->meta));
init_list(&thr->loops);
bird_thread_sync_all(&tsd->sync, bird_thread_show, cmd_show_threads_done, "Show Threads");
}
+_Bool task_still_in_limit(void)
+{
+ return ns_now() < account_last + this_thread->max_loop_time_ns;
+}
+
/*
* Birdloop
static struct bird_thread main_thread;
struct birdloop main_birdloop = { .thread = &main_thread, };
+_Thread_local struct birdloop *this_birdloop;
static void birdloop_enter_locked(struct birdloop *loop);
timers_init(&main_birdloop.time, &root_pool);
birdloop_enter_locked(&main_birdloop);
+ this_birdloop = &main_birdloop;
this_thread = &main_thread;
}
ASSERT_DIE(!ev_active(&loop->event));
loop->ping_pending = 0;
account_to(&this_thread->overhead);
+ this_birdloop = this_thread->meta;
birdloop_leave(loop);
/* Request local socket reload */
struct birdloop *loop = _loop;
account_to(&loop->locking);
birdloop_enter(loop);
+ this_birdloop = loop;
u64 dif = account_to(&loop->working);
if (dif > this_thread->max_loop_time_ns)
repeat += ev_run_list(&loop->event_list);
/* Check end time */
- } while (repeat && (ns_now() < account_last + this_thread->max_loop_time_ns));
+ } while (repeat && task_still_in_limit());
/* Request meta timer */
timer *t = timers_first(&loop->time);
loop->sock_changed = 0;
account_to(&this_thread->overhead);
+ this_birdloop = this_thread->meta;
birdloop_leave(loop);
}