mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-09 20:58:44 +00:00
Locking subsystem: Just a global BIRD lock to begin with.
This commit is contained in:
parent
feb17ced23
commit
1db83a507a
@ -9,6 +9,7 @@
|
||||
#ifndef _BIRD_BIRDLIB_H_
|
||||
#define _BIRD_BIRDLIB_H_
|
||||
|
||||
#include "sysdep/config.h"
|
||||
#include "lib/alloca.h"
|
||||
|
||||
/* Ugly structure offset handling macros */
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#define _BIRD_LISTS_C_
|
||||
|
||||
#include "nest/bird.h"
|
||||
#include "lib/birdlib.h"
|
||||
#include "lib/lists.h"
|
||||
|
||||
LIST_INLINE int
|
||||
|
46
lib/locking.h
Normal file
46
lib/locking.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* BIRD Library -- Locking
|
||||
*
|
||||
* (c) 2020--2021 Maria Matejka <mq@jmq.cz>
|
||||
*
|
||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||
*/
|
||||
|
||||
#ifndef _BIRD_LOCKING_H_
|
||||
#define _BIRD_LOCKING_H_
|
||||
|
||||
struct domain_generic;
|
||||
|
||||
/* Here define the global lock order; first to last. */
|
||||
struct lock_order {
|
||||
struct domain_generic *the_bird;
|
||||
};
|
||||
|
||||
#define LOCK_ORDER_DEPTH (sizeof(struct lock_order) / sizeof(struct domain_generic *))
|
||||
|
||||
extern _Thread_local struct lock_order locking_stack;
|
||||
extern _Thread_local struct domain_generic **last_locked;
|
||||
|
||||
#define DOMAIN(type) struct domain__##type
|
||||
#define DEFINE_DOMAIN(type) DOMAIN(type) { struct domain_generic *type; }
|
||||
|
||||
#define DOMAIN_NEW(type, name) (DOMAIN(type)) { .type = domain_new(name) }
|
||||
struct domain_generic *domain_new(const char *name);
|
||||
|
||||
#define DOMAIN_NULL(type) (DOMAIN(type)) {}
|
||||
|
||||
#define LOCK_DOMAIN(type, d) do_lock(((d).type), &(locking_stack.type))
|
||||
#define UNLOCK_DOMAIN(type, d) do_unlock(((d).type), &(locking_stack.type))
|
||||
|
||||
/* Internal for locking */
|
||||
void do_lock(struct domain_generic *dg, struct domain_generic **lsp);
|
||||
void do_unlock(struct domain_generic *dg, struct domain_generic **lsp);
|
||||
|
||||
/* Use with care. To be removed in near future. */
|
||||
DEFINE_DOMAIN(the_bird);
|
||||
extern DOMAIN(the_bird) the_bird_domain;
|
||||
|
||||
#define the_bird_lock() LOCK_DOMAIN(the_bird, the_bird_domain)
|
||||
#define the_bird_unlock() UNLOCK_DOMAIN(the_bird, the_bird_domain)
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
src := alloc.c io.c krt.c log.c main.c random.c
|
||||
src := alloc.c io.c krt.c log.c main.c random.c coroutine.c
|
||||
obj := $(src-o-files)
|
||||
$(all-daemon)
|
||||
$(cf-local)
|
||||
|
102
sysdep/unix/coroutine.c
Normal file
102
sysdep/unix/coroutine.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* BIRD Coroutines
|
||||
*
|
||||
* (c) 2017 Martin Mares <mj@ucw.cz>
|
||||
* (c) 2020 Maria Matejka <mq@jmq.cz>
|
||||
*
|
||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#undef LOCAL_DEBUG
|
||||
|
||||
#undef DEBUG_LOCKING
|
||||
|
||||
#include "lib/birdlib.h"
|
||||
#include "lib/locking.h"
|
||||
#include "lib/resource.h"
|
||||
|
||||
/*
|
||||
* Implementation of coroutines based on POSIX threads
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* Locking subsystem
|
||||
*/
|
||||
|
||||
#define ASSERT_NO_LOCK ASSERT_DIE(last_locked == NULL)
|
||||
|
||||
struct domain_generic {
|
||||
pthread_mutex_t mutex;
|
||||
struct domain_generic **prev;
|
||||
struct lock_order *locked_by;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#define DOMAIN_INIT(_name) { .mutex = PTHREAD_MUTEX_INITIALIZER, .name = _name }
|
||||
|
||||
static struct domain_generic the_bird_domain_gen = DOMAIN_INIT("The BIRD");
|
||||
|
||||
DOMAIN(the_bird) the_bird_domain = { .the_bird = &the_bird_domain_gen };
|
||||
|
||||
struct domain_generic *
|
||||
domain_new(const char *name)
|
||||
{
|
||||
struct domain_generic *dg = xmalloc(sizeof(struct domain_generic));
|
||||
*dg = (struct domain_generic) DOMAIN_INIT(name);
|
||||
return dg;
|
||||
}
|
||||
|
||||
void
|
||||
domain_free(struct domain_generic *dg)
|
||||
{
|
||||
pthread_mutex_destroy(&dg->mutex);
|
||||
xfree(dg);
|
||||
}
|
||||
|
||||
_Thread_local struct lock_order locking_stack = {};
|
||||
_Thread_local struct domain_generic **last_locked = NULL;
|
||||
|
||||
void do_lock(struct domain_generic *dg, struct domain_generic **lsp)
|
||||
{
|
||||
if (lsp <= last_locked)
|
||||
bug("Trying to lock in a bad order");
|
||||
if (*lsp)
|
||||
bug("Inconsistent locking stack state on lock");
|
||||
|
||||
pthread_mutex_lock(&dg->mutex);
|
||||
|
||||
if (dg->prev || dg->locked_by)
|
||||
bug("Previous unlock not finished correctly");
|
||||
dg->prev = last_locked;
|
||||
*lsp = dg;
|
||||
last_locked = lsp;
|
||||
dg->locked_by = &locking_stack;
|
||||
}
|
||||
|
||||
void do_unlock(struct domain_generic *dg, struct domain_generic **lsp)
|
||||
{
|
||||
if (dg->locked_by != &locking_stack)
|
||||
bug("Inconsistent domain state on unlock");
|
||||
if ((last_locked != lsp) || (*lsp != dg))
|
||||
bug("Inconsistent locking stack state on unlock");
|
||||
dg->locked_by = NULL;
|
||||
last_locked = dg->prev;
|
||||
*lsp = NULL;
|
||||
dg->prev = NULL;
|
||||
pthread_mutex_unlock(&dg->mutex);
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "lib/resource.h"
|
||||
#include "lib/socket.h"
|
||||
#include "lib/event.h"
|
||||
#include "lib/locking.h"
|
||||
#include "lib/timer.h"
|
||||
#include "lib/string.h"
|
||||
#include "nest/iface.h"
|
||||
@ -2263,7 +2264,9 @@ io_loop(void)
|
||||
|
||||
/* And finally enter poll() to find active sockets */
|
||||
watchdog_stop();
|
||||
the_bird_unlock();
|
||||
pout = poll(pfd, nfds, poll_tout);
|
||||
the_bird_lock();
|
||||
watchdog_start();
|
||||
|
||||
if (pout < 0)
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "lib/resource.h"
|
||||
#include "lib/socket.h"
|
||||
#include "lib/event.h"
|
||||
#include "lib/locking.h"
|
||||
#include "lib/timer.h"
|
||||
#include "lib/string.h"
|
||||
#include "nest/route.h"
|
||||
@ -959,6 +960,8 @@ main(int argc, char **argv)
|
||||
dup2(0, 2);
|
||||
}
|
||||
|
||||
the_bird_lock();
|
||||
|
||||
main_thread_init();
|
||||
|
||||
write_pid_file();
|
||||
|
Loading…
Reference in New Issue
Block a user