Skip to content

Commit c80483d

Browse files
committed
Fixed circular buffer resizing bug.
1 parent 00d1465 commit c80483d

File tree

5 files changed

+79
-20
lines changed

5 files changed

+79
-20
lines changed

src/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,6 @@ TEST_XFAILS_X86 := $(MUT_BOX_XFAILS) \
374374
test/run-pass/vec-alloc-append.rs \
375375
test/run-pass/vec-slice.rs \
376376
test/run-pass/task-comm-3.rs \
377-
test/run-pass/task-comm-4.rs \
378377
test/compile-fail/bad-recv.rs \
379378
test/compile-fail/bad-send.rs \
380379
test/compile-fail/infinite-tag-type-recursion.rs \

src/rt/circular_buffer.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
circular_buffer::circular_buffer(rust_dom *dom, size_t unit_sz) :
88
dom(dom),
99
_buffer_sz(INITIAL_CIRCULAR_BUFFFER_SIZE_IN_UNITS * unit_sz),
10-
unit_sz(unit_sz),
10+
_unit_sz(unit_sz),
1111
_next(0),
1212
_unread(0),
1313
_buffer((uint8_t *)dom->calloc(_buffer_sz)) {
@@ -27,7 +27,7 @@ circular_buffer::~circular_buffer() {
2727
"~circular_buffer 0x%" PRIxPTR,
2828
this);
2929
I(dom, _buffer);
30-
// I(dom, unread == 0);
30+
// I(dom, _unread == 0);
3131
dom->free(_buffer);
3232
}
3333

@@ -38,8 +38,8 @@ void
3838
circular_buffer::transfer(void *dst) {
3939
I(dom, dst);
4040
uint8_t *ptr = (uint8_t *) dst;
41-
for (size_t i = 0; i < _unread; i += unit_sz) {
42-
memcpy(&ptr[i], &_buffer[_next + i % _buffer_sz], unit_sz);
41+
for (size_t i = 0; i < _unread; i += _unit_sz) {
42+
memcpy(&ptr[i], &_buffer[(_next + i) % _buffer_sz], _unit_sz);
4343
}
4444
}
4545

@@ -65,15 +65,15 @@ circular_buffer::enqueue(void *src) {
6565
dom->log(rust_log::MEM | rust_log::COMM,
6666
"circular_buffer enqueue "
6767
"unread: %d, buffer_sz: %d, unit_sz: %d",
68-
_unread, _buffer_sz, unit_sz);
68+
_unread, _buffer_sz, _unit_sz);
6969

7070
I(dom, _unread < _buffer_sz);
71-
I(dom, _unread + unit_sz <= _buffer_sz);
71+
I(dom, _unread + _unit_sz <= _buffer_sz);
7272

7373
// Copy data
7474
size_t i = (_next + _unread) % _buffer_sz;
75-
memcpy(&_buffer[i], src, unit_sz);
76-
_unread += unit_sz;
75+
memcpy(&_buffer[i], src, _unit_sz);
76+
_unread += _unit_sz;
7777

7878
dom->log(rust_log::MEM | rust_log::COMM,
7979
"circular_buffer pushed data at index: %d", i);
@@ -86,30 +86,34 @@ circular_buffer::enqueue(void *src) {
8686
void
8787
circular_buffer::dequeue(void *dst) {
8888
I(dom, dst);
89-
I(dom, unit_sz > 0);
90-
I(dom, _unread >= unit_sz);
89+
I(dom, _unit_sz > 0);
90+
I(dom, _unread >= _unit_sz);
9191
I(dom, _unread <= _buffer_sz);
9292
I(dom, _buffer);
93-
size_t i = _next;
94-
memcpy(dst, &_buffer[i], unit_sz);
93+
94+
memcpy(dst, &_buffer[_next], _unit_sz);
9595
dom->log(rust_log::MEM | rust_log::COMM,
96-
"shifted data from index %d", i);
97-
_unread -= unit_sz;
98-
_next += unit_sz;
96+
"shifted data from index %d", _next);
97+
_unread -= _unit_sz;
98+
_next += _unit_sz;
9999
I(dom, _next <= _buffer_sz);
100100
if (_next == _buffer_sz) {
101101
_next = 0;
102102
}
103103

104104
// Shrink if possible.
105-
if (_buffer_sz >= INITIAL_CIRCULAR_BUFFFER_SIZE_IN_UNITS * unit_sz &&
105+
if (_buffer_sz >= INITIAL_CIRCULAR_BUFFFER_SIZE_IN_UNITS * _unit_sz &&
106106
_unread <= _buffer_sz / 4) {
107+
dom->log(rust_log::MEM | rust_log::COMM,
108+
"circular_buffer is shrinking to %d bytes", _buffer_sz / 2);
107109
void *tmp = dom->malloc(_buffer_sz / 2);
108110
transfer(tmp);
109111
_buffer_sz >>= 1;
110112
dom->free(_buffer);
111113
_buffer = (uint8_t *)tmp;
114+
_next = 0;
112115
}
116+
113117
}
114118

115119
bool

src/rt/circular_buffer.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,19 @@ circular_buffer : public dom_owned<circular_buffer> {
2020
bool is_empty();
2121

2222
private:
23+
// Size of the buffer in bytes.
2324
size_t _buffer_sz;
24-
size_t unit_sz;
25+
26+
// Size of the data unit in bytes.
27+
size_t _unit_sz;
28+
29+
// Byte offset within the buffer where to read the next unit of data.
2530
size_t _next;
31+
32+
// Number of bytes that have not been read from the buffer.
2633
size_t _unread;
34+
35+
// The buffer itself.
2736
uint8_t *_buffer;
2837
};
2938

src/test/run-pass/task-comm-4.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,30 @@ io fn main() -> () {
33
}
44

55
io fn test00() {
6+
let int r = 0;
7+
let int sum = 0;
68
let port[int] p = port();
79
let chan[int] c = chan(p);
8-
c <| 42;
9-
let int r <- p;
10+
11+
c <| 1;
12+
c <| 2;
13+
c <| 3;
14+
c <| 4;
15+
16+
r <- p; sum += r; log (r);
17+
r <- p; sum += r; log (r);
18+
r <- p; sum += r; log (r);
19+
r <- p; sum += r; log (r);
20+
21+
c <| 5;
22+
c <| 6;
23+
c <| 7;
24+
c <| 8;
25+
26+
r <- p; sum += r; log (r);
27+
r <- p; sum += r; log (r);
28+
r <- p; sum += r; log (r);
29+
r <- p; sum += r; log (r);
30+
31+
check (sum == 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8);
1032
}

src/test/run-pass/task-comm-5.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
io fn main() -> () {
2+
test00();
3+
}
4+
5+
io fn test00() {
6+
let int r = 0;
7+
let int sum = 0;
8+
let port[int] p = port();
9+
let chan[int] c = chan(p);
10+
let int number_of_messages = 1000;
11+
12+
let int i = 0;
13+
while (i < number_of_messages) {
14+
c <| i;
15+
i += 1;
16+
}
17+
18+
i = 0;
19+
while (i < number_of_messages) {
20+
r <- p; sum += r;
21+
i += 1;
22+
}
23+
24+
check (sum == ((number_of_messages * (number_of_messages - 1)) / 2));
25+
}

0 commit comments

Comments
 (0)