Implement ring buffer clear
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 30 May 2018 00:11:43 +0000 (02:11 +0200)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 26 Aug 2019 17:25:00 +0000 (13:25 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lib/ringbuffer/frontend_internal.h
lib/ringbuffer/ring_buffer_frontend.c
lib/ringbuffer/ring_buffer_vfs.c
lib/ringbuffer/vfs.h

index d02a73d32c2a46bc8a26469e1fddb0fb6eb762f1..a1bfe558440c7d8f7f5af4d45395d6047fe334b7 100644 (file)
@@ -154,6 +154,8 @@ extern
 void lib_ring_buffer_switch_remote(struct lib_ring_buffer *buf);
 extern
 void lib_ring_buffer_switch_remote_empty(struct lib_ring_buffer *buf);
+extern
+void lib_ring_buffer_clear(struct lib_ring_buffer *buf);
 
 /* Buffer write helpers */
 
@@ -185,6 +187,30 @@ void lib_ring_buffer_reserve_push_reader(struct lib_ring_buffer *buf,
                                              consumed_new) != consumed_old));
 }
 
+/*
+ * Move consumed position to the beginning of subbuffer in which the
+ * write offset is.
+ */
+static inline
+void lib_ring_buffer_clear_reader(struct lib_ring_buffer *buf,
+                                 struct channel *chan)
+{
+       const struct lib_ring_buffer_config *config = &chan->backend.config;
+       unsigned long offset, consumed_old, consumed_new;
+
+       do {
+               offset = v_read(config, &buf->offset);
+               consumed_old = atomic_long_read(&buf->consumed);
+               if (unlikely(subbuf_trunc(offset, chan)
+                             - subbuf_trunc(consumed_old, chan)
+                            > 0))
+                       consumed_new = subbuf_trunc(offset, chan);
+               else
+                       return;
+       } while (unlikely(atomic_long_cmpxchg(&buf->consumed, consumed_old,
+                                             consumed_new) != consumed_old));
+}
+
 static inline
 int lib_ring_buffer_pending_data(const struct lib_ring_buffer_config *config,
                                 struct lib_ring_buffer *buf,
index 0d2d6936bbcf870bce1d093a762c9a733b8cbc8a..3cab365264e87431530c449648b8a9d6314449e4 100644 (file)
@@ -1957,6 +1957,16 @@ void lib_ring_buffer_switch_remote_empty(struct lib_ring_buffer *buf)
 }
 EXPORT_SYMBOL_GPL(lib_ring_buffer_switch_remote_empty);
 
+void lib_ring_buffer_clear(struct lib_ring_buffer *buf)
+{
+       struct lib_ring_buffer_backend *bufb = &buf->backend;
+       struct channel *chan = bufb->chan;
+
+       lib_ring_buffer_switch_remote(buf);
+       lib_ring_buffer_clear_reader(buf, chan);
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_clear);
+
 /*
  * Returns :
  * 0 if ok
index f6c0e3dfe21dfc56ee4ee6078bb078c3053c4c79..b423432d8df2e4a14843f5927236122d2516f829 100644 (file)
@@ -263,6 +263,9 @@ long lib_ring_buffer_ioctl(struct file *filp, unsigned int cmd,
        case RING_BUFFER_FLUSH_EMPTY:
                lib_ring_buffer_switch_remote_empty(buf);
                return 0;
+       case RING_BUFFER_CLEAR:
+               lib_ring_buffer_clear(buf);
+               return 0;
        default:
                return -ENOIOCTLCMD;
        }
@@ -414,6 +417,9 @@ long lib_ring_buffer_compat_ioctl(struct file *filp, unsigned int cmd,
        case RING_BUFFER_COMPAT_FLUSH_EMPTY:
                lib_ring_buffer_switch_remote_empty(buf);
                return 0;
+       case RING_BUFFER_COMPAT_CLEAR:
+               lib_ring_buffer_clear(buf);
+               return 0;
        default:
                return -ENOIOCTLCMD;
        }
index b30b0f5814553f84915ab20a1982e062d5a20cc7..2061156dd1b19aba0ebab7cf01815ab4e7645f78 100644 (file)
@@ -112,6 +112,8 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos,
  * so it can be read again.
  */
 #define RING_BUFFER_METADATA_CACHE_DUMP                _IO(0xF6, 0x10)
+/* Clear ring buffer content. */
+#define RING_BUFFER_CLEAR                      _IO(0xF6, 0x11)
 
 #ifdef CONFIG_COMPAT
 /* Get a snapshot of the current ring buffer producer and consumer positions */
@@ -156,6 +158,9 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos,
 /* Flush the current sub-buffer, even if empty. */
 #define RING_BUFFER_COMPAT_FLUSH_EMPTY                 \
        RING_BUFFER_FLUSH_EMPTY
+/* Clear ring buffer content. */
+#define RING_BUFFER_COMPAT_CLEAR                       \
+       RING_BUFFER_CLEAR
 #endif /* CONFIG_COMPAT */
 
 #endif /* _LIB_RING_BUFFER_VFS_H */
This page took 0.02973 seconds and 4 git commands to generate.