17 #ifndef _TLM_TLM_MM_H_
18 #define _TLM_TLM_MM_H_
21 #include <util/pool_allocator.h>
33 struct tlm_gp_mm :
public tlm_extension<tlm_gp_mm> {
36 void copy_from(ATTR_UNUSED tlm_extension_base
const& from)
override {
41 tlm_gp_mm* clone()
const override {
return tlm_gp_mm::create(data_size); }
43 size_t const data_size;
44 uint8_t*
const data_ptr;
45 uint8_t*
const be_ptr;
47 static tlm_gp_mm* create(
size_t sz,
bool be =
false);
49 template <
typename TYPES = tlm_base_protocol_types>
50 static typename TYPES::tlm_payload_type* add_data_ptr(
size_t sz,
typename TYPES::tlm_payload_type& gp,
bool be =
false) {
51 return add_data_ptr(sz, &gp, be);
53 template <
typename TYPES = tlm_base_protocol_types>
54 static typename TYPES::tlm_payload_type* add_data_ptr(
size_t sz,
typename TYPES::tlm_payload_type* gp,
bool be =
false);
57 tlm_gp_mm(
size_t sz, uint8_t* data_ptr, uint8_t* be_ptr)
73 :
tlm_gp_mm(sz, data, BE ? be :
nullptr) {}
75 uint8_t be[BE ? SZ : 0];
86 :
tlm_gp_mm(sz,
new uint8_t[sz],
nullptr) {}
89 inline tlm_gp_mm* tlm::scc::tlm_gp_mm::create(
size_t sz,
bool be) {
92 }
else if(sz > 1024) {
94 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<4096, true>)>::get().allocate()) tlm_gp_mm_t<4096, true>(sz);
96 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<4096, false>)>::get().allocate()) tlm_gp_mm_t<4096, false>(sz);
100 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<1024, true>)>::get().allocate()) tlm_gp_mm_t<1024, true>(sz);
102 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<1024, false>)>::get().allocate()) tlm_gp_mm_t<1024, false>(sz);
106 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<256, true>)>::get().allocate()) tlm_gp_mm_t<256, true>(sz);
108 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<256, false>)>::get().allocate()) tlm_gp_mm_t<256, false>(sz);
112 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<64, true>)>::get().allocate()) tlm_gp_mm_t<64, true>(sz);
114 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<64, false>)>::get().allocate()) tlm_gp_mm_t<64, false>(sz);
117 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<16, true>)>::get().allocate()) tlm_gp_mm_t<16, true>(sz);
119 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<16, false>)>::get().allocate()) tlm_gp_mm_t<16, false>(sz);
123 template <
typename TYPES>
124 inline typename TYPES::tlm_payload_type* tlm::scc::tlm_gp_mm::add_data_ptr(
size_t sz,
typename TYPES::tlm_payload_type* gp,
bool be) {
125 auto* ext = create(sz, be);
126 gp->set_auto_extension(ext);
127 gp->set_data_ptr(ext->data_ptr);
128 gp->set_data_length(sz);
129 gp->set_byte_enable_ptr(ext->be_ptr);
131 gp->set_byte_enable_length(sz);
143 EXT* clone()
const override {
return create(*
this); }
145 template <
typename... Args>
static EXT* create(Args... args) {
150 template <
typename... Args>
161 template <
typename TYPES = tlm_base_protocol_types,
bool CLEANUP_DATA = true>
class tlm_mm :
public tlm::tlm_mm_interface {
162 using payload_type =
typename TYPES::tlm_payload_type;
192 template <
typename PEXT> payload_type*
allocate() {
194 ptr->set_auto_extension(
new PEXT);
201 payload_type*
allocate(
size_t sz,
bool be =
false);
207 template <
typename PEXT> payload_type*
allocate(
size_t sz,
bool be =
false) {
216 void free(tlm::tlm_generic_payload* trans)
override;
227 template <
typename TYPES,
bool CLEANUP_DATA>
229 auto* ptr = allocator.allocate(sc_core::sc_time_stamp().value());
230 return new(ptr) payload_type(
this);
233 template <
typename TYPES,
bool CLEANUP_DATA>
235 return sz ? tlm_gp_mm::add_data_ptr(sz, allocate(), be) : allocate();
239 if(CLEANUP_DATA && !trans->get_extension<
tlm_gp_mm>()) {
240 if(trans->get_data_ptr())
241 delete[] trans->get_data_ptr();
242 trans->set_data_ptr(
nullptr);
243 if(trans->get_byte_enable_ptr())
244 delete[] trans->get_byte_enable_ptr();
245 trans->set_byte_enable_ptr(
nullptr);
248 trans->~tlm_generic_payload();
249 allocator.free(trans);
payload_type * allocate()
get a tlm_payload_type with registered extension
payload_type * allocate()
get a plain tlm_payload_type without extensions
payload_type * allocate(size_t sz, bool be=false)
get a tlm_payload_type with registered extension and initialize data pointer
void free(tlm::tlm_generic_payload *trans) override
return the extension into the memory pool (removing the extensions)
static tlm_mm & get()
accessor function of the singleton
a generic pool allocator singleton not being MT-safe
void free(void *p)
pit the memory back into the pool