C:/ESLX/projects/TLMWG/tlm2/include/tlm/tlm_h/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2008 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 3.0 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 //
00019 // To the LRM writer : this class is purely an artifact of the implementation.
00020 //
00021 
00022 #ifndef __CIRCULAR_BUFFER_H__
00023 #define __CIRCULAR_BUFFER_H__
00024 
00025 #include <iostream>
00026 
00027 namespace tlm {
00028 
00029 template < typename T >
00030 class circular_buffer
00031 {
00032 public:
00033   circular_buffer( int size );
00034 
00035   circular_buffer<T> &operator=( const circular_buffer<T> & ); 
00036 
00037   ~circular_buffer() { delete [] m_buf; }
00038   
00039   void resize( int size );
00040 
00041   const T &read();
00042   void write( const T & );
00043 
00044   bool is_empty() const { return used() == 0; }
00045   bool is_full() const { return free() == 0; }
00046 
00047   int size() const { return m_size; }
00048   int used() const { return m_used; }
00049   int free() const { return m_free; }
00050 
00051   T &write_data() { return m_buf[m_wi]; }
00052   const T &read_data() const { return m_buf[m_ri]; }
00053 
00054   const T &peek_data( int i ) const { return m_buf[(m_ri + i) % size()]; }
00055   T &poke_data( int i ) { return m_buf[(m_ri + i) % size()]; }
00056 
00057   void increment_write_pos( int i = 1 );
00058   void increment_read_pos( int i = 1 );
00059 
00060   void init();
00061 
00062   void debug() const;
00063 
00064 private:
00065   circular_buffer( const circular_buffer<T> &b ); // disabled
00066   void copy( const circular_buffer<T> &b );
00067 
00068 private:
00069   int m_size;                   // size of the buffer
00070   T*  m_buf;                    // the buffer
00071   int m_free;                   // number of free spaces
00072   int m_used;                   // number of used spaces
00073   int m_ri;                     // index of next read
00074   int m_wi;                     // index of next write
00075   
00076 };
00077 
00078 template< typename T >
00079 void
00080 circular_buffer<T>::debug() const
00081 {
00082 
00083   std::cout << "Buffer debug" << std::endl;
00084   std::cout << "Size : " << size() << std::endl;
00085   std::cout << "Free/Used " << free() << "/" << used() << std::endl;
00086   std::cout << "Indeces : r/w = " << m_ri << "/" << m_wi << std::endl;
00087 
00088   if( is_empty() ) {
00089 
00090     std::cout << "empty" << std::endl;
00091 
00092   }
00093 
00094   if( is_full() ) {
00095 
00096     std::cout << "full" << std::endl;
00097 
00098   }
00099 
00100   std::cout << "Data : " << std::endl;
00101   for( int i = 0; i < used(); i++ ) {
00102 
00103     std::cout << peek_data( i ) << std::endl;
00104 
00105   }
00106 
00107 
00108 }
00109 
00110 template < typename T >
00111 circular_buffer<T>::
00112 circular_buffer( int size ) {
00113 
00114   m_size = size;
00115   m_buf = new T[m_size];
00116 
00117   init();
00118 
00119 }
00120  
00121 template < typename T >
00122 circular_buffer<T> &
00123 circular_buffer<T>::operator=( const circular_buffer<T> &b ) {
00124 
00125   init();
00126 
00127   for( int i = 0; i < size() && i < b.used(); i++ ) {
00128 
00129     write( b.peek_data( i ) );
00130 
00131   }
00132 
00133   return *this;
00134   
00135 }
00136 
00137 template < typename T >
00138 void
00139 circular_buffer<T>::resize( int size )
00140 {
00141 
00142   int i;
00143   T *new_buf = new T[size];
00144 
00145   for( i = 0; i < size && i < used(); i++ ) {
00146 
00147     new_buf[i] = peek_data( i );
00148 
00149   }
00150 
00151   delete [] m_buf;
00152 
00153   m_size = size;
00154   m_ri = 0;
00155   m_wi = i % m_size;
00156   m_used = i;
00157   m_free = m_size - m_used;
00158   
00159   m_buf = new_buf;
00160 
00161 }
00162  
00163 
00164 template < typename T >
00165 void
00166 circular_buffer<T>::init() {
00167 
00168   m_free = m_size;
00169   m_used = 0;
00170   m_ri = 0;
00171   m_wi = 0;
00172 
00173 }
00174 
00175 template < typename T >
00176 void
00177 circular_buffer<T>::copy( const circular_buffer<T> &b )
00178 {
00179 
00180   m_size = b.m_size;   // size of the buffer
00181   m_buf = b.m_buf;     // the buffer
00182   m_free = b.m_free;   // number of free spaces
00183   m_used = b.m_used;   // number of used spaces
00184   m_ri = b.m_ri;       // index of next read
00185   m_wi = b.m_wi;       // index of next write  
00186 
00187 }
00188 
00189 template < typename T >
00190 const T &
00191 circular_buffer<T>::read()
00192 {
00193 
00194   const T &t = read_data();
00195 
00196   increment_read_pos();
00197 
00198   return t;
00199 
00200 }
00201 
00202 template < typename T >
00203 void
00204 circular_buffer<T>::write( const T &t )
00205 {
00206 
00207   write_data() = t;
00208   increment_write_pos();
00209 
00210 }
00211 
00212 
00213 template < typename T >
00214 void
00215 circular_buffer<T>::increment_write_pos( int i ) {
00216 
00217   m_wi = ( m_wi + i ) % m_size;
00218   m_used += i;
00219   m_free -= i;
00220   
00221 }
00222 
00223 template < typename T >
00224 void
00225 circular_buffer<T>::increment_read_pos( int i ) {
00226 
00227   m_ri = ( m_ri + i ) % m_size;
00228   m_used -= i;
00229   m_free += i;
00230   
00231 }
00232 
00233 } // namespace tlm
00234 
00235 #endif
00236 

Generated on Thu Jun 5 17:43:03 2008 for TLM 2 by  doxygen 1.5.3