00001 /*!@file Util/SharedBuffer.H a thread-safe buffer */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: David Berg <dberg@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/SharedBuffer.H $ 00035 00036 #ifndef UTIL_SHAREDBUFFER_H_DEFINED 00037 #define UTIL_SHAREDBUFFER_H_DEFINED 00038 00039 #include <deque> 00040 #include "Util/Semaphore.H" 00041 00042 // ###################################################################### 00043 //A simple thread-safe FIFO logic buffer. This buffer can be used to 00044 //safely read/write buffered data in a multi-threaded 00045 //consumer-producer enviornment. Push() and pop() are gaurenteed 00046 //atomic. The calling processing will block if pop() is called on an 00047 //empty buffer. The Buffer is allowed to grow unbounded. 00048 //###################################################################### 00049 template<class T> 00050 class SharedBuffer 00051 { 00052 public: 00053 //! Construct a shared buffer, FIFO logic, possibly zero padded 00054 inline SharedBuffer(const uint buffsize = 0); 00055 00056 //! destructor 00057 virtual inline ~SharedBuffer(); 00058 00059 //! push data on our queue 00060 inline void push(const T& element); 00061 00062 //!pop some data off our queue, removing from the queue 00063 inline T pop(); 00064 00065 //!post a message to stop waiting on pop(), allowing threads to 00066 //!exit. Should only be called during cleanup. 00067 inline void stopWaiting(); 00068 00069 private: 00070 std::deque<T> itsBuffer; 00071 Semaphore itsReadable,itsSISO; 00072 00073 }; 00074 00075 // ###################################################################### 00076 //inline implementations 00077 // ###################################################################### 00078 template<class T> 00079 inline SharedBuffer<T>::SharedBuffer(const uint zerobuffer) : 00080 itsBuffer(zerobuffer), itsReadable(0), itsSISO(1) 00081 { } 00082 00083 // ###################################################################### 00084 template<class T> 00085 inline SharedBuffer<T>::~SharedBuffer() 00086 { } 00087 00088 // ###################################################################### 00089 template<class T> 00090 inline void SharedBuffer<T>::push(const T& newitem) 00091 { 00092 itsSISO.wait(); 00093 itsBuffer.push_front(newitem); 00094 itsSISO.post(); 00095 itsReadable.post(); 00096 } 00097 00098 // ###################################################################### 00099 template<class T> 00100 inline T SharedBuffer<T>::pop() 00101 { 00102 itsReadable.wait(); 00103 itsSISO.wait(); 00104 //locked 00105 if (itsBuffer.size() > 0) 00106 { 00107 T temp = itsBuffer.back(); 00108 itsBuffer.pop_back(); 00109 //unlock 00110 itsSISO.post(); 00111 return temp; 00112 } 00113 T temp = T(); 00114 //unlock 00115 itsSISO.post(); 00116 itsReadable.post();//return the counter to +1 so nobody blocks. 00117 return temp; 00118 } 00119 00120 // ###################################################################### 00121 template<class T> 00122 inline void SharedBuffer<T>::stopWaiting() 00123 { 00124 itsReadable.post(); 00125 } 00126 00127 #endif 00128 // ###################################################################### 00129 /* So things look consistent in everyone's emacs... */ 00130 /* Local Variables: */ 00131 /* indent-tabs-mode: nil */ 00132 /* End: */