Add a function to call rcu_barrier once per loop
isc_loop_rcu_barrier() sets a flag so that rcu_barrier() will be called at the end of the current loop tick. This allows us to minimize time spent synchronizing between threads.
This commit is contained in:
@@ -225,4 +225,14 @@ isc_loop_shuttingdown(isc_loop_t *loop);
|
||||
*
|
||||
* \li 'loop' is a valid loop and the loop tid matches the current tid.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_loop_rcu_barrier(isc_loop_t *loop);
|
||||
/*%<
|
||||
* Triggers an rcu_barrier() call at the end of the current loop tick.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* \li 'loop' is a valid loop and the loop tid matches the current tid.
|
||||
*/
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
@@ -236,7 +236,7 @@ loop_init(isc_loop_t *loop, isc_loopmgr_t *loopmgr, uint32_t tid) {
|
||||
|
||||
static void
|
||||
quiescent_cb(uv_prepare_t *handle) {
|
||||
UNUSED(handle);
|
||||
isc_loop_t *loop = uv_handle_get_data(handle);
|
||||
|
||||
#if defined(RCU_QSBR)
|
||||
/* safe memory reclamation */
|
||||
@@ -247,6 +247,10 @@ quiescent_cb(uv_prepare_t *handle) {
|
||||
#else
|
||||
INSIST(!rcu_read_ongoing());
|
||||
#endif
|
||||
|
||||
if (loop->rcu_barrier) {
|
||||
rcu_barrier();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -624,3 +628,11 @@ isc_loop_shuttingdown(isc_loop_t *loop) {
|
||||
|
||||
return (loop->shuttingdown);
|
||||
}
|
||||
|
||||
void
|
||||
isc_loop_rcu_barrier(isc_loop_t *loop) {
|
||||
REQUIRE(VALID_LOOP(loop));
|
||||
REQUIRE(loop->tid == isc_tid());
|
||||
|
||||
loop->rcu_barrier = true;
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ struct isc_loop {
|
||||
|
||||
/* safe memory reclamation */
|
||||
uv_prepare_t quiescent;
|
||||
|
||||
bool rcu_barrier;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user