From 83ad787f994d6efbde505ce9915f44bef2b5408d Mon Sep 17 00:00:00 2001
From: Josh Blum
Date: Thu, 13 Dec 2012 19:45:08 -0800
Subject: some work on the circular buffer alloc

---
 lib/gras_impl/endless_buffer_queue.hpp | 98 ++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 lib/gras_impl/endless_buffer_queue.hpp

(limited to 'lib/gras_impl')

diff --git a/lib/gras_impl/endless_buffer_queue.hpp b/lib/gras_impl/endless_buffer_queue.hpp
new file mode 100644
index 0000000..68797a2
--- /dev/null
+++ b/lib/gras_impl/endless_buffer_queue.hpp
@@ -0,0 +1,98 @@
+// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.
+
+#ifndef INCLUDED_LIBGRAS_IMPL_ENDLESS_BUFFER_QUEUE_HPP
+#define INCLUDED_LIBGRAS_IMPL_ENDLESS_BUFFER_QUEUE_HPP
+
+#include <gras_impl/debug.hpp>
+#include <gras/sbuffer.hpp>
+#include <boost/bind.hpp>
+#include <boost/circular_buffer.hpp>
+
+namespace gras
+{
+
+struct EndlessBufferQueue
+{
+    enum {MAX_QUEUE_SIZE = 128};
+
+    static SBuffer make_circular_buffer(const size_t num_bytes);
+
+    EndlessBufferQueue(const size_t num_bytes);
+
+    SBuffer &front(void);
+
+    void pop(const size_t num_bytes);
+
+    void push(const SBuffer &buff);
+
+    SBufferToken _token;
+    SBuffer _circ_buff;
+    char *_write_ptr;
+    size_t _bytes_avail;
+    size_t _cur_index, _ack_index;
+    boost::circular_buffer<SBuffer> _available_buffers;
+    boost::circular_buffer<SBuffer> _returned_buffers;
+};
+
+EndlessBufferQueue::EndlessBufferQueue(const size_t num_bytes)
+{
+    _cur_index = 0;
+    _ack_index = 0;
+
+    //allocate a large buffer
+    _circ_buff = EndlessBufferQueue::make_circular_buffer(num_bytes);
+    _write_ptr = (char *)_circ_buff.get_actual_memory();
+    _bytes_avail = _circ_buff.get_actual_length();
+
+    //create token as buffer returner
+    SBufferDeleter deleter = boost::bind(&EndlessBufferQueue::push, this, _1);
+    _token = SBufferToken(new SBufferDeleter(deleter));
+
+    //allocate pool of sbuffers
+    _available_buffers.resize(MAX_QUEUE_SIZE);
+    _returned_buffers.resize(MAX_QUEUE_SIZE);
+    SBufferConfig config;
+    config.memory = _circ_buff.get_actual_memory();
+    config.length = _circ_buff.get_actual_length();
+    for (size_t i = 0; i < _available_buffers.size(); i++)
+    {
+        _available_buffers.push_back(SBuffer(config));
+    }
+}
+
+GRAS_FORCE_INLINE SBuffer &EndlessBufferQueue::front(void)
+{
+    ASSERT(_bytes_avail);
+    ASSERT(not _available_buffers.empty());
+    SBuffer &front = _available_buffers.front();
+    front->config.memory = _write_ptr;
+    front->config.length = _bytes_avail;
+    front.offset = 0;
+    front.length = 0;
+    return front;
+}
+
+GRAS_FORCE_INLINE void EndlessBufferQueue::pop(const size_t num_bytes)
+{
+    ASSERT(_bytes_avail >= num_bytes);
+    SBuffer &front = _available_buffers.front();
+    front->config.length = num_bytes;
+    front->config.user_index = _cur_index++;
+    _write_ptr += num_bytes;
+    if (_write_ptr > (char *)_circ_buff.get(circ_buff.get_actual_length()))
+    {
+        _write_ptr -= circ_buff.get_actual_length();
+    }
+    _bytes_avail -= num_bytes;
+}
+
+void EndlessBufferQueue::push(const SBuffer &buff)
+{
+    _returned_buffers.push_back(buff);
+    //BOOST_FOREACH(
+    //TODO update available
+}
+
+} //namespace gras
+
+#endif /*INCLUDED_LIBGRAS_IMPL_ENDLESS_BUFFER_QUEUE_HPP*/
-- 
cgit