From 5d61a504c6d395914d78f97e82f6fd0fdf0f98a0 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 19 Aug 2011 20:44:21 -0400 Subject: [PATCH] Add wakeup on subbuffer delivery Signed-off-by: Mathieu Desnoyers --- libringbuffer/frontend_internal.h | 15 ++++++++++-- libringbuffer/frontend_types.h | 2 ++ libringbuffer/ring_buffer_backend.c | 1 + libringbuffer/shm.c | 6 +++++ libringbuffer/shm.h | 29 ++++++++++++++++++++++++ libust/ltt-ring-buffer-client.h | 8 +++---- libust/ltt-ring-buffer-metadata-client.h | 6 ++--- 7 files changed, 58 insertions(+), 9 deletions(-) diff --git a/libringbuffer/frontend_internal.h b/libringbuffer/frontend_internal.h index 73b44726..c60affe0 100644 --- a/libringbuffer/frontend_internal.h +++ b/libringbuffer/frontend_internal.h @@ -378,8 +378,19 @@ void lib_ring_buffer_check_deliver(const struct lib_ring_buffer_config *config, if (config->wakeup == RING_BUFFER_WAKEUP_BY_WRITER && uatomic_read(&buf->active_readers) && lib_ring_buffer_poll_deliver(config, buf, chan, handle)) { - //wake_up_interruptible(&buf->read_wait); - //wake_up_interruptible(&chan->read_wait); + int wakeup_fd = shm_get_wakeup_fd(handle, &buf->self._ref); + + if (wakeup_fd >= 0) { + int ret; + /* + * Wake-up the other end by + * writing a null byte in the + * pipe (non-blocking). + */ + do { + ret = write(wakeup_fd, "", 1); + } while (ret == -1L && errno == EINTR); + } } } diff --git a/libringbuffer/frontend_types.h b/libringbuffer/frontend_types.h index 974f782e..ad7848c8 100644 --- a/libringbuffer/frontend_types.h +++ b/libringbuffer/frontend_types.h @@ -103,6 +103,8 @@ struct lib_ring_buffer { int get_subbuf:1; /* Sub-buffer being held by reader */ int switch_timer_enabled:1; /* Protected by ring_buffer_nohz_lock */ int read_timer_enabled:1; /* Protected by ring_buffer_nohz_lock */ + /* shmp pointer to self */ + DECLARE_SHMP(struct lib_ring_buffer, self); } ____cacheline_aligned; static inline diff --git a/libringbuffer/ring_buffer_backend.c b/libringbuffer/ring_buffer_backend.c index badde80f..18dd1b01 100644 --- a/libringbuffer/ring_buffer_backend.c +++ b/libringbuffer/ring_buffer_backend.c @@ -283,6 +283,7 @@ int channel_backend_init(struct channel_backend *chanb, buf = shmp(handle, chanb->buf[i].shmp); if (!buf) goto end; + set_shmp(buf->self, chanb->buf[i].shmp._ref); ret = lib_ring_buffer_create(buf, chanb, i, handle, shmobj); if (ret) diff --git a/libringbuffer/shm.c b/libringbuffer/shm.c index 8f158e2f..6a77af64 100644 --- a/libringbuffer/shm.c +++ b/libringbuffer/shm.c @@ -49,6 +49,12 @@ struct shm_object *shm_object_table_append(struct shm_object_table *table, goto error_fcntl; } } + /* The write end of the pipe needs to be non-blocking */ + ret = fcntl(waitfd[1], F_SETFL, O_NONBLOCK); + if (ret < 0) { + PERROR("fcntl"); + goto error_fcntl; + } *obj->wait_fd = *waitfd; /* shm_fd: create shm */ diff --git a/libringbuffer/shm.h b/libringbuffer/shm.h index d370375b..008c5c41 100644 --- a/libringbuffer/shm.h +++ b/libringbuffer/shm.h @@ -68,4 +68,33 @@ struct shm_object *shm_object_table_append(struct shm_object_table *table, struct shm_ref zalloc_shm(struct shm_object *obj, size_t len); void align_shm(struct shm_object *obj, size_t align); +static inline +int shm_get_wakeup_fd(struct shm_handle *handle, struct shm_ref *ref) +{ + struct shm_object_table *table = handle->table; + struct shm_object *obj; + size_t index; + + index = (size_t) ref->index; + if (unlikely(index >= table->allocated_len)) + return -EPERM; + obj = &table->objects[index]; + return obj->wait_fd[1]; + +} + +static inline +int shm_get_wait_fd(struct shm_handle *handle, struct shm_ref *ref) +{ + struct shm_object_table *table = handle->table; + struct shm_object *obj; + size_t index; + + index = (size_t) ref->index; + if (unlikely(index >= table->allocated_len)) + return -EPERM; + obj = &table->objects[index]; + return obj->wait_fd[0]; +} + #endif /* _LIBRINGBUFFER_SHM_H */ diff --git a/libust/ltt-ring-buffer-client.h b/libust/ltt-ring-buffer-client.h index d71d3861..e4845642 100644 --- a/libust/ltt-ring-buffer-client.h +++ b/libust/ltt-ring-buffer-client.h @@ -362,13 +362,13 @@ static const struct lib_ring_buffer_config client_config = { .tsc_bits = 32, .alloc = RING_BUFFER_ALLOC_PER_CPU, - .sync = RING_BUFFER_SYNC_PER_CPU, + .sync = RING_BUFFER_SYNC_GLOBAL, .mode = RING_BUFFER_MODE_TEMPLATE, .backend = RING_BUFFER_PAGE, - .output = RING_BUFFER_SPLICE, + .output = RING_BUFFER_MMAP, .oops = RING_BUFFER_OOPS_CONSISTENCY, - .ipi = RING_BUFFER_IPI_BARRIER, - .wakeup = RING_BUFFER_WAKEUP_BY_TIMER, + .ipi = RING_BUFFER_NO_IPI_BARRIER, + .wakeup = RING_BUFFER_WAKEUP_BY_WRITER, }; static diff --git a/libust/ltt-ring-buffer-metadata-client.h b/libust/ltt-ring-buffer-metadata-client.h index 88716a26..ef70a9f0 100644 --- a/libust/ltt-ring-buffer-metadata-client.h +++ b/libust/ltt-ring-buffer-metadata-client.h @@ -149,10 +149,10 @@ static const struct lib_ring_buffer_config client_config = { .sync = RING_BUFFER_SYNC_GLOBAL, .mode = RING_BUFFER_MODE_TEMPLATE, .backend = RING_BUFFER_PAGE, - .output = RING_BUFFER_SPLICE, + .output = RING_BUFFER_MMAP, .oops = RING_BUFFER_OOPS_CONSISTENCY, - .ipi = RING_BUFFER_IPI_BARRIER, - .wakeup = RING_BUFFER_WAKEUP_BY_TIMER, + .ipi = RING_BUFFER_NO_IPI_BARRIER, + .wakeup = RING_BUFFER_WAKEUP_BY_WRITER, }; static -- 2.34.1