22#include <util/pool_allocator.h>
41struct tlm_gp_mm :
public tlm_extension<tlm_gp_mm> {
42 virtual ~tlm_gp_mm() {}
44 void copy_from(ATTR_UNUSED tlm_extension_base
const& from)
override {
51 size_t const data_size;
52 uint8_t*
const data_ptr;
53 uint8_t*
const be_ptr;
55 static tlm_gp_mm*
create(
size_t sz,
bool be =
false);
57 template <
typename TYPES = tlm_base_protocol_types>
58 static typename TYPES::tlm_payload_type* add_data_ptr(
size_t sz,
typename TYPES::tlm_payload_type& gp,
bool be =
false) {
59 return add_data_ptr(sz, &gp, be);
61 template <
typename TYPES = tlm_base_protocol_types>
62 static typename TYPES::tlm_payload_type* add_data_ptr(
size_t sz,
typename TYPES::tlm_payload_type* gp,
bool be =
false);
65 tlm_gp_mm(
size_t sz, uint8_t* data_ptr, uint8_t* be_ptr)
77template <
size_t SZ,
bool BE = false>
struct tlm_gp_mm_t :
public tlm_gp_mm {
91 :
tlm_gp_mm(sz, data, BE ? be : nullptr) {}
93 uint8_t be[BE ? SZ : 0];
96struct tlm_gp_mm_v :
public tlm_gp_mm {
100 virtual ~tlm_gp_mm_v() {
delete data_ptr; }
103 tlm_gp_mm_v(
size_t sz)
104 : tlm_gp_mm(sz,
new uint8_t[sz],
nullptr) {}
117 }
else if(sz > 1024) {
123 }
else if(sz > 256) {
155template <
typename TYPES>
156inline typename TYPES::tlm_payload_type* tlm::scc::tlm_gp_mm::add_data_ptr(
size_t sz,
typename TYPES::tlm_payload_type* gp,
bool be) {
157 auto* ext =
create(sz, be);
158 gp->set_auto_extension(ext);
159 gp->set_data_ptr(ext->data_ptr);
160 gp->set_data_length(sz);
161 gp->set_byte_enable_ptr(ext->be_ptr);
163 gp->set_byte_enable_length(sz);
169template <
typename EXT>
struct tlm_ext_mm :
public EXT {
177 EXT* clone()
const override {
return create(*
this); }
179 template <
typename... Args>
static EXT* create(Args... args) {
180 return new(
util::pool_allocator<
sizeof(tlm_ext_mm<EXT>)>::get().allocate()) tlm_ext_mm<EXT>(args...);
184 template <
typename... Args>
185 tlm_ext_mm(Args... args)
188template <
typename TYPES>
struct tlm_mm_traits {
using mm_if_type = tlm::tlm_mm_interface; };
196template <
typename TYPES,
bool CLEANUP_DATA,
typename BASE>
class tlm_mm_t :
public BASE {
197 using payload_type =
typename TYPES::tlm_payload_type;
199 static_assert(!std::is_base_of<tlm::tlm_generic_payload, typename TYPES::tlm_payload_type>::value,
"Using cxs::tlm_network_cxs_types");
205 tlm_mm_t(
const tlm_mm_t&) =
delete;
207 tlm_mm_t(tlm_mm_t&&) =
delete;
209 tlm_mm_t& operator=(
const tlm_mm_t& other) =
delete;
211 tlm_mm_t& operator=(tlm_mm_t&& other) =
delete;
213 ~tlm_mm_t() =
default;
219 auto* ptr = allocator.allocate(sc_core::sc_time_stamp().value());
220 return new(ptr) payload_type(
this);
226 template <
typename PEXT> payload_type*
allocate() {
228 ptr->set_auto_extension(
new PEXT);
235 void free(payload_base* trans) {
236 trans->~payload_base();
237 allocator.free(trans);
250template <
typename TYPES,
bool CLEANUP_DATA>
class tlm_mm_t<TYPES, CLEANUP_DATA,
tlm::tlm_mm_interface> :
public tlm::tlm_mm_interface {
251 using payload_type =
typename TYPES::tlm_payload_type;
257 tlm_mm_t(
const tlm_mm_t&) =
delete;
259 tlm_mm_t(tlm_mm_t&&) =
delete;
261 tlm_mm_t& operator=(
const tlm_mm_t& other) =
delete;
263 tlm_mm_t& operator=(tlm_mm_t&& other) =
delete;
265 ~tlm_mm_t() =
default;
271 auto* ptr = allocator.allocate(sc_core::sc_time_stamp().value());
272 return new(ptr) payload_type(
this);
278 template <
typename PEXT> payload_type*
allocate() {
280 ptr->set_auto_extension(
new PEXT);
293 template <
typename PEXT> payload_type*
allocate(
size_t sz,
bool be =
false) {
295 ptr->set_auto_extension(tlm_ext_mm<PEXT>::create());
302 void free(tlm::tlm_generic_payload* trans) {
303 if(CLEANUP_DATA && !trans->get_extension<
tlm_gp_mm>()) {
304 if(trans->get_data_ptr())
305 delete[] trans->get_data_ptr();
306 if(trans->get_byte_enable_ptr())
307 delete[] trans->get_byte_enable_ptr();
309 trans->set_data_ptr(
nullptr);
310 trans->set_byte_enable_ptr(
nullptr);
312 trans->~tlm_generic_payload();
313 allocator.free(trans);
326template <
typename TYPES = tlm_base_protocol_types,
bool CLEANUP_DATA = true>
328:
public tlm_mm_t<TYPES, CLEANUP_DATA,
329 typename std::conditional<std::is_base_of<tlm::tlm_generic_payload, typename TYPES::tlm_payload_type>::value,
330 tlm::tlm_mm_interface, typename tlm_mm_traits<TYPES>::mm_if_type>::type> {
payload_type * allocate(size_t sz, bool be=false)
get a plain tlm_payload_type without extensions but initialized data and byte enable
payload_type * allocate()
get a plain tlm_payload_type without extensions
void free(tlm::tlm_generic_payload *trans)
return the extension into the memory pool (removing the extensions)
payload_type * allocate()
get a tlm_payload_type with registered extension
payload_type * allocate(size_t sz, bool be=false)
get a tlm_payload_type with registered extension and initialize data pointer
void free(payload_base *trans)
return the extension into the memory pool (removing the extensions)
payload_type * allocate()
get a tlm_payload_type with registered extension
payload_type * allocate()
get a plain tlm_payload_type without extensions
a generic pool allocator singleton not being MT-safe
void free(void *p)
pit the memory back into the pool
Creates a new tlm_gp_mm object with fixed size.
Memory management for TLM generic payload data.
static tlm_gp_mm * create(size_t sz, bool be=false)
Creates a new tlm_gp_mm object with a dynamically allocated buffer.
static tlm_mm & get()
accessor function of the singleton