3 * Copyright 2003 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 3, 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 <gr_vmcircbuf.h>
29 #include <gr_preferences.h>
31 #include <gr_local_sighandler.h>
33 // all the factories we know about
34 #include <gr_vmcircbuf_createfilemapping.h>
35 #include <gr_vmcircbuf_sysv_shm.h>
36 #include <gr_vmcircbuf_mmap_shm_open.h>
37 #include <gr_vmcircbuf_mmap_tmpfile.h>
39 static const char *FACTORY_PREF_KEY = "gr_vmcircbuf_default_factory";
41 gr_vmcircbuf::~gr_vmcircbuf ()
45 gr_vmcircbuf_factory::~gr_vmcircbuf_factory ()
49 // ----------------------------------------------------------------
51 static gr_vmcircbuf_factory *s_default_factory = 0;
53 gr_vmcircbuf_factory *
54 gr_vmcircbuf_sysconfig::get_default_factory ()
56 if (s_default_factory)
57 return s_default_factory;
61 std::vector<gr_vmcircbuf_factory *> all = all_factories ();
63 const char *name = gr_preferences::get (FACTORY_PREF_KEY);
66 for (unsigned int i = 0; i < all.size (); i++){
67 if (strcmp (name, all[i]->name ()) == 0){
68 s_default_factory = all[i];
70 fprintf (stderr, "gr_vmcircbuf_sysconfig: using %s\n",
71 s_default_factory->name ());
72 return s_default_factory;
77 // either we don't have a default, or the default named is not in our
78 // list of factories. Find the first factory that works.
81 fprintf (stderr, "gr_vmcircbuf_sysconfig: finding a working factory...\n");
83 for (unsigned int i = 0; i < all.size (); i++){
84 if (test_factory (all[i], verbose)){
85 set_default_factory (all[i]);
86 return s_default_factory;
92 fprintf (stderr, "gr_vmcircbuf_sysconfig: unable to find a working factory!\n");
93 throw std::runtime_error ("gr_vmcircbuf_sysconfig");
96 std::vector<gr_vmcircbuf_factory *>
97 gr_vmcircbuf_sysconfig::all_factories ()
99 std::vector<gr_vmcircbuf_factory *> result;
101 result.push_back (gr_vmcircbuf_createfilemapping_factory::singleton ());
102 result.push_back (gr_vmcircbuf_sysv_shm_factory::singleton ());
103 result.push_back (gr_vmcircbuf_mmap_shm_open_factory::singleton ());
104 result.push_back (gr_vmcircbuf_mmap_tmpfile_factory::singleton ());
110 gr_vmcircbuf_sysconfig::set_default_factory (gr_vmcircbuf_factory *f)
112 gr_preferences::set (FACTORY_PREF_KEY, f->name ());
113 s_default_factory = f;
117 // ------------------------------------------------------------------------
118 // test code for vmcircbuf factories
119 // ------------------------------------------------------------------------
122 init_buffer (gr_vmcircbuf *c, int counter, int size)
124 unsigned int *p = (unsigned int *) c->pointer_to_first_copy ();
125 for (unsigned int i = 0; i < size / sizeof (int); i++)
130 check_mapping (gr_vmcircbuf *c, int counter, int size, char *msg, bool verbose)
135 fprintf (stderr, "... %s", msg);
137 unsigned int *p1 = (unsigned int *) c->pointer_to_first_copy ();
138 unsigned int *p2 = (unsigned int *) c->pointer_to_second_copy ();
140 // fprintf (stderr, "p1 = %p, p2 = %p\n", p1, p2);
142 for (unsigned int i = 0; i < size / sizeof (int); i++){
143 if (p1[i] != counter + i){
146 fprintf (stderr, " p1[%d] == %u, expected %u\n", i, p1[i], counter + i);
149 if (p2[i] != counter + i){
151 fprintf (stderr, " p2[%d] == %u, expected %u\n", i, p2[i], counter + i);
158 fprintf (stderr, " OK\n");
166 static char buf[100];
167 if (size >= (1 << 20)){
168 snprintf (buf, sizeof (buf), "%dMB", size / (1 << 20));
170 else if (size >= (1 << 10)){
171 snprintf (buf, sizeof (buf), "%dKB", size / (1 << 10));
174 snprintf (buf, sizeof (buf), "%d", size);
180 test_a_bunch (gr_vmcircbuf_factory *factory, int n, int size, int *start_ptr, bool verbose)
187 for (int i = 0; i < n; i++){
188 counter[i] = *start_ptr;
190 if ((c[i] = factory->make (size)) == 0){
193 "Failed to allocate gr_vmcircbuf number %d of size %d (cum = %s)\n",
194 i + 1, size, memsize (cum_size));
197 init_buffer (c[i], counter[i], size);
201 for (int i = 0; i < n; i++){
203 snprintf (msg, sizeof (msg), "test_a_bunch_%dx%s[%d]", n, memsize (size), i);
204 ok &= check_mapping (c[i], counter[i], size, msg, verbose);
207 for (int i = 0; i < n; i++){
216 standard_tests (gr_vmcircbuf_factory *f, int verbose)
219 fprintf (stderr, "Testing %s...\n", f->name ());
221 bool v = verbose >= 2;
222 int granularity = f->granularity ();
226 ok &= test_a_bunch (f, 1, 1 * granularity, &start, v); // 1 x 4KB = 4KB
229 ok &= test_a_bunch (f, 64, 4 * granularity, &start, v); // 64 x 16KB = 1MB
230 ok &= test_a_bunch (f, 4, 4 * (1L << 20), &start, v); // 4 x 4MB = 16MB
231 // ok &= test_a_bunch (f, 256, 256 * (1L << 10), &start, v); // 256 x 256KB = 64MB
235 fprintf (stderr, "....... %s: %s", f->name (), ok ? "OK\n" : "Doesn't work\n");
241 gr_vmcircbuf_sysconfig::test_factory (gr_vmcircbuf_factory *f, int verbose)
243 // Install local signal handlers for SIGSEGV and SIGBUS.
244 // If something goes wrong, these signals may be invoked.
247 gr_local_sighandler sigsegv (SIGSEGV, gr_local_sighandler::throw_signal);
250 gr_local_sighandler sigbus (SIGBUS, gr_local_sighandler::throw_signal);
253 gr_local_sighandler sigsys (SIGSYS, gr_local_sighandler::throw_signal);
257 return standard_tests (f, verbose);
259 catch (gr_signal &sig){
261 fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n");
263 "gr_vmcircbuf_factory::test_factory (%s): caught %s\n",
264 f->name (), sig.name().c_str());
270 fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n");
272 "gr_vmcircbuf_factory::test_factory (%s): some kind of uncaught exception\n",
277 return false; // never gets here. shut compiler up.
281 gr_vmcircbuf_sysconfig::test_all_factories (int verbose)
285 std::vector<gr_vmcircbuf_factory *> all = all_factories ();
287 for (unsigned int i = 0; i < all.size (); i++)
288 ok |= test_factory (all[i], verbose);