From 2556b8e081cd0d5c7b5a4f95b64280f94bf12123 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sat, 15 Dec 2012 16:06:59 +0100 Subject: ucoolib/utils: add fifo low level container --- ucoolib/utils/fifo.hh | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 ucoolib/utils/fifo.hh (limited to 'ucoolib/utils/fifo.hh') diff --git a/ucoolib/utils/fifo.hh b/ucoolib/utils/fifo.hh new file mode 100644 index 0000000..0b8aa28 --- /dev/null +++ b/ucoolib/utils/fifo.hh @@ -0,0 +1,76 @@ +#ifndef ucoolib_utils_fifo_hh +#define ucoolib_utils_fifo_hh +// ucoolib - Microcontroller object oriented library. {{{ +// +// Copyright (C) 2012 Nicolas Schodet +// +// APBTeam: +// Web: http://apbteam.org/ +// Email: team AT apbteam DOT org +// +// This program 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 of the License, or +// (at your option) any later version. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "ucoolib/common.hh" + +namespace ucoo { + +/// First In First Out container. It is implemented as a circular buffer, +/// providing thread safety if the reader and the writer are in separated +/// threads. +/// +/// This is a rather low level container used to implement ucoolib features. +/// Be careful that there is only room for size - 1 elements in the FIFO. +template +class Fifo +{ + public: + /// Constructor, initialise an empty FIFO. + Fifo (); + /// Test whether the FIFO is empty. + bool empty () const { return head_ == tail_; } + /// Test whether the FIFO is full. + bool full () const { return head_ == next (tail_); } + /// Remove an element, do not do that if FIFO is empty! + T pop (); + /// Add an element, do not do that if FIFO is full! + void push (const T &e); + /// Pop up to COUNT elements and store them in BUF. Return the number of + /// read elements. + int read (T *buf, int count); + /// Push up to COUNT elements from BUF. Return the number of written + /// elements. + int write (const T *buf, int count); + private: + /// Return next index, use unsigned operation for optimisation. + int next (int index) const + { + return (static_cast (index) + 1) % size; + } + private: + /// Index of the next element to pop, always incremented. + int_atomic_t head_; + /// Index of the next free space where to put a pushed element, also + /// always incremented. + int_atomic_t tail_; + /// Memory to store elements. + T buffer_[size]; +}; + +} // namespace ucoo + +#include "fifo.tcc" + +#endif // ucoolib_utils_fifo_hh -- cgit v1.2.3