112027Sjungma@eit.uni-kl.de/*****************************************************************************
212027Sjungma@eit.uni-kl.de
312027Sjungma@eit.uni-kl.de  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412027Sjungma@eit.uni-kl.de  more contributor license agreements.  See the NOTICE file distributed
512027Sjungma@eit.uni-kl.de  with this work for additional information regarding copyright ownership.
612027Sjungma@eit.uni-kl.de  Accellera licenses this file to you under the Apache License, Version 2.0
712027Sjungma@eit.uni-kl.de  (the "License"); you may not use this file except in compliance with the
812027Sjungma@eit.uni-kl.de  License.  You may obtain a copy of the License at
912027Sjungma@eit.uni-kl.de
1012027Sjungma@eit.uni-kl.de    http://www.apache.org/licenses/LICENSE-2.0
1112027Sjungma@eit.uni-kl.de
1212027Sjungma@eit.uni-kl.de  Unless required by applicable law or agreed to in writing, software
1312027Sjungma@eit.uni-kl.de  distributed under the License is distributed on an "AS IS" BASIS,
1412027Sjungma@eit.uni-kl.de  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512027Sjungma@eit.uni-kl.de  implied.  See the License for the specific language governing
1612027Sjungma@eit.uni-kl.de  permissions and limitations under the License.
1712027Sjungma@eit.uni-kl.de
1812027Sjungma@eit.uni-kl.de *****************************************************************************/
1912027Sjungma@eit.uni-kl.de
2012027Sjungma@eit.uni-kl.de/*****************************************************************************
2112027Sjungma@eit.uni-kl.de
2212027Sjungma@eit.uni-kl.de  sc_temporary.h -- Temporary value pool classes.
2312027Sjungma@eit.uni-kl.de
2412027Sjungma@eit.uni-kl.de  Original Author: Andy Goodrich, Forte Design Systems, Inc.
2512027Sjungma@eit.uni-kl.de
2612027Sjungma@eit.uni-kl.de  CHANGE LOG AT END OF FILE
2712027Sjungma@eit.uni-kl.de *****************************************************************************/
2812027Sjungma@eit.uni-kl.de
2912027Sjungma@eit.uni-kl.de#ifndef SC_TEMPORARY_H
3012027Sjungma@eit.uni-kl.de#define SC_TEMPORARY_H
3112027Sjungma@eit.uni-kl.de
3212027Sjungma@eit.uni-kl.de#include <cstddef>                // std::size_t
3312027Sjungma@eit.uni-kl.de
3412027Sjungma@eit.uni-kl.denamespace sc_core {
3512027Sjungma@eit.uni-kl.de
3612027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
3712027Sjungma@eit.uni-kl.de// sc_byte_heap - CLASS MANAGING A TEMPORARY HEAP OF BYTES
3812027Sjungma@eit.uni-kl.de//
3912027Sjungma@eit.uni-kl.de// This facility implements a heap of temporary byte allocations. Once an
4012027Sjungma@eit.uni-kl.de// request has been allocated it is not freed. However the entire heap
4112027Sjungma@eit.uni-kl.de// wraps and the storage is reused. This means that no allocations should
4212027Sjungma@eit.uni-kl.de// be assumed as permanent. Allocations are double-word aligned. This is
4312027Sjungma@eit.uni-kl.de// raw storage, so objects which contain virtual methods cannot be allocated
4412027Sjungma@eit.uni-kl.de// with this object. See the sc_vpool object for that type of storage
4512027Sjungma@eit.uni-kl.de// allocation.
4612027Sjungma@eit.uni-kl.de//
4712027Sjungma@eit.uni-kl.de// char* allocate( int size )
4812027Sjungma@eit.uni-kl.de//   This method returns a pointer to block of size bytes. The block
4912027Sjungma@eit.uni-kl.de//   returned is the next available one in the heap. If the current heap
5012027Sjungma@eit.uni-kl.de//   cannot fullfil the request it will be rewound and storage allocated from
5112027Sjungma@eit.uni-kl.de//   its start. All allocations start on an 8-byte boundary.
5212027Sjungma@eit.uni-kl.de//       size = number of bytes to be allocated.
5312027Sjungma@eit.uni-kl.de//
5412027Sjungma@eit.uni-kl.de// void initialize( int heap_size=0x100000 )
5512027Sjungma@eit.uni-kl.de//   This method allocates the storage to be managed. If there is already
5612027Sjungma@eit.uni-kl.de//   a block of storage under management it is freed. If no argument is
5712027Sjungma@eit.uni-kl.de//   provided for the heap size, a megabyte will be allocated.
5812027Sjungma@eit.uni-kl.de//       heap_size = number of bytes to allocate for the heap.
5912027Sjungma@eit.uni-kl.de//
6012027Sjungma@eit.uni-kl.de// unsigned int length()
6112027Sjungma@eit.uni-kl.de//   This method returns the size of this object's heap in bytes.
6212027Sjungma@eit.uni-kl.de//
6312027Sjungma@eit.uni-kl.de// sc_byte_heap()
6412027Sjungma@eit.uni-kl.de//   This is the non-initialized object instance constructor. It does not
6512027Sjungma@eit.uni-kl.de//   allocate the heap storage, that is done by the initialize() method.
6612027Sjungma@eit.uni-kl.de//
6712027Sjungma@eit.uni-kl.de// sc_byte_heap(int)
6812027Sjungma@eit.uni-kl.de//   This is the initializing object instance constructor. It does allocates
6912027Sjungma@eit.uni-kl.de//   a heap of the specified number of bytes.
7012027Sjungma@eit.uni-kl.de//       heap_size = number of bytes to allocate for the heap.
7112027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
7212027Sjungma@eit.uni-kl.declass sc_byte_heap {
7312027Sjungma@eit.uni-kl.de  public:
7412027Sjungma@eit.uni-kl.de    char*  m_bgn_p;  // Beginning of heap storage.
7512027Sjungma@eit.uni-kl.de    char*  m_end_p;  // End of heap storage.
7612027Sjungma@eit.uni-kl.de    char*  m_next_p; // Next heap location to be allocated.
7712027Sjungma@eit.uni-kl.de
7812027Sjungma@eit.uni-kl.de    inline char* allocate( std::size_t bytes_n )
7912027Sjungma@eit.uni-kl.de    {
8012027Sjungma@eit.uni-kl.de        char*   result_p;
8112027Sjungma@eit.uni-kl.de        bytes_n = (bytes_n + 7) & ((std::size_t)(-8));
8212027Sjungma@eit.uni-kl.de        result_p = m_next_p;
8312027Sjungma@eit.uni-kl.de        m_next_p += bytes_n;
8412027Sjungma@eit.uni-kl.de        if ( m_next_p >= m_end_p )
8512027Sjungma@eit.uni-kl.de        {
8612027Sjungma@eit.uni-kl.de            result_p = m_bgn_p;
8712027Sjungma@eit.uni-kl.de            m_next_p = m_bgn_p + bytes_n;
8812027Sjungma@eit.uni-kl.de        }
8912027Sjungma@eit.uni-kl.de        return result_p;
9012027Sjungma@eit.uni-kl.de    }
9112027Sjungma@eit.uni-kl.de
9212027Sjungma@eit.uni-kl.de    inline void initialize( std::size_t heap_size=0x100000 )
9312027Sjungma@eit.uni-kl.de    {
9412027Sjungma@eit.uni-kl.de        delete [] m_bgn_p;
9512027Sjungma@eit.uni-kl.de        m_bgn_p = new char[heap_size];
9612027Sjungma@eit.uni-kl.de        m_end_p = &m_bgn_p[heap_size];
9712027Sjungma@eit.uni-kl.de        m_next_p = m_bgn_p;
9812027Sjungma@eit.uni-kl.de    }
9912027Sjungma@eit.uni-kl.de
10012027Sjungma@eit.uni-kl.de	inline std::size_t length()
10112027Sjungma@eit.uni-kl.de	{
10212027Sjungma@eit.uni-kl.de		return (std::size_t)(m_end_p - m_bgn_p);
10312027Sjungma@eit.uni-kl.de	}
10412027Sjungma@eit.uni-kl.de
10512027Sjungma@eit.uni-kl.de	inline sc_byte_heap() :
10612027Sjungma@eit.uni-kl.de	    m_bgn_p(0), m_end_p(0), m_next_p(0)
10712027Sjungma@eit.uni-kl.de	{
10812027Sjungma@eit.uni-kl.de	}
10912027Sjungma@eit.uni-kl.de
11012027Sjungma@eit.uni-kl.de		inline sc_byte_heap( std::size_t heap_size ) :
11112027Sjungma@eit.uni-kl.de	    m_bgn_p(0), m_end_p(0), m_next_p(0)
11212027Sjungma@eit.uni-kl.de	{
11312027Sjungma@eit.uni-kl.de		initialize( heap_size );
11412027Sjungma@eit.uni-kl.de	}
11512027Sjungma@eit.uni-kl.de
11612027Sjungma@eit.uni-kl.de	inline ~sc_byte_heap()
11712027Sjungma@eit.uni-kl.de	{
11812027Sjungma@eit.uni-kl.de		delete [] m_bgn_p;
11912027Sjungma@eit.uni-kl.de	}
12012027Sjungma@eit.uni-kl.de
12112027Sjungma@eit.uni-kl.de};
12212027Sjungma@eit.uni-kl.de
12312027Sjungma@eit.uni-kl.de
12412027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
12512027Sjungma@eit.uni-kl.de// sc_vpool<T> - CLASS MANAGING A TEMPORARY VECTOR OF CLASS T INSTANCES
12612027Sjungma@eit.uni-kl.de//
12712027Sjungma@eit.uni-kl.de// This class implements a fixed pool of objects contained in a vector. These
12812027Sjungma@eit.uni-kl.de// objects are allocated via the allocate() method. An index, m_pool_i,
12912027Sjungma@eit.uni-kl.de// indicates the next object to be allocated. The vector is a power of 2 in
13012027Sjungma@eit.uni-kl.de// size, and this fact is used to wrap the list when m_pool_i reaches the
13112027Sjungma@eit.uni-kl.de// end of the vector.
13212027Sjungma@eit.uni-kl.de//
13312027Sjungma@eit.uni-kl.de// sc_vpool( int log2, T* pool_p=0 )
13412027Sjungma@eit.uni-kl.de//   This is the object instance constructor for this class. It configures
13512027Sjungma@eit.uni-kl.de//   the object to manage a vector of 2**log2 entries. If a vector is
13612027Sjungma@eit.uni-kl.de//   not supplied one will be allocated.
13712027Sjungma@eit.uni-kl.de//     log2   =  the log base two of the size of the vector.
13812027Sjungma@eit.uni-kl.de//     pool_p -> vector of 2**log2 entries to be managed or 0.
13912027Sjungma@eit.uni-kl.de//
14012027Sjungma@eit.uni-kl.de// ~sc_vpool()
14112027Sjungma@eit.uni-kl.de//   This is the object instance destructor for this class. It frees the
14212027Sjungma@eit.uni-kl.de//   block of storage which was being managed.
14312027Sjungma@eit.uni-kl.de//
14412027Sjungma@eit.uni-kl.de// T* allocate()
14512027Sjungma@eit.uni-kl.de//   This method returns the address of the next entry in the vector, m_pool_p,
14612027Sjungma@eit.uni-kl.de//   pointed to by the index, m_pool_i, and updates that index. The index
14712027Sjungma@eit.uni-kl.de//   update consists of adding 1 to m_pool_i and masking it by m_wrap.
14812027Sjungma@eit.uni-kl.de//
14912027Sjungma@eit.uni-kl.de// void reset()
15012027Sjungma@eit.uni-kl.de//   This method resets the allocation index, m_pool_i, to point to the start
15112027Sjungma@eit.uni-kl.de//   of the vector of objects under management. This call is not usually made
15212027Sjungma@eit.uni-kl.de//   since there are a fixed number of entries and the index wraps. However,
15312027Sjungma@eit.uni-kl.de//   for diagnostics tests it is convenient to be able to reset to the start
15412027Sjungma@eit.uni-kl.de//   of the vector.
15512027Sjungma@eit.uni-kl.de//
15612027Sjungma@eit.uni-kl.de// int size()
15712027Sjungma@eit.uni-kl.de//   This method returns the number of object instances contained in the
15812027Sjungma@eit.uni-kl.de//   vector being managed by this object instance.
15912027Sjungma@eit.uni-kl.de//------------------------------------------------------------------------------
16012027Sjungma@eit.uni-kl.detemplate<class T>
16112027Sjungma@eit.uni-kl.declass sc_vpool {
16212027Sjungma@eit.uni-kl.de  protected:
16312027Sjungma@eit.uni-kl.de	std::size_t m_pool_i;	// Index of next entry to m_pool_m to provide.
16412027Sjungma@eit.uni-kl.de	T*          m_pool_p;	// Vector of temporaries.
16512027Sjungma@eit.uni-kl.de	std::size_t m_wrap;		// Mask to wrap vector index.
16612027Sjungma@eit.uni-kl.de
16712027Sjungma@eit.uni-kl.de  public:
16812027Sjungma@eit.uni-kl.de	inline sc_vpool( int log2, T* pool_p=0 );
16912027Sjungma@eit.uni-kl.de	inline ~sc_vpool();
17012027Sjungma@eit.uni-kl.de	inline T* allocate();
17112027Sjungma@eit.uni-kl.de	inline void reset();
17212027Sjungma@eit.uni-kl.de	inline std::size_t size();
17312027Sjungma@eit.uni-kl.de};
17412027Sjungma@eit.uni-kl.de
17512027Sjungma@eit.uni-kl.detemplate<class T> sc_vpool<T>::sc_vpool( int log2, T* pool_p )
17612027Sjungma@eit.uni-kl.de  : m_pool_i( 0 )
17712027Sjungma@eit.uni-kl.de  , m_pool_p( pool_p ? pool_p : new T[static_cast<std::size_t>(1) << log2] )
17812027Sjungma@eit.uni-kl.de  , m_wrap( ~(static_cast<std::size_t>(-1) << log2) )
17912027Sjungma@eit.uni-kl.de{
18012027Sjungma@eit.uni-kl.de	// if ( log2 > 32 ) SC_REPORT_ERROR(SC_ID_POOL_SIZE_, "");
18112027Sjungma@eit.uni-kl.de}
18212027Sjungma@eit.uni-kl.de
18312027Sjungma@eit.uni-kl.detemplate<class T> sc_vpool<T>::~sc_vpool()
18412027Sjungma@eit.uni-kl.de{
18512027Sjungma@eit.uni-kl.de	// delete [] m_pool_p;
18612027Sjungma@eit.uni-kl.de}
18712027Sjungma@eit.uni-kl.de
18812027Sjungma@eit.uni-kl.detemplate<class T> T* sc_vpool<T>::allocate()
18912027Sjungma@eit.uni-kl.de{
19012027Sjungma@eit.uni-kl.de	T* result_p;	// Entry to return.
19112027Sjungma@eit.uni-kl.de
19212027Sjungma@eit.uni-kl.de	result_p = &m_pool_p[m_pool_i];
19312027Sjungma@eit.uni-kl.de	m_pool_i = (m_pool_i + 1) & m_wrap;
19412027Sjungma@eit.uni-kl.de	return result_p;
19512027Sjungma@eit.uni-kl.de}
19612027Sjungma@eit.uni-kl.de
19712027Sjungma@eit.uni-kl.detemplate<class T> void sc_vpool<T>::reset()
19812027Sjungma@eit.uni-kl.de{
19912027Sjungma@eit.uni-kl.de	m_pool_i = 0;
20012027Sjungma@eit.uni-kl.de}
20112027Sjungma@eit.uni-kl.de
20212027Sjungma@eit.uni-kl.detemplate<class T> std::size_t sc_vpool<T>::size()
20312027Sjungma@eit.uni-kl.de{
20412027Sjungma@eit.uni-kl.de	return m_wrap + 1;
20512027Sjungma@eit.uni-kl.de}
20612027Sjungma@eit.uni-kl.de
20712027Sjungma@eit.uni-kl.de} // namespace sc_core
20812027Sjungma@eit.uni-kl.de
20912027Sjungma@eit.uni-kl.de// $Log: sc_temporary.h,v $
21012027Sjungma@eit.uni-kl.de// Revision 1.4  2011/08/26 20:46:19  acg
21112027Sjungma@eit.uni-kl.de//  Andy Goodrich: moved the modification log to the end of the file to
21212027Sjungma@eit.uni-kl.de//  eliminate source line number skew when check-ins are done.
21312027Sjungma@eit.uni-kl.de//
21412027Sjungma@eit.uni-kl.de// Revision 1.3  2011/08/24 22:05:56  acg
21512027Sjungma@eit.uni-kl.de//  Torsten Maehne: initialization changes to remove warnings.
21612027Sjungma@eit.uni-kl.de//
21712027Sjungma@eit.uni-kl.de// Revision 1.2  2011/02/18 20:38:44  acg
21812027Sjungma@eit.uni-kl.de//  Andy Goodrich: Updated Copyright notice.
21912027Sjungma@eit.uni-kl.de//
22012027Sjungma@eit.uni-kl.de// Revision 1.1.1.1  2006/12/15 20:20:06  acg
22112027Sjungma@eit.uni-kl.de// SystemC 2.3
22212027Sjungma@eit.uni-kl.de//
22312027Sjungma@eit.uni-kl.de// Revision 1.3  2006/01/13 18:53:11  acg
22412027Sjungma@eit.uni-kl.de// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
22512027Sjungma@eit.uni-kl.de// the source.
22612027Sjungma@eit.uni-kl.de//
22712027Sjungma@eit.uni-kl.de
22812027Sjungma@eit.uni-kl.de#endif // SC_TEMPORARY_H
229