3 * Copyright 2004 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
26 #include <qa_gr_buffer.h>
27 #include <gr_buffer.h>
28 #include <cppunit/TestAssert.h>
30 #include <gr_random.h>
33 leak_check (void f ())
35 long buffer_count = gr_buffer_ncurrently_allocated ();
36 long buffer_reader_count = gr_buffer_reader_ncurrently_allocated ();
40 CPPUNIT_ASSERT_EQUAL (buffer_reader_count, gr_buffer_reader_ncurrently_allocated ());
41 CPPUNIT_ASSERT_EQUAL (buffer_count, gr_buffer_ncurrently_allocated ());
45 // ----------------------------------------------------------------------------
46 // test single writer, no readers...
52 int nitems = 4000 / sizeof (int);
55 gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
60 sa = buf->space_available ();
61 CPPUNIT_ASSERT (sa > 0);
64 for (int i = 0; i < 5; i++){
65 sa = buf->space_available ();
66 CPPUNIT_ASSERT_EQUAL (last_sa, sa);
69 int *p = (int *) buf->write_pointer ();
70 CPPUNIT_ASSERT (p != 0);
72 for (int j = 0; j < sa; j++)
75 buf->update_write_pointer (sa);
79 // ----------------------------------------------------------------------------
80 // test single writer, single reader
86 int nitems = 4000 / sizeof (int);
87 int write_counter = 0;
90 gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
91 gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 0));
96 // write 1/3 of buffer
98 sa = buf->space_available ();
99 CPPUNIT_ASSERT (sa > 0);
101 int *p = (int *) buf->write_pointer ();
102 CPPUNIT_ASSERT (p != 0);
104 for (int j = 0; j < sa/3; j++){
105 *p++ = write_counter++;
107 buf->update_write_pointer (sa/3);
110 // write the next 1/3 (1/2 of what's left)
112 sa = buf->space_available ();
113 CPPUNIT_ASSERT (sa > 0);
115 p = (int *) buf->write_pointer ();
116 CPPUNIT_ASSERT (p != 0);
118 for (int j = 0; j < sa/2; j++){
119 *p++ = write_counter++;
121 buf->update_write_pointer (sa/2);
124 // check that we can read it OK
126 int ia = r1->items_available ();
127 CPPUNIT_ASSERT_EQUAL (write_counter, ia);
129 int *rp = (int *) r1->read_pointer ();
130 CPPUNIT_ASSERT (rp != 0);
132 for (int i = 0; i < ia/2; i++){
133 CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
137 r1->update_read_pointer (ia/2);
141 ia = r1->items_available ();
142 rp = (int *) r1->read_pointer ();
143 CPPUNIT_ASSERT (rp != 0);
145 for (int i = 0; i < ia; i++){
146 CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
150 r1->update_read_pointer (ia);
153 // ----------------------------------------------------------------------------
154 // single writer, single reader: check wrap-around
160 // 64K is the largest granularity we've seen so far (MS windows file mapping).
161 // This allows a bit of "white box testing"
163 int nitems = (64 * (1L << 10)) / sizeof (int); // 64K worth of ints
165 gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
166 gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 0));
168 int read_counter = 0;
169 int write_counter = 0;
174 // Write 3/4 of buffer
176 n = (int) (buf->space_available () * 0.75);
177 wp = (int *) buf->write_pointer ();
179 for (int i = 0; i < n; i++)
180 *wp++ = write_counter++;
181 buf->update_write_pointer (n);
185 int m = r1->items_available ();
186 CPPUNIT_ASSERT_EQUAL (n, m);
187 rp = (int *) r1->read_pointer ();
189 for (int i = 0; i < m; i++){
190 CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
194 r1->update_read_pointer (m);
196 // Now write as much as we can.
197 // This will wrap around the buffer
199 n = buf->space_available ();
200 CPPUNIT_ASSERT_EQUAL (nitems - 1, n); // white box test
201 wp = (int *) buf->write_pointer ();
203 for (int i = 0; i < n; i++)
204 *wp++ = write_counter++;
205 buf->update_write_pointer (n);
209 m = r1->items_available ();
210 CPPUNIT_ASSERT_EQUAL (n, m);
211 rp = (int *) r1->read_pointer ();
213 for (int i = 0; i < m; i++){
214 CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
218 r1->update_read_pointer (m);
222 // ----------------------------------------------------------------------------
223 // single writer, N readers, randomized order and lengths
224 // ----------------------------------------------------------------------------
229 int nitems = (64 * (1L << 10)) / sizeof (int);
231 static const int N = 5;
232 gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
233 gr_buffer_reader_sptr reader[N];
235 int write_counter = 0;
238 for (int i = 0; i < N; i++){
240 reader[i] = gr_buffer_add_reader (buf, 0);
243 for (int lc = 0; lc < 1000; lc++){
247 int n = (int) (buf->space_available () * random.ran1 ());
248 int *wp = (int *) buf->write_pointer ();
250 for (int i = 0; i < n; i++)
251 *wp++ = write_counter++;
253 buf->update_write_pointer (n);
255 // pick a random reader and read some
257 int r = (int) (N * random.ran1 ());
258 CPPUNIT_ASSERT (0 <= r && r < N);
260 int m = reader[r]->items_available ();
261 int *rp = (int *) reader[r]->read_pointer ();
263 for (int i = 0; i < m; i++){
264 CPPUNIT_ASSERT_EQUAL (read_counter[r], *rp);
268 reader[r]->update_read_pointer (m);
273 // ----------------------------------------------------------------------------
278 leak_check (t0_body);
284 leak_check (t1_body);
290 leak_check (t2_body);
296 leak_check (t3_body);