📄 gr_vmcircbuf.cc
字号:
/* -*- c++ -*- *//* * Copyright 2003 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 2, 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <gr_vmcircbuf.h>#include <assert.h>#include <stdexcept>#include <gr_preferences.h>#include <stdio.h>#include <gr_local_sighandler.h>// all the factories we know about#include <gr_vmcircbuf_sysv_shm.h>#include <gr_vmcircbuf_mmap_shm_open.h>#include <gr_vmcircbuf_mmap_tmpfile.h>static const char *FACTORY_PREF_KEY = "gr_vmcircbuf_default_factory";gr_vmcircbuf::~gr_vmcircbuf (){}gr_vmcircbuf_factory::~gr_vmcircbuf_factory (){}// ----------------------------------------------------------------static gr_vmcircbuf_factory *s_default_factory = 0;gr_vmcircbuf_factory *gr_vmcircbuf_sysconfig::get_default_factory (){ if (s_default_factory) return s_default_factory; bool verbose = false; std::vector<gr_vmcircbuf_factory *> all = all_factories (); const char *name = gr_preferences::get (FACTORY_PREF_KEY); if (name){ for (unsigned int i = 0; i < all.size (); i++){ if (strcmp (name, all[i]->name ()) == 0){ s_default_factory = all[i]; if (verbose) fprintf (stderr, "gr_vmcircbuf_sysconfig: using %s\n", s_default_factory->name ()); return s_default_factory; } } } // either we don't have a default, or the default named is not in our // list of factories. Find the first factory that works. if (verbose) fprintf (stderr, "gr_vmcircbuf_sysconfig: finding a working factory...\n"); for (unsigned int i = 0; i < all.size (); i++){ if (test_factory (all[i], verbose)){ set_default_factory (all[i]); return s_default_factory; } } // We're screwed! fprintf (stderr, "gr_vmcircbuf_sysconfig: unable to find a working factory!\n"); throw std::runtime_error ("gr_vmcircbuf_sysconfig");}std::vector<gr_vmcircbuf_factory *>gr_vmcircbuf_sysconfig::all_factories (){ std::vector<gr_vmcircbuf_factory *> result; result.push_back (gr_vmcircbuf_sysv_shm_factory::singleton ()); result.push_back (gr_vmcircbuf_mmap_shm_open_factory::singleton ()); result.push_back (gr_vmcircbuf_mmap_tmpfile_factory::singleton ()); return result;}voidgr_vmcircbuf_sysconfig::set_default_factory (gr_vmcircbuf_factory *f){ gr_preferences::set (FACTORY_PREF_KEY, f->name ()); s_default_factory = f;}// ------------------------------------------------------------------------// test code for vmcircbuf factories// ------------------------------------------------------------------------static voidinit_buffer (gr_vmcircbuf *c, int counter, int size){ unsigned int *p = (unsigned int *) c->pointer_to_first_copy (); for (unsigned int i = 0; i < size / sizeof (int); i++) p[i] = counter + i;}static boolcheck_mapping (gr_vmcircbuf *c, int counter, int size, char *msg, bool verbose){ bool ok = true; if (verbose) fprintf (stderr, "... %s", msg); unsigned int *p1 = (unsigned int *) c->pointer_to_first_copy (); unsigned int *p2 = (unsigned int *) c->pointer_to_second_copy (); // fprintf (stderr, "p1 = %p, p2 = %p\n", p1, p2); for (unsigned int i = 0; i < size / sizeof (int); i++){ if (p1[i] != counter + i){ ok = false; if (verbose) fprintf (stderr, " p1[%d] == %u, expected %u\n", i, p1[i], counter + i); break; } if (p2[i] != counter + i){ if (verbose) fprintf (stderr, " p2[%d] == %u, expected %u\n", i, p2[i], counter + i); ok = false; break; } } if (ok && verbose){ fprintf (stderr, " OK\n"); } return ok;}static char *memsize (int size){ static char buf[100]; if (size >= (1 << 20)){ snprintf (buf, sizeof (buf), "%dMB", size / (1 << 20)); } else if (size >= (1 << 10)){ snprintf (buf, sizeof (buf), "%dKB", size / (1 << 10)); } else { snprintf (buf, sizeof (buf), "%d", size); } return buf;}static booltest_a_bunch (gr_vmcircbuf_factory *factory, int n, int size, int *start_ptr, bool verbose){ bool ok = true; int counter[n]; gr_vmcircbuf *c[n]; int cum_size = 0; for (int i = 0; i < n; i++){ counter[i] = *start_ptr; *start_ptr += size; if ((c[i] = factory->make (size)) == 0){ if (verbose) fprintf (stderr, "Failed to allocate gr_vmcircbuf number %d of size %d (cum = %s)\n", i + 1, size, memsize (cum_size)); return false; } init_buffer (c[i], counter[i], size); cum_size += size; } for (int i = 0; i < n; i++){ char msg[100]; snprintf (msg, sizeof (msg), "test_a_bunch_%dx%s[%d]", n, memsize (size), i); ok &= check_mapping (c[i], counter[i], size, msg, verbose); } for (int i = 0; i < n; i++){ delete c[i]; c[i] = 0; } return ok;}static boolstandard_tests (gr_vmcircbuf_factory *f, int verbose){ if (verbose >= 1) fprintf (stderr, "Testing %s...\n", f->name ()); bool v = verbose >= 2; int granularity = f->granularity (); int start = 0; bool ok = true; ok &= test_a_bunch (f, 1, 1 * granularity, &start, v); // 1 x 4KB = 4KB if (ok){ ok &= test_a_bunch (f, 64, 4 * granularity, &start, v); // 256 x 16KB = 4MB ok &= test_a_bunch (f, 32, 4 * (1L << 20), &start, v); // 32 x 4MB = 64MB ok &= test_a_bunch (f, 256, 256 * (1L << 10), &start, v); // 256 x 256KB = 64MB } if (verbose >= 1) fprintf (stderr, "....... %s: %s", f->name (), ok ? "OK\n" : "Doesn't work\n"); return ok;}boolgr_vmcircbuf_sysconfig::test_factory (gr_vmcircbuf_factory *f, int verbose){ // Install local signal handlers for SIGSEGV and SIGBUS. // If something goes wrong, these signals may be invoked. gr_local_sighandler sigsegv (SIGSEGV, gr_local_sighandler::throw_signal); gr_local_sighandler sigbus (SIGBUS, gr_local_sighandler::throw_signal); try { return standard_tests (f, verbose); } catch (gr_signal &sig){ if (verbose){ fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n"); fprintf (stderr, "gr_vmcircbuf_factory::test_factory (%s): caught %s\n", f->name (), sig.name().c_str()); return false; } } catch (...){ if (verbose){ fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n"); fprintf (stderr, "gr_vmcircbuf_factory::test_factory (%s): some kind of uncaught exception\n", f->name ()); } return false; } return false; // never gets here. shut compiler up.}boolgr_vmcircbuf_sysconfig::test_all_factories (int verbose){ bool ok = false; std::vector<gr_vmcircbuf_factory *> all = all_factories (); for (unsigned int i = 0; i < all.size (); i++) ok |= test_factory (all[i], verbose); return ok;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -