about summary refs log tree commit diff
path: root/src/rt/circular_buffer.cpp
diff options
context:
space:
mode:
authorBrian Anderson <andersrb@gmail.com>2011-01-08 18:52:37 -0500
committerGraydon Hoare <graydon@mozilla.com>2011-01-10 11:31:33 -0800
commit9e5f6d3977d96b4d12b0530432ec505b8df2a383 (patch)
treeabc2e678971499f7efacf7937074c8eafd041868 /src/rt/circular_buffer.cpp
parent295c54e10f587a56dfec95ca3a3aee0f9fd721a2 (diff)
downloadrust-9e5f6d3977d96b4d12b0530432ec505b8df2a383.tar.gz
rust-9e5f6d3977d96b4d12b0530432ec505b8df2a383.zip
Cleanup circular_buffer
Diffstat (limited to 'src/rt/circular_buffer.cpp')
-rw-r--r--src/rt/circular_buffer.cpp91
1 files changed, 52 insertions, 39 deletions
diff --git a/src/rt/circular_buffer.cpp b/src/rt/circular_buffer.cpp
index 142e7574743..a466724702c 100644
--- a/src/rt/circular_buffer.cpp
+++ b/src/rt/circular_buffer.cpp
@@ -7,10 +7,10 @@
 circular_buffer::circular_buffer(rust_dom *dom, size_t unit_sz) :
     dom(dom),
     unit_sz(unit_sz),
-    _buffer_sz(INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS * unit_sz),
+    _buffer_sz(initial_size()),
     _next(0),
     _unread(0),
-    _buffer((uint8_t *)dom->calloc(_buffer_sz)) {
+    _buffer((uint8_t *)dom->malloc(_buffer_sz)) {
 
     A(dom, unit_sz, "Unit size must be larger than zero.");
 
@@ -30,6 +30,12 @@ circular_buffer::~circular_buffer() {
     dom->free(_buffer);
 }
 
+size_t
+circular_buffer::initial_size() {
+    I(dom, unit_sz > 0);
+    return INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS * unit_sz;
+}
+
 /**
  * Copies the unread data from this buffer to the "dst" address.
  */
@@ -43,19 +49,18 @@ circular_buffer::transfer(void *dst) {
     // First copy from _next to either the end of the unread
     // items or the end of the buffer
     size_t head_sz;
-    if (_next + _unread > _buffer_sz) {
-        head_sz = _buffer_sz - _next;
-    } else {
+    if (_next + _unread <= _buffer_sz) {
         head_sz = _unread;
+    } else {
+        head_sz = _buffer_sz - _next;
     }
     I(dom, _next + head_sz <= _buffer_sz);
-    I(dom, _next < _buffer_sz);
     memcpy(ptr, _buffer + _next, head_sz);
 
     // Then copy any other items from the beginning of the buffer
     I(dom, _unread >= head_sz);
     size_t tail_sz = _unread - head_sz;
-    I(dom, tail_sz <= _buffer_sz);
+    I(dom, head_sz + tail_sz <= _buffer_sz);
     memcpy(ptr + head_sz, _buffer, tail_sz);
 }
 
@@ -71,16 +76,7 @@ circular_buffer::enqueue(void *src) {
 
     // Grow if necessary.
     if (_unread == _buffer_sz) {
-        size_t new_buffer_sz = _buffer_sz * 2;
-        I(dom, new_buffer_sz <= MAX_CIRCULAR_BUFFER_SIZE);
-        dom->log(rust_log::MEM | rust_log::COMM,
-                 "circular_buffer is growing to %d bytes", new_buffer_sz);
-        void *new_buffer = dom->malloc(new_buffer_sz);
-        transfer(new_buffer);
-        dom->free(_buffer);
-        _buffer = (uint8_t *)new_buffer;
-        _next = 0;
-        _buffer_sz = new_buffer_sz;
+        grow();
     }
 
     dom->log(rust_log::MEM | rust_log::COMM,
@@ -92,21 +88,21 @@ circular_buffer::enqueue(void *src) {
     I(dom, _unread + unit_sz <= _buffer_sz);
 
     // Copy data
-    size_t i;
-    if (_next + _unread < _buffer_sz) {
-        i = _next + _unread;
-    } else {
+    size_t dst_idx = _next + _unread;
+    I(dom, dst_idx >= _buffer_sz || dst_idx + unit_sz <= _buffer_sz);
+    if (dst_idx >= _buffer_sz) {
+        dst_idx -= _buffer_sz;
+
         I(dom, _next >= unit_sz);
-        i = _next + _unread - _buffer_sz;
-        I(dom, i <= _next - unit_sz);
+        I(dom, dst_idx <= _next - unit_sz);
     }
 
-    I(dom, i + unit_sz <= _buffer_sz);
-    memcpy(&_buffer[i], src, unit_sz);
+    I(dom, dst_idx + unit_sz <= _buffer_sz);
+    memcpy(&_buffer[dst_idx], src, unit_sz);
     _unread += unit_sz;
 
     dom->log(rust_log::MEM | rust_log::COMM,
-             "circular_buffer pushed data at index: %d", i);
+             "circular_buffer pushed data at index: %d", dst_idx);
 }
 
 /**
@@ -139,22 +135,39 @@ circular_buffer::dequeue(void *dst) {
     }
 
     // Shrink if possible.
-    if (_buffer_sz > INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS * unit_sz &&
-        _unread <= _buffer_sz / 4) {
-        size_t new_buffer_sz = _buffer_sz / 2;
-        I(dom,
-          INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS * unit_sz <= new_buffer_sz);
-        dom->log(rust_log::MEM | rust_log::COMM,
-                 "circular_buffer is shrinking to %d bytes", new_buffer_sz);
-        void *tmp = dom->malloc(new_buffer_sz);
-        transfer(tmp);
-        dom->free(_buffer);
-        _buffer = (uint8_t *)tmp;
-        _next = 0;
-        _buffer_sz = new_buffer_sz;
+    if (_buffer_sz > initial_size() && _unread <= _buffer_sz / 4) {
+        shrink();
     }
 }
 
+void
+circular_buffer::grow() {
+    size_t new_buffer_sz = _buffer_sz * 2;
+    I(dom, new_buffer_sz <= MAX_CIRCULAR_BUFFER_SIZE);
+    dom->log(rust_log::MEM | rust_log::COMM,
+             "circular_buffer is growing to %d bytes", new_buffer_sz);
+    void *new_buffer = dom->malloc(new_buffer_sz);
+    transfer(new_buffer);
+    dom->free(_buffer);
+    _buffer = (uint8_t *)new_buffer;
+    _next = 0;
+    _buffer_sz = new_buffer_sz;
+}
+
+void
+circular_buffer::shrink() {
+    size_t new_buffer_sz = _buffer_sz / 2;
+    I(dom, initial_size() <= new_buffer_sz);
+    dom->log(rust_log::MEM | rust_log::COMM,
+             "circular_buffer is shrinking to %d bytes", new_buffer_sz);
+    void *new_buffer = dom->malloc(new_buffer_sz);
+    transfer(new_buffer);
+    dom->free(_buffer);
+    _buffer = (uint8_t *)new_buffer;
+    _next = 0;
+    _buffer_sz = new_buffer_sz;
+}
+
 uint8_t *
 circular_buffer::peek() {
     return &_buffer[_next];