Browse Source

uasync: fix stall detection — record timestamp after poll wait, not before

topo_upd
Evgeny 2 months ago
parent
commit
a47ef86810
  1. 14
      lib/u_async.c
  2. 2
      lib/u_async.h

14
lib/u_async.c

@ -985,11 +985,10 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
if (!ua->sockets || !ua->timeout_heap) return; if (!ua->sockets || !ua->timeout_heap) return;
uint64_t now_us_poll_entry = get_time_us(); uint64_t now_us_poll_entry = get_time_us();
if (ua->last_poll_entry_us && now_us_poll_entry - ua->last_poll_entry_us > 10000) { if (ua->last_poll_exit_us && now_us_poll_entry - ua->last_poll_exit_us > 10000) {
DEBUG_WARN(DEBUG_CATEGORY_UASYNC, "Event loop stall: %lluus since last poll entry", DEBUG_WARN(DEBUG_CATEGORY_UASYNC, "Event loop stall: %lluus since end of last poll processing",
(unsigned long long)(now_us_poll_entry - ua->last_poll_entry_us)); (unsigned long long)(now_us_poll_entry - ua->last_poll_exit_us));
} }
ua->last_poll_entry_us = now_us_poll_entry;
DEBUG_DEBUG(DEBUG_CATEGORY_UASYNC, "poll(%d sockets, %zu timers, timeout=%d.%dms)", DEBUG_DEBUG(DEBUG_CATEGORY_UASYNC, "poll(%d sockets, %zu timers, timeout=%d.%dms)",
ua->sockets->count, ua->timeout_heap->size, timeout_tb >= 0 ? timeout_tb / 10000 : -1, ua->sockets->count, ua->timeout_heap->size, timeout_tb >= 0 ? timeout_tb / 10000 : -1,
@ -1040,6 +1039,7 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
timeout_ms = (poll_timeout.tv_sec * 1000) + (poll_timeout.tv_usec / 1000); timeout_ms = (poll_timeout.tv_sec * 1000) + (poll_timeout.tv_usec / 1000);
} else { } else {
// Nothing to do - return immediately // Nothing to do - return immediately
ua->last_poll_exit_us = get_time_us();
return; return;
} }
} }
@ -1051,6 +1051,7 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
int max_events = 64; int max_events = 64;
int ret = epoll_wait(ua->epoll_fd, events, max_events, timeout_ms); int ret = epoll_wait(ua->epoll_fd, events, max_events, timeout_ms);
ua->last_poll_exit_us = get_time_us();
if (ret < 0) { if (ret < 0) {
if (errno == EINTR) { if (errno == EINTR) {
return; return;
@ -1086,6 +1087,7 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
nanosleep(&ts, NULL); nanosleep(&ts, NULL);
#endif #endif
} }
ua->last_poll_exit_us = get_time_us();
process_timeouts(ua); process_timeouts(ua);
return; return;
} }
@ -1129,6 +1131,7 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
tv.tv_usec = (timeout_ms % 1000) * 1000; tv.tv_usec = (timeout_ms % 1000) * 1000;
int ret = select((int)max_fd + 1, &read_fds, &write_fds, &except_fds, &tv); int ret = select((int)max_fd + 1, &read_fds, &write_fds, &except_fds, &tv);
ua->last_poll_exit_us = get_time_us();
if (ret < 0) { if (ret < 0) {
int err = WSAGetLastError(); int err = WSAGetLastError();
@ -1203,6 +1206,7 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
} }
int ret = poll(ua->poll_fds, ua->poll_fds_count, timeout_ms); int ret = poll(ua->poll_fds, ua->poll_fds_count, timeout_ms);
ua->last_poll_exit_us = get_time_us();
if (ret < 0) { if (ret < 0) {
if (errno == EINTR) { if (errno == EINTR) {
return; return;
@ -1327,7 +1331,7 @@ struct UASYNC* uasync_create(void) {
ua->posted_tasks_head = NULL; ua->posted_tasks_head = NULL;
ua->immediate_queue_head = NULL; ua->immediate_queue_head = NULL;
ua->immediate_queue_tail = NULL; ua->immediate_queue_tail = NULL;
ua->last_poll_entry_us = 0; ua->last_poll_exit_us = 0;
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "Creating SA..."); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "Creating SA...");
ua->sockets = socket_array_create(16); ua->sockets = socket_array_create(16);

2
lib/u_async.h

@ -75,7 +75,7 @@ struct UASYNC {
pthread_mutex_t posted_lock; pthread_mutex_t posted_lock;
#endif #endif
volatile sig_atomic_t stop; volatile sig_atomic_t stop;
uint64_t last_poll_entry_us; uint64_t last_poll_exit_us;
}; };
// Type definitions // Type definitions

Loading…
Cancel
Save