TLM-2.0: include/tlm/tlm_1/tlm_req_rsp/tlm_channels/tlm_fifo/circular_buffer.h Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# include/tlm/tlm_1/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