112853Sgabeblack@google.com/*****************************************************************************
212853Sgabeblack@google.com
312853Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412853Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512853Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612853Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712853Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812853Sgabeblack@google.com  License.  You may obtain a copy of the License at
912853Sgabeblack@google.com
1012853Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112853Sgabeblack@google.com
1212853Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312853Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412853Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512853Sgabeblack@google.com  implied.  See the License for the specific language governing
1612853Sgabeblack@google.com  permissions and limitations under the License.
1712853Sgabeblack@google.com
1812853Sgabeblack@google.com *****************************************************************************/
1912853Sgabeblack@google.com
2012853Sgabeblack@google.com/*****************************************************************************
2112853Sgabeblack@google.com
2212853Sgabeblack@google.com  sc_temporary.h -- Temporary value pool classes.
2312853Sgabeblack@google.com
2412853Sgabeblack@google.com  Original Author: Andy Goodrich, Forte Design Systems, Inc.
2512853Sgabeblack@google.com
2612853Sgabeblack@google.com  CHANGE LOG AT END OF FILE
2712853Sgabeblack@google.com *****************************************************************************/
2812853Sgabeblack@google.com
2912853Sgabeblack@google.com#ifndef __SYSTEMC_EXT_DT_SC_TEMPORARY_HH__
3012853Sgabeblack@google.com#define __SYSTEMC_EXT_DT_SC_TEMPORARY_HH__
3112853Sgabeblack@google.com
3212853Sgabeblack@google.com#include <cstddef> // std::size_t
3312853Sgabeblack@google.com
3412853Sgabeblack@google.comnamespace sc_core
3512853Sgabeblack@google.com{
3612853Sgabeblack@google.com
3712853Sgabeblack@google.com//-----------------------------------------------------------------------------
3812853Sgabeblack@google.com// sc_byte_heap - CLASS MANAGING A TEMPORARY HEAP OF BYTES
3912853Sgabeblack@google.com//
4012853Sgabeblack@google.com// This facility implements a heap of temporary byte allocations. Once an
4112853Sgabeblack@google.com// request has been allocated it is not freed. However the entire heap
4212853Sgabeblack@google.com// wraps and the storage is reused. This means that no allocations should
4312853Sgabeblack@google.com// be assumed as permanent. Allocations are double-word aligned. This is
4412853Sgabeblack@google.com// raw storage, so objects which contain virtual methods cannot be allocated
4512853Sgabeblack@google.com// with this object. See the sc_vpool object for that type of storage
4612853Sgabeblack@google.com// allocation.
4712853Sgabeblack@google.com//
4812853Sgabeblack@google.com// char* allocate( int size )
4912853Sgabeblack@google.com//   This method returns a pointer to block of size bytes. The block
5012853Sgabeblack@google.com//   returned is the next available one in the heap. If the current heap
5112853Sgabeblack@google.com//   cannot fullfil the request it will be rewound and storage allocated from
5212853Sgabeblack@google.com//   its start. All allocations start on an 8-byte boundary.
5312853Sgabeblack@google.com//       size = number of bytes to be allocated.
5412853Sgabeblack@google.com//
5512853Sgabeblack@google.com// void initialize( int heap_size=0x100000 )
5612853Sgabeblack@google.com//   This method allocates the storage to be managed. If there is already
5712853Sgabeblack@google.com//   a block of storage under management it is freed. If no argument is
5812853Sgabeblack@google.com//   provided for the heap size, a megabyte will be allocated.
5912853Sgabeblack@google.com//       heap_size = number of bytes to allocate for the heap.
6012853Sgabeblack@google.com//
6112853Sgabeblack@google.com// unsigned int length()
6212853Sgabeblack@google.com//   This method returns the size of this object's heap in bytes.
6312853Sgabeblack@google.com//
6412853Sgabeblack@google.com// sc_byte_heap()
6512853Sgabeblack@google.com//   This is the non-initialized object instance constructor. It does not
6612853Sgabeblack@google.com//   allocate the heap storage, that is done by the initialize() method.
6712853Sgabeblack@google.com//
6812853Sgabeblack@google.com// sc_byte_heap(int)
6912853Sgabeblack@google.com//   This is the initializing object instance constructor. It does allocates
7012853Sgabeblack@google.com//   a heap of the specified number of bytes.
7112853Sgabeblack@google.com//       heap_size = number of bytes to allocate for the heap.
7212853Sgabeblack@google.com//-----------------------------------------------------------------------------
7312853Sgabeblack@google.comclass sc_byte_heap
7412853Sgabeblack@google.com{
7512853Sgabeblack@google.com  public:
7612853Sgabeblack@google.com    char *m_bgn_p; // Beginning of heap storage.
7712853Sgabeblack@google.com    char *m_end_p; // End of heap storage.
7812853Sgabeblack@google.com    char *m_next_p; // Next heap location to be allocated.
7912853Sgabeblack@google.com
8012853Sgabeblack@google.com    inline char *
8112853Sgabeblack@google.com    allocate(std::size_t bytes_n)
8212853Sgabeblack@google.com    {
8312853Sgabeblack@google.com        char *result_p;
8412853Sgabeblack@google.com        bytes_n = (bytes_n + 7) & ((std::size_t)(-8));
8512853Sgabeblack@google.com        result_p = m_next_p;
8612853Sgabeblack@google.com        m_next_p += bytes_n;
8712853Sgabeblack@google.com        if (m_next_p >= m_end_p) {
8812853Sgabeblack@google.com            result_p = m_bgn_p;
8912853Sgabeblack@google.com            m_next_p = m_bgn_p + bytes_n;
9012853Sgabeblack@google.com        }
9112853Sgabeblack@google.com        return result_p;
9212853Sgabeblack@google.com    }
9312853Sgabeblack@google.com
9412853Sgabeblack@google.com    inline void
9512853Sgabeblack@google.com    initialize(std::size_t heap_size=0x100000)
9612853Sgabeblack@google.com    {
9712853Sgabeblack@google.com        delete [] m_bgn_p;
9812853Sgabeblack@google.com        m_bgn_p = new char[heap_size];
9912853Sgabeblack@google.com        m_end_p = &m_bgn_p[heap_size];
10012853Sgabeblack@google.com        m_next_p = m_bgn_p;
10112853Sgabeblack@google.com    }
10212853Sgabeblack@google.com
10312853Sgabeblack@google.com    inline std::size_t
10412853Sgabeblack@google.com    length()
10512853Sgabeblack@google.com    {
10612853Sgabeblack@google.com        return (std::size_t)(m_end_p - m_bgn_p);
10712853Sgabeblack@google.com    }
10812853Sgabeblack@google.com
10912853Sgabeblack@google.com    inline sc_byte_heap() : m_bgn_p(0), m_end_p(0), m_next_p(0) {}
11012853Sgabeblack@google.com
11112853Sgabeblack@google.com    inline sc_byte_heap(std::size_t heap_size) :
11212853Sgabeblack@google.com            m_bgn_p(0), m_end_p(0), m_next_p(0)
11312853Sgabeblack@google.com    {
11412853Sgabeblack@google.com        initialize(heap_size);
11512853Sgabeblack@google.com    }
11612853Sgabeblack@google.com
11712853Sgabeblack@google.com    inline ~sc_byte_heap() { delete [] m_bgn_p;	}
11812853Sgabeblack@google.com};
11912853Sgabeblack@google.com
12012853Sgabeblack@google.com
12112853Sgabeblack@google.com//-----------------------------------------------------------------------------
12212853Sgabeblack@google.com// sc_vpool<T> - CLASS MANAGING A TEMPORARY VECTOR OF CLASS T INSTANCES
12312853Sgabeblack@google.com//
12412853Sgabeblack@google.com// This class implements a fixed pool of objects contained in a vector. These
12512853Sgabeblack@google.com// objects are allocated via the allocate() method. An index, m_pool_i,
12612853Sgabeblack@google.com// indicates the next object to be allocated. The vector is a power of 2 in
12712853Sgabeblack@google.com// size, and this fact is used to wrap the list when m_pool_i reaches the
12812853Sgabeblack@google.com// end of the vector.
12912853Sgabeblack@google.com//
13012853Sgabeblack@google.com// sc_vpool( int log2, T* pool_p=0 )
13112853Sgabeblack@google.com//   This is the object instance constructor for this class. It configures
13212853Sgabeblack@google.com//   the object to manage a vector of 2**log2 entries. If a vector is
13312853Sgabeblack@google.com//   not supplied one will be allocated.
13412853Sgabeblack@google.com//     log2   =  the log base two of the size of the vector.
13512853Sgabeblack@google.com//     pool_p -> vector of 2**log2 entries to be managed or 0.
13612853Sgabeblack@google.com//
13712853Sgabeblack@google.com// ~sc_vpool()
13812853Sgabeblack@google.com//   This is the object instance destructor for this class. It frees the
13912853Sgabeblack@google.com//   block of storage which was being managed.
14012853Sgabeblack@google.com//
14112853Sgabeblack@google.com// T* allocate()
14212853Sgabeblack@google.com//   This method returns the address of the next entry in the vector, m_pool_p,
14312853Sgabeblack@google.com//   pointed to by the index, m_pool_i, and updates that index. The index
14412853Sgabeblack@google.com//   update consists of adding 1 to m_pool_i and masking it by m_wrap.
14512853Sgabeblack@google.com//
14612853Sgabeblack@google.com// void reset()
14712853Sgabeblack@google.com//   This method resets the allocation index, m_pool_i, to point to the start
14812853Sgabeblack@google.com//   of the vector of objects under management. This call is not usually made
14912853Sgabeblack@google.com//   since there are a fixed number of entries and the index wraps. However,
15012853Sgabeblack@google.com//   for diagnostics tests it is convenient to be able to reset to the start
15112853Sgabeblack@google.com//   of the vector.
15212853Sgabeblack@google.com//
15312853Sgabeblack@google.com// int size()
15412853Sgabeblack@google.com//   This method returns the number of object instances contained in the
15512853Sgabeblack@google.com//   vector being managed by this object instance.
15612853Sgabeblack@google.com//-----------------------------------------------------------------------------
15712853Sgabeblack@google.comtemplate<class T>
15812853Sgabeblack@google.comclass sc_vpool
15912853Sgabeblack@google.com{
16012853Sgabeblack@google.com  protected:
16112853Sgabeblack@google.com    std::size_t m_pool_i; // Index of next entry to m_pool_m to provide.
16212853Sgabeblack@google.com    T *m_pool_p; // Vector of temporaries.
16312853Sgabeblack@google.com    std::size_t m_wrap; // Mask to wrap vector index.
16412853Sgabeblack@google.com
16512853Sgabeblack@google.com  public:
16612853Sgabeblack@google.com    inline sc_vpool(int log2, T *pool_p=0);
16712853Sgabeblack@google.com    inline ~sc_vpool();
16812853Sgabeblack@google.com    inline T *allocate();
16912853Sgabeblack@google.com    inline void reset();
17012853Sgabeblack@google.com    inline std::size_t size();
17112853Sgabeblack@google.com};
17212853Sgabeblack@google.com
17312853Sgabeblack@google.comtemplate<class T>
17412853Sgabeblack@google.comsc_vpool<T>::sc_vpool(int log2, T *pool_p) : m_pool_i(0),
17512853Sgabeblack@google.com        m_pool_p(pool_p ? pool_p : new T[static_cast<std::size_t>(1) << log2]),
17612853Sgabeblack@google.com        m_wrap(~(static_cast<std::size_t>(-1) << log2))
17712853Sgabeblack@google.com{
17812853Sgabeblack@google.com    // if (log2 > 32) SC_REPORT_ERROR(SC_ID_POOL_SIZE_, "");
17912853Sgabeblack@google.com}
18012853Sgabeblack@google.com
18112853Sgabeblack@google.comtemplate<class T>
18212853Sgabeblack@google.comsc_vpool<T>::~sc_vpool()
18312853Sgabeblack@google.com{
18412853Sgabeblack@google.com    // delete [] m_pool_p;
18512853Sgabeblack@google.com}
18612853Sgabeblack@google.com
18712853Sgabeblack@google.comtemplate<class T>
18812853Sgabeblack@google.comT *sc_vpool<T>::allocate()
18912853Sgabeblack@google.com{
19012853Sgabeblack@google.com    T *result_p; // Entry to return.
19112853Sgabeblack@google.com
19212853Sgabeblack@google.com    result_p = &m_pool_p[m_pool_i];
19312853Sgabeblack@google.com    m_pool_i = (m_pool_i + 1) & m_wrap;
19412853Sgabeblack@google.com    return result_p;
19512853Sgabeblack@google.com}
19612853Sgabeblack@google.com
19712853Sgabeblack@google.comtemplate<class T>
19812853Sgabeblack@google.comvoid sc_vpool<T>::reset()
19912853Sgabeblack@google.com{
20012853Sgabeblack@google.com    m_pool_i = 0;
20112853Sgabeblack@google.com}
20212853Sgabeblack@google.com
20312853Sgabeblack@google.comtemplate<class T>
20412853Sgabeblack@google.comstd::size_t sc_vpool<T>::size() { return m_wrap + 1; }
20512853Sgabeblack@google.com
20612853Sgabeblack@google.com} // namespace sc_core
20712853Sgabeblack@google.com
20812853Sgabeblack@google.com// $Log: sc_temporary.h,v $
20912853Sgabeblack@google.com// Revision 1.4  2011/08/26 20:46:19  acg
21012853Sgabeblack@google.com//  Andy Goodrich: moved the modification log to the end of the file to
21112853Sgabeblack@google.com//  eliminate source line number skew when check-ins are done.
21212853Sgabeblack@google.com//
21312853Sgabeblack@google.com// Revision 1.3  2011/08/24 22:05:56  acg
21412853Sgabeblack@google.com//  Torsten Maehne: initialization changes to remove warnings.
21512853Sgabeblack@google.com//
21612853Sgabeblack@google.com// Revision 1.2  2011/02/18 20:38:44  acg
21712853Sgabeblack@google.com//  Andy Goodrich: Updated Copyright notice.
21812853Sgabeblack@google.com//
21912853Sgabeblack@google.com// Revision 1.1.1.1  2006/12/15 20:20:06  acg
22012853Sgabeblack@google.com// SystemC 2.3
22112853Sgabeblack@google.com//
22212853Sgabeblack@google.com// Revision 1.3  2006/01/13 18:53:11  acg
22312853Sgabeblack@google.com// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
22412853Sgabeblack@google.com// the source.
22512853Sgabeblack@google.com//
22612853Sgabeblack@google.com
22712853Sgabeblack@google.com#endif // __SYSTEMC_EXT_DT_SC_TEMPORARY_HH__
228