0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-23 02:01:55 +00:00
bird/lib/event.h
Maria Matejka 84c298465f Decoupling loops from threads to allow fixed thread count
On large configurations, too many threads would spawn with one thread
per loop. Therefore, threads may now run multiple loops at once. The
thread count is configurable and may be changed during run. All threads
are spawned on startup.

This change helps with memory bloating. BIRD filters need large
temporary memory blocks to store their stack and also memory management
keeps its hot page storage per-thread.

Known bugs:
* Thread autobalancing is not yet implemented.
* Low latency loops are executed together with standard loops.
2023-01-19 11:13:50 +01:00

76 lines
1.8 KiB
C

/*
* BIRD Library -- Event Processing
*
* (c) 1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifndef _BIRD_EVENT_H_
#define _BIRD_EVENT_H_
#include "lib/resource.h"
#include "lib/locking.h"
#include <stdatomic.h>
struct birdloop;
typedef struct event {
resource r;
void (*hook)(void *);
void *data;
struct event * _Atomic next;
struct event_list * _Atomic list;
} event;
typedef struct event_list {
event * _Atomic receiver; /* Event receive list */
event * _Atomic _executor; /* Event execute list */
const char *name;
struct birdloop *loop; /* The executor loop */
} event_list;
extern event_list global_event_list;
extern event_list global_work_list;
event *ev_new(pool *);
void ev_run(event *);
void ev_init_list(event_list *, struct birdloop *loop, const char *name);
void ev_enqueue(event_list *, event *);
#define ev_send ev_enqueue
#define ev_send_loop(l, e) ev_send(birdloop_event_list((l)), (e))
#define ev_schedule(e) ({ ASSERT_THE_BIRD_LOCKED; if (!ev_active((e))) ev_send(&global_event_list, (e)); })
#define ev_schedule_work(e) ({ ASSERT_THE_BIRD_LOCKED; if (!ev_active((e))) ev_send(&global_work_list, (e)); })
void ev_postpone(event *);
int ev_run_list_limited(event_list *, uint);
#define ev_run_list(l) ev_run_list_limited((l), ~0)
#define LEGACY_EVENT_LIST(l) (((l) == &global_event_list) || ((l) == &global_work_list))
static inline int
ev_active(event *e)
{
return atomic_load_explicit(&e->list, memory_order_acquire) != NULL;
}
static inline event_list *
ev_get_list(event *e)
{
return atomic_load_explicit(&e->list, memory_order_acquire);
}
static inline event*
ev_new_init(pool *p, void (*hook)(void *), void *data)
{
event *e = ev_new(p);
e->hook = hook;
e->data = data;
return e;
}
#endif