summaryrefslogtreecommitdiff
path: root/gnuradio-runtime/include/gnuradio/buffer_single_mapped.h
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-runtime/include/gnuradio/buffer_single_mapped.h')
-rw-r--r--gnuradio-runtime/include/gnuradio/buffer_single_mapped.h167
1 files changed, 167 insertions, 0 deletions
diff --git a/gnuradio-runtime/include/gnuradio/buffer_single_mapped.h b/gnuradio-runtime/include/gnuradio/buffer_single_mapped.h
new file mode 100644
index 0000000000..5377534aa8
--- /dev/null
+++ b/gnuradio-runtime/include/gnuradio/buffer_single_mapped.h
@@ -0,0 +1,167 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_GR_RUNTIME_BUFFER_SINGLE_MAPPED_H
+#define INCLUDED_GR_RUNTIME_BUFFER_SINGLE_MAPPED_H
+
+#include <functional>
+
+#include <gnuradio/api.h>
+#include <gnuradio/block.h>
+#include <gnuradio/buffer.h>
+#include <gnuradio/logger.h>
+#include <gnuradio/runtime_types.h>
+
+namespace gr {
+
+/*!
+ * TODO: update this
+ *
+ * \brief Single writer, multiple reader fifo.
+ * \ingroup internal
+ */
+class GR_RUNTIME_API buffer_single_mapped : public buffer
+{
+public:
+ gr::logger_ptr d_logger;
+ gr::logger_ptr d_debug_logger;
+
+ virtual ~buffer_single_mapped();
+
+ /*!
+ * \brief Return the block that owns this buffer.
+ */
+ block_sptr buf_owner() { return d_buf_owner; }
+
+ /*!
+ * \brief return number of items worth of space available for writing
+ */
+ virtual int space_available();
+
+ virtual void update_reader_block_history(unsigned history, int delay)
+ {
+ unsigned old_max = d_max_reader_history;
+ d_max_reader_history = std::max(d_max_reader_history, history);
+ if (d_max_reader_history != old_max) {
+ d_write_index = d_max_reader_history - 1;
+
+#ifdef BUFFER_DEBUG
+ std::ostringstream msg;
+ msg << "[" << this << "] "
+ << "buffer_single_mapped constructor -- set wr index to: "
+ << d_write_index;
+ GR_LOG_DEBUG(d_logger, msg.str());
+#endif
+
+ // Reset the reader's read index if the buffer's write index has changed.
+ // Note that "history - 1" is the nzero_preload value passed to
+ // buffer_add_reader.
+ for (auto reader : d_readers) {
+ reader->d_read_index = d_write_index - (reader->link()->history() - 1);
+ }
+ }
+
+ // Only attempt to set has history flag if it is not already set
+ if (!d_has_history) {
+ // Blocks that set delay may set history to delay + 1 but this is
+ // not "real" history
+ d_has_history = ((static_cast<int>(history) - 1) != delay);
+ }
+ }
+
+ void deleter(char* ptr)
+ {
+ // Delegate free of the underlying buffer to the block that owns it
+ if (ptr != nullptr)
+ buf_owner()->free_custom_buffer(ptr);
+ }
+
+ /*!
+ * \brief Return true if thread is ready to call the callback, false otherwise
+ */
+ virtual bool output_blkd_cb_ready(int output_multiple);
+
+ /*!
+ * \brief Callback function that the scheduler will call when it determines
+ * that the output is blocked
+ */
+ virtual bool output_blocked_callback(int output_multiple, bool force);
+
+protected:
+ /*!
+ * sets d_base, d_bufsize.
+ * returns true iff successful.
+ */
+ bool allocate_buffer(int nitems, size_t sizeof_item, uint64_t downstream_lcm_nitems);
+
+ virtual unsigned index_add(unsigned a, unsigned b)
+ {
+ unsigned s = a + b;
+
+ if (s >= d_bufsize)
+ s -= d_bufsize;
+
+ assert(s < d_bufsize);
+ return s;
+ }
+
+ virtual unsigned index_sub(unsigned a, unsigned b)
+ {
+ // NOTE: a is writer ptr and b is read ptr
+ int s = a - b;
+
+ if (s < 0)
+ s = d_bufsize - b;
+
+ assert((unsigned)s < d_bufsize);
+ return s;
+ }
+
+private:
+ friend class buffer_reader;
+
+ friend GR_RUNTIME_API buffer_sptr make_buffer(int nitems,
+ size_t sizeof_item,
+ uint64_t downstream_lcm_nitems,
+ block_sptr link,
+ block_sptr buf_owner);
+
+ block_sptr d_buf_owner; // block that "owns" this buffer
+
+ std::unique_ptr<char, std::function<void(char*)>> d_buffer;
+
+ /*!
+ * \brief constructor is private. Use gr_make_buffer to create instances.
+ *
+ * Allocate a buffer that holds at least \p nitems of size \p sizeof_item.
+ *
+ * \param nitems is the minimum number of items the buffer will hold.
+ * \param sizeof_item is the size of an item in bytes.
+ * \param downstream_lcm_nitems is the least common multiple of the items to
+ * read by downstream blocks
+ * \param link is the block that writes to this buffer.
+ * \param buf_owner if the block that owns the buffer which may or may not
+ * be the same as the block that writes to this buffer
+ *
+ * The total size of the buffer will be rounded up to a system
+ * dependent boundary. This is typically the system page size, but
+ * under MS windows is 64KB.
+ */
+ buffer_single_mapped(int nitems,
+ size_t sizeof_item,
+ uint64_t downstream_lcm_nitems,
+ block_sptr link,
+ block_sptr buf_owner);
+};
+
+} /* namespace gr */
+
+
+#endif /* INCLUDED_GR_RUNTIME_BUFFER_SINGLE_MAPPED_H */