diff options
author | Frediano Ziglio <fziglio@redhat.com> | 2016-01-22 09:57:56 +0000 |
---|---|---|
committer | Frediano Ziglio <freddy77@gmail.com> | 2023-11-22 07:38:54 +0000 |
commit | 893608e16c29fe2a74a7f7b1756a4c1500348bd0 (patch) | |
tree | 530bbcad3ed05bf68d3cf7831de4666052429bdc /server | |
parent | 820d0d4f0db8b98ce826c84f246c05be6ca97774 (diff) |
try to understand where the wakeups came from
Diffstat (limited to 'server')
-rw-r--r-- | server/event-loop.c | 11 | ||||
-rw-r--r-- | server/red-worker.cpp | 67 | ||||
-rw-r--r-- | server/video-stream.cpp | 3 |
3 files changed, 76 insertions, 5 deletions
diff --git a/server/event-loop.c b/server/event-loop.c index e5291b5a..d295e42e 100644 --- a/server/event-loop.c +++ b/server/event-loop.c @@ -86,6 +86,11 @@ typedef struct SpiceTimerGlib { GSource *source; } SpiceTimerGlib; +bool got_event_watch; +bool got_event_watch_read; +bool got_event_watch_write; +bool got_event_timeout; + static SpiceTimer* timer_add(const SpiceCoreInterfaceInternal *iface, SpiceTimerFunc func, void *opaque) { @@ -103,6 +108,7 @@ static gboolean timer_func(gpointer user_data) { SpiceTimerGlib *timer = (SpiceTimerGlib*) user_data; + got_event_timeout = true; timer->func(timer->opaque); /* timer might be free after func(), don't touch */ @@ -183,6 +189,11 @@ static gboolean watch_func(GIOChannel *source, GIOCondition condition, // this works also under Windows despite the name int fd = g_io_channel_unix_get_fd(source); + got_event_watch = true; + if (condition & G_IO_IN) + got_event_watch_read = true; + if (condition & G_IO_OUT) + got_event_watch_write = true; watch->func(fd, giocondition_to_spice_event(condition), watch->opaque); return TRUE; diff --git a/server/red-worker.cpp b/server/red-worker.cpp index 912b7d55..cf9808c8 100644 --- a/server/red-worker.cpp +++ b/server/red-worker.cpp @@ -750,11 +750,22 @@ handle_dev_loadvm_commands(RedWorker* worker, RedWorkerMessageLoadvmCommands* ms } } +bool got_event_notify; +bool got_event_dispatch; + static void worker_dispatcher_record(void *opaque, uint32_t message_type, void *payload) { auto worker = static_cast<RedWorker *>(opaque); - red_record_event(worker->record, 1, message_type); + if (message_type == RED_WORKER_MESSAGE_WAKEUP) { + got_event_notify = true; + } else { + got_event_dispatch = true; + } + + if (worker->record) { + red_record_event(worker->record, 1, message_type); + } } template <typename T> @@ -873,18 +884,57 @@ struct RedWorkerSource { RedWorker *worker; }; +#define ALL_LOOP_EVENTS \ + LOOP_EVENT(any) \ + LOOP_EVENT(timeout) \ + LOOP_EVENT(stream_timeout) \ + LOOP_EVENT(watch) \ + LOOP_EVENT(watch_read) \ + LOOP_EVENT(watch_write) \ + LOOP_EVENT(dispatch) \ + LOOP_EVENT(notify) + +#define LOOP_EVENT(name) extern bool got_event_ ## name; +ALL_LOOP_EVENTS +#undef LOOP_EVENT + +typedef struct WakeupEvent { + const char *name; + bool *p_got_event; + RedStatCounter counter; +} WakeupEvent; +static WakeupEvent wakeup_events[] = { +#define LOOP_EVENT(name) { #name, &got_event_ ## name, {} }, + ALL_LOOP_EVENTS +#undef LOOP_EVENT +}; + +bool got_event_any; +bool got_event_stream_timeout; + static gboolean worker_source_prepare(GSource *source, gint *p_timeout) { RedWorkerSource *wsource = SPICE_CONTAINEROF(source, RedWorkerSource, source); RedWorker *worker = wsource->worker; unsigned int timeout; + for (int i = 0; i < G_N_ELEMENTS(wakeup_events); ++i) { + const WakeupEvent *ev = &wakeup_events[i]; + if (*ev->p_got_event) { + stat_inc_counter(ev->counter, 1); + } + *ev->p_got_event = false; + } + got_event_any = true; + timeout = MIN(worker->event_timeout, display_channel_get_streams_timeout(worker->display_channel)); *p_timeout = (timeout == INF_EVENT_WAIT) ? -1 : timeout; - if (*p_timeout == 0) + if (*p_timeout == 0) { + got_event_stream_timeout = true; return TRUE; + } if (worker->was_blocked && !red_process_is_blocked(worker)) { return TRUE; @@ -953,9 +1003,7 @@ RedWorker* red_worker_new(QXLInstance *qxl) worker->qxl = qxl; register_callbacks(dispatcher); - if (worker->record) { - dispatcher->register_universal_handler(worker_dispatcher_record); - } + dispatcher->register_universal_handler(worker_dispatcher_record); worker->driver_cap_monitors_config = false; char worker_str[SPICE_STAT_NODE_NAME_MAX]; @@ -966,6 +1014,15 @@ RedWorker* red_worker_new(QXLInstance *qxl) stat_init_counter(&worker->full_loop_counter, reds, &worker->stat, "full_loops", TRUE); stat_init_counter(&worker->total_loop_counter, reds, &worker->stat, "total_loops", TRUE); + { + RedStatNode node; + stat_init_node(&node, reds, NULL, "wakeups", TRUE); + for (int i = 0; i < G_N_ELEMENTS(wakeup_events); ++i) { + WakeupEvent *ev = &wakeup_events[i]; + stat_init_counter(&ev->counter, reds, &node, ev->name, TRUE); + } + } + worker->dispatch_watch = dispatcher->create_watch(&worker->core); spice_assert(worker->dispatch_watch != nullptr); diff --git a/server/video-stream.cpp b/server/video-stream.cpp index 056d0c31..62a96bce 100644 --- a/server/video-stream.cpp +++ b/server/video-stream.cpp @@ -930,6 +930,8 @@ void video_stream_detach_and_stop(DisplayChannel *display) } } +extern bool got_event_stream_timeout; + void video_stream_timeout(DisplayChannel *display) { Ring *ring = &display->priv->streams; @@ -941,6 +943,7 @@ void video_stream_timeout(DisplayChannel *display) VideoStream *stream = SPICE_CONTAINEROF(item, VideoStream, link); item = ring_next(ring, item); if (now >= (stream->last_time + RED_STREAM_TIMEOUT)) { + got_event_stream_timeout = true; detach_video_stream_gracefully(display, stream, nullptr); video_stream_stop(display, stream); } |