[haiku-commits] r35813 - in haiku/trunk: headers/private/kernel/util src/system/kernel/util

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 11 Mar 2010 18:12:21 +0100 (CET)

Author: bonefish
Date: 2010-03-11 18:12:21 +0100 (Thu, 11 Mar 2010)
New Revision: 35813
Changeset: http://dev.haiku-os.org/changeset/35813/haiku

Modified:
   haiku/trunk/headers/private/kernel/util/ring_buffer.h
   haiku/trunk/src/system/kernel/util/ring_buffer.cpp
Log:
* Added create_ring_buffer_etc() which allows to re-create a ring buffer from
  a given flat buffer.
* Added ring_buffer_peek() for random position reading from the ring buffer
  without changing its state.


Modified: haiku/trunk/headers/private/kernel/util/ring_buffer.h
===================================================================
--- haiku/trunk/headers/private/kernel/util/ring_buffer.h       2010-03-11 
17:09:11 UTC (rev 35812)
+++ haiku/trunk/headers/private/kernel/util/ring_buffer.h       2010-03-11 
17:12:21 UTC (rev 35813)
@@ -17,11 +17,17 @@
 };
 
 
+// flags for create_ring_buffer_etc()
+#define RING_BUFFER_INIT_FROM_BUFFER   0x01
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct ring_buffer *create_ring_buffer(size_t size);
+struct ring_buffer *create_ring_buffer_etc(void *memory, size_t size,
+                       uint32 flags);
 void delete_ring_buffer(struct ring_buffer *buffer);
 
 void ring_buffer_clear(struct ring_buffer *buffer);
@@ -32,9 +38,12 @@
 size_t ring_buffer_write(struct ring_buffer *buffer, const uint8 *data, 
ssize_t length);
 ssize_t ring_buffer_user_read(struct ring_buffer *buffer, uint8 *data, ssize_t 
length);
 ssize_t ring_buffer_user_write(struct ring_buffer *buffer, const uint8 *data, 
ssize_t length);
+size_t ring_buffer_peek(struct ring_buffer *buffer, size_t offset, void *data,
+                       size_t length);
 
 #ifdef __cplusplus
 }
 #endif
 
+
 #endif /* RING_BUFFER_H */

Modified: haiku/trunk/src/system/kernel/util/ring_buffer.cpp
===================================================================
--- haiku/trunk/src/system/kernel/util/ring_buffer.cpp  2010-03-11 17:09:11 UTC 
(rev 35812)
+++ haiku/trunk/src/system/kernel/util/ring_buffer.cpp  2010-03-11 17:12:21 UTC 
(rev 35813)
@@ -122,15 +122,38 @@
 //     #pragma mark -
 
 
-struct ring_buffer *
+struct ring_buffer*
 create_ring_buffer(size_t size)
 {
-       struct ring_buffer *buffer = (ring_buffer *)malloc(sizeof(ring_buffer) 
+ size);
-       if (buffer == NULL)
-               return NULL;
+       return create_ring_buffer_etc(NULL, size, 0);
+}
 
+
+struct ring_buffer*
+create_ring_buffer_etc(void* memory, size_t size, uint32 flags)
+{
+       if (memory == NULL) {
+               ring_buffer* buffer = (ring_buffer*)malloc(sizeof(ring_buffer) 
+ size);
+               if (buffer == NULL)
+                       return NULL;
+
+               buffer->size = size;
+               ring_buffer_clear(buffer);
+
+               return buffer;
+       }
+
+       size -= sizeof(ring_buffer);
+       ring_buffer* buffer = (ring_buffer*)memory;
+
        buffer->size = size;
-       ring_buffer_clear(buffer);
+       if ((flags & RING_BUFFER_INIT_FROM_BUFFER) != 0
+               && (size_t)buffer->size == size
+               && buffer->in >= 0 && (size_t)buffer->in <= size
+               && buffer->first >= 0 && (size_t)buffer->first < size) {
+               // structure looks valid
+       } else
+               ring_buffer_clear(buffer);
 
        return buffer;
 }
@@ -205,6 +228,45 @@
 }
 
 
+/*!    Reads data from the ring buffer, but doesn't remove the data from it.
+       \param buffer The ring buffer.
+       \param offset The offset relative to the beginning of the data in the 
ring
+               buffer at which to start reading.
+       \param data The buffer to which to copy the data.
+       \param length The number of bytes to read at maximum.
+       \return The number of bytes actually read from the buffer.
+*/
+size_t
+ring_buffer_peek(struct ring_buffer* buffer, size_t offset, void* data,
+       size_t length)
+{
+       size_t available = buffer->in;
+
+       if (offset >= available || length == 0)
+               return 0;
+
+       if (offset + length > available)
+               length = available - offset;
+
+       if ((offset += buffer->first) >= (size_t)buffer->size)
+               offset -= buffer->size;
+
+       if (offset + length <= (size_t)buffer->size) {
+               // simple copy
+               memcpy(data, buffer->buffer + offset, length);
+       } else {
+               // need to copy both ends
+               size_t upper = buffer->size - offset;
+               size_t lower = length - upper;
+
+               memcpy(data, buffer->buffer + offset, upper);
+               memcpy((uint8*)data + upper, buffer->buffer, lower);
+       }
+
+       return length;
+}
+
+
 #if 0
 /**    Sends the contents of the ring buffer to a port.
  *     The buffer will be empty afterwards only if sending the data actually 
works.


Other related posts:

  • » [haiku-commits] r35813 - in haiku/trunk: headers/private/kernel/util src/system/kernel/util - ingo_weinhold