Skip to content

Commit

Permalink
Add config parameters for reactor locking spin counts.
Browse files Browse the repository at this point in the history
Added:
  "reactor" / "registration_locking_spin_count" (int)
  "reactor" / "io_locking_spin_count" (int)

Both values default to 0.
  • Loading branch information
chriskohlhoff committed Nov 5, 2024
1 parent 13a6d87 commit 62481a2
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 17 deletions.
6 changes: 6 additions & 0 deletions asio/include/asio/detail/conditionally_enabled_mutex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ class conditionally_enabled_mutex
return enabled_;
}

// Get the spin count.
int spin_count() const
{
return spin_count_;
}

// Lock the mutex.
void lock()
{
Expand Down
5 changes: 4 additions & 1 deletion asio/include/asio/detail/epoll_reactor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class epoll_reactor
bool try_speculative_[max_ops];
bool shutdown_;

ASIO_DECL descriptor_state(bool locking);
ASIO_DECL descriptor_state(bool locking, int spin_count);
void set_ready_events(uint32_t events) { task_result_ = events; }
void add_ready_events(uint32_t events) { task_result_ |= events; }
ASIO_DECL operation* perform_io(uint32_t events);
Expand Down Expand Up @@ -272,6 +272,9 @@ class epoll_reactor
// Whether I/O locking is enabled.
const bool io_locking_;

// How any times to spin waiting for the I/O mutex.
const int io_locking_spin_count_;

// Mutex to protect access to the registered descriptors.
mutex registered_descriptors_mutex_;

Expand Down
16 changes: 10 additions & 6 deletions asio/include/asio/detail/impl/epoll_reactor.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,19 @@ namespace detail {
epoll_reactor::epoll_reactor(asio::execution_context& ctx)
: execution_context_service_base<epoll_reactor>(ctx),
scheduler_(use_service<scheduler>(ctx)),
mutex_(config(ctx).get("reactor", "registration_locking", true)),
mutex_(config(ctx).get("reactor", "registration_locking", true),
config(ctx).get("reactor", "registration_locking_spin_count", 0)),
interrupter_(),
epoll_fd_(do_epoll_create()),
timer_fd_(do_timerfd_create()),
shutdown_(false),
io_locking_(config(ctx).get("reactor", "io_locking", true)),
registered_descriptors_mutex_(mutex_.enabled()),
io_locking_spin_count_(
config(ctx).get("reactor", "io_locking_spin_count", 0)),
registered_descriptors_mutex_(mutex_.enabled(), mutex_.spin_count()),
registered_descriptors_(
config(ctx).get("reactor", "preallocated_io_objects", 0U), io_locking_)
config(ctx).get("reactor", "preallocated_io_objects", 0U),
io_locking_, io_locking_spin_count_)
{
// Add the interrupter's descriptor to epoll.
epoll_event ev = { 0, { 0 } };
Expand Down Expand Up @@ -670,7 +674,7 @@ int epoll_reactor::do_timerfd_create()
epoll_reactor::descriptor_state* epoll_reactor::allocate_descriptor_state()
{
mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
return registered_descriptors_.alloc(io_locking_);
return registered_descriptors_.alloc(io_locking_, io_locking_spin_count_);
}

void epoll_reactor::free_descriptor_state(epoll_reactor::descriptor_state* s)
Expand Down Expand Up @@ -762,9 +766,9 @@ struct epoll_reactor::perform_io_cleanup_on_block_exit
operation* first_op_;
};

epoll_reactor::descriptor_state::descriptor_state(bool locking)
epoll_reactor::descriptor_state::descriptor_state(bool locking, int spin_count)
: operation(&epoll_reactor::descriptor_state::do_complete),
mutex_(locking)
mutex_(locking, spin_count)
{
}

Expand Down
14 changes: 9 additions & 5 deletions asio/include/asio/detail/impl/io_uring_service.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,21 @@ namespace detail {
io_uring_service::io_uring_service(asio::execution_context& ctx)
: execution_context_service_base<io_uring_service>(ctx),
scheduler_(use_service<scheduler>(ctx)),
mutex_(config(ctx).get("reactor", "registration_locking", true)),
mutex_(config(ctx).get("reactor", "registration_locking", true),
config(ctx).get("reactor", "registration_locking_spin_count", 0)),
outstanding_work_(0),
submit_sqes_op_(this),
pending_sqes_(0),
pending_submit_sqes_op_(false),
shutdown_(false),
io_locking_(config(ctx).get("reactor", "io_locking", true)),
io_locking_spin_count_(
config(ctx).get("reactor", "io_locking_spin_count", 0)),
timeout_(),
registration_mutex_(mutex_.enabled()),
registered_io_objects_(
config(ctx).get("reactor", "preallocated_io_objects", 0U), io_locking_),
config(ctx).get("reactor", "preallocated_io_objects", 0U),
io_locking_, io_locking_spin_count_),
reactor_(use_service<reactor>(ctx)),
reactor_data_(),
event_fd_(-1)
Expand Down Expand Up @@ -614,7 +618,7 @@ void io_uring_service::register_with_reactor()
io_uring_service::io_object* io_uring_service::allocate_io_object()
{
mutex::scoped_lock registration_lock(registration_mutex_);
return registered_io_objects_.alloc(io_locking_);
return registered_io_objects_.alloc(io_locking_, io_locking_spin_count_);
}

void io_uring_service::free_io_object(io_uring_service::io_object* io_obj)
Expand Down Expand Up @@ -899,8 +903,8 @@ void io_uring_service::io_queue::do_complete(void* owner, operation* base,
}
}

io_uring_service::io_object::io_object(bool locking)
: mutex_(locking)
io_uring_service::io_object::io_object(bool locking, int spin_count)
: mutex_(locking, spin_count)
{
}

Expand Down
10 changes: 7 additions & 3 deletions asio/include/asio/detail/impl/kqueue_reactor.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,18 @@ namespace detail {
kqueue_reactor::kqueue_reactor(asio::execution_context& ctx)
: execution_context_service_base<kqueue_reactor>(ctx),
scheduler_(use_service<scheduler>(ctx)),
mutex_(config(ctx).get("reactor", "registration_locking", true)),
mutex_(config(ctx).get("reactor", "registration_locking", true),
config(ctx).get("reactor", "registration_locking_spin_count", 0)),
kqueue_fd_(do_kqueue_create()),
interrupter_(),
shutdown_(false),
io_locking_(config(ctx).get("reactor", "io_locking", true)),
io_locking_spin_count_(
config(ctx).get("reactor", "io_locking_spin_count", 0)),
registered_descriptors_mutex_(mutex_.enabled()),
registered_descriptors_(
config(ctx).get("reactor", "preallocated_io_objects", 0U), io_locking_)
config(ctx).get("reactor", "preallocated_io_objects", 0U),
io_locking_, io_locking_spin_count_)
{
struct kevent events[1];
ASIO_KQUEUE_EV_SET(&events[0], interrupter_.read_descriptor(),
Expand Down Expand Up @@ -565,7 +569,7 @@ int kqueue_reactor::do_kqueue_create()
kqueue_reactor::descriptor_state* kqueue_reactor::allocate_descriptor_state()
{
mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
return registered_descriptors_.alloc(io_locking_);
return registered_descriptors_.alloc(io_locking_, io_locking_spin_count_);
}

void kqueue_reactor::free_descriptor_state(kqueue_reactor::descriptor_state* s)
Expand Down
5 changes: 4 additions & 1 deletion asio/include/asio/detail/io_uring_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class io_uring_service
io_queue queues_[max_ops];
bool shutdown_;

ASIO_DECL io_object(bool locking);
ASIO_DECL io_object(bool locking, int spin_count);
};

// Per I/O object data.
Expand Down Expand Up @@ -280,6 +280,9 @@ class io_uring_service
// Whether I/O locking is enabled.
const bool io_locking_;

// How any times to spin waiting for the I/O mutex.
const int io_locking_spin_count_;

// The timer queues.
timer_queue_set timer_queues_;

Expand Down
6 changes: 5 additions & 1 deletion asio/include/asio/detail/kqueue_reactor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ class kqueue_reactor
// Per-descriptor queues.
struct descriptor_state
{
descriptor_state(bool locking) : mutex_(locking) {}
descriptor_state(bool locking, int spin_count)
: mutex_(locking, spin_count) {}

friend class kqueue_reactor;
friend class object_pool_access;
Expand Down Expand Up @@ -252,6 +253,9 @@ class kqueue_reactor
// Whether I/O locking is enabled.
const bool io_locking_;

// How any times to spin waiting for the I/O mutex.
const int io_locking_spin_count_;

// Mutex to protect access to the registered descriptors.
mutex registered_descriptors_mutex_;

Expand Down

0 comments on commit 62481a2

Please sign in to comment.