diff options
Diffstat (limited to 'gnuradio-runtime/lib/qa_buffer.cc')
-rw-r--r-- | gnuradio-runtime/lib/qa_buffer.cc | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/gnuradio-runtime/lib/qa_buffer.cc b/gnuradio-runtime/lib/qa_buffer.cc new file mode 100644 index 0000000000..5f1dece0ad --- /dev/null +++ b/gnuradio-runtime/lib/qa_buffer.cc @@ -0,0 +1,304 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qa_buffer.h> +#include <gnuradio/buffer.h> +#include <cppunit/TestAssert.h> +#include <stdlib.h> +#include <gnuradio/random.h> + +static void +leak_check(void f()) +{ + long buffer_count = gr::buffer_ncurrently_allocated(); + long buffer_reader_count = gr::buffer_reader_ncurrently_allocated(); + + f(); + + CPPUNIT_ASSERT_EQUAL(buffer_reader_count, gr::buffer_reader_ncurrently_allocated()); + CPPUNIT_ASSERT_EQUAL(buffer_count, gr::buffer_ncurrently_allocated()); +} + + +// ---------------------------------------------------------------------------- +// test single writer, no readers... +// + +static void +t0_body() +{ + int nitems = 4000 / sizeof(int); + int counter = 0; + + gr::buffer_sptr buf(gr::make_buffer(nitems, sizeof(int), gr::block_sptr())); + + int last_sa; + int sa; + + sa = buf->space_available(); + CPPUNIT_ASSERT(sa > 0); + last_sa = sa; + + for(int i = 0; i < 5; i++) { + sa = buf->space_available(); + CPPUNIT_ASSERT_EQUAL(last_sa, sa); + last_sa = sa; + + int *p = (int*)buf->write_pointer(); + CPPUNIT_ASSERT(p != 0); + + for(int j = 0; j < sa; j++) + *p++ = counter++; + + buf->update_write_pointer(sa); + } +} + +// ---------------------------------------------------------------------------- +// test single writer, single reader +// + +static void +t1_body() +{ + int nitems = 4000 / sizeof(int); + int write_counter = 0; + int read_counter = 0; + + gr::buffer_sptr buf(gr::make_buffer(nitems, sizeof(int), gr::block_sptr())); + gr::buffer_reader_sptr r1(gr::buffer_add_reader(buf, 0, gr::block_sptr())); + + int sa; + + // write 1/3 of buffer + + sa = buf->space_available(); + CPPUNIT_ASSERT(sa > 0); + + int *p = (int*)buf->write_pointer(); + CPPUNIT_ASSERT(p != 0); + + for(int j = 0; j < sa/3; j++) { + *p++ = write_counter++; + } + buf->update_write_pointer(sa/3); + + // write the next 1/3 (1/2 of what's left) + + sa = buf->space_available(); + CPPUNIT_ASSERT(sa > 0); + + p = (int*)buf->write_pointer(); + CPPUNIT_ASSERT(p != 0); + + for(int j = 0; j < sa/2; j++) { + *p++ = write_counter++; + } + buf->update_write_pointer(sa/2); + + // check that we can read it OK + + int ia = r1->items_available(); + CPPUNIT_ASSERT_EQUAL(write_counter, ia); + + int *rp = (int*)r1->read_pointer(); + CPPUNIT_ASSERT(rp != 0); + + for(int i = 0; i < ia/2; i++) { + CPPUNIT_ASSERT_EQUAL(read_counter, *rp); + read_counter++; + rp++; + } + r1->update_read_pointer(ia/2); + + // read the rest + + ia = r1->items_available(); + rp = (int *) r1->read_pointer(); + CPPUNIT_ASSERT(rp != 0); + + for(int i = 0; i < ia; i++) { + CPPUNIT_ASSERT_EQUAL(read_counter, *rp); + read_counter++; + rp++; + } + r1->update_read_pointer(ia); +} + +// ---------------------------------------------------------------------------- +// single writer, single reader: check wrap-around +// + +static void +t2_body() +{ + // 64K is the largest granularity we've seen so far (MS windows file mapping). + // This allows a bit of "white box testing" + + int nitems = (64 * (1L << 10)) / sizeof(int); // 64K worth of ints + + gr::buffer_sptr buf(gr::make_buffer(nitems, sizeof(int), gr::block_sptr())); + gr::buffer_reader_sptr r1(gr::buffer_add_reader(buf, 0, gr::block_sptr())); + + int read_counter = 0; + int write_counter = 0; + int n; + int *wp = 0; + int *rp = 0; + + // Write 3/4 of buffer + + n = (int)(buf->space_available() * 0.75); + wp = (int*)buf->write_pointer(); + + for(int i = 0; i < n; i++) + *wp++ = write_counter++; + buf->update_write_pointer(n); + + // Now read it all + + int m = r1->items_available(); + CPPUNIT_ASSERT_EQUAL(n, m); + rp = (int*)r1->read_pointer(); + + for(int i = 0; i < m; i++) { + CPPUNIT_ASSERT_EQUAL(read_counter, *rp); + read_counter++; + rp++; + } + r1->update_read_pointer(m); + + // Now write as much as we can. + // This will wrap around the buffer + + n = buf->space_available(); + CPPUNIT_ASSERT_EQUAL(nitems - 1, n); // white box test + wp = (int*)buf->write_pointer(); + + for(int i = 0; i < n; i++) + *wp++ = write_counter++; + buf->update_write_pointer(n); + + // now read it all + + m = r1->items_available(); + CPPUNIT_ASSERT_EQUAL(n, m); + rp = (int*)r1->read_pointer(); + + for(int i = 0; i < m; i++) { + CPPUNIT_ASSERT_EQUAL(read_counter, *rp); + read_counter++; + rp++; + } + r1->update_read_pointer(m); +} + +// ---------------------------------------------------------------------------- +// single writer, N readers, randomized order and lengths +// ---------------------------------------------------------------------------- + +static void +t3_body() +{ + int nitems = (64 * (1L << 10)) / sizeof(int); + + static const int N = 5; + gr::buffer_sptr buf(gr::make_buffer(nitems, sizeof(int), gr::block_sptr())); + gr::buffer_reader_sptr reader[N]; + int read_counter[N]; + int write_counter = 0; + gr::random random; + + for(int i = 0; i < N; i++) { + read_counter[i] = 0; + reader[i] = buffer_add_reader(buf, 0, gr::block_sptr()); + } + + for(int lc = 0; lc < 1000; lc++) { + + // write some + + int n = (int)(buf->space_available() * random.ran1()); + int *wp = (int*)buf->write_pointer(); + + for(int i = 0; i < n; i++) + *wp++ = write_counter++; + + buf->update_write_pointer(n); + + // pick a random reader and read some + + int r = (int)(N * random.ran1()); + CPPUNIT_ASSERT(0 <= r && r < N); + + int m = reader[r]->items_available(); + int *rp = (int*)reader[r]->read_pointer(); + + for(int i = 0; i < m; i++) { + CPPUNIT_ASSERT_EQUAL(read_counter[r], *rp); + read_counter[r]++; + rp++; + } + reader[r]->update_read_pointer (m); + } +} + + +// ---------------------------------------------------------------------------- + +void +qa_buffer::t0() +{ + leak_check(t0_body); +} + +void +qa_buffer::t1() +{ + leak_check(t1_body); +} + +void +qa_buffer::t2() +{ + leak_check(t2_body); +} + +void +qa_buffer::t3() +{ + leak_check(t3_body); +} + +void +qa_buffer::t4() +{ +} + +void +qa_buffer::t5() +{ +} |