17 #ifndef _TLM_TLM_MM_H_
18 #define _TLM_TLM_MM_H_
21 #include <type_traits>
22 #include <util/pool_allocator.h>
34 struct tlm_gp_mm :
public tlm_extension<tlm_gp_mm> {
37 void copy_from(ATTR_UNUSED tlm_extension_base
const& from)
override {
42 tlm_gp_mm* clone()
const override {
return tlm_gp_mm::create(data_size); }
44 size_t const data_size;
45 uint8_t*
const data_ptr;
46 uint8_t*
const be_ptr;
48 static tlm_gp_mm* create(
size_t sz,
bool be =
false);
50 template <
typename TYPES = tlm_base_protocol_types>
51 static typename TYPES::tlm_payload_type* add_data_ptr(
size_t sz,
typename TYPES::tlm_payload_type& gp,
bool be =
false) {
52 return add_data_ptr(sz, &gp, be);
54 template <
typename TYPES = tlm_base_protocol_types>
55 static typename TYPES::tlm_payload_type* add_data_ptr(
size_t sz,
typename TYPES::tlm_payload_type* gp,
bool be =
false);
58 tlm_gp_mm(
size_t sz, uint8_t* data_ptr, uint8_t* be_ptr)
74 :
tlm_gp_mm(sz, data, BE ? be :
nullptr) {}
76 uint8_t be[BE ? SZ : 0];
87 :
tlm_gp_mm(sz,
new uint8_t[sz],
nullptr) {}
90 inline tlm_gp_mm* tlm::scc::tlm_gp_mm::create(
size_t sz,
bool be) {
93 }
else if(sz > 1024) {
95 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<4096, true>)>::get().allocate()) tlm_gp_mm_t<4096, true>(sz);
97 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<4096, false>)>::get().allocate()) tlm_gp_mm_t<4096, false>(sz);
101 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<1024, true>)>::get().allocate()) tlm_gp_mm_t<1024, true>(sz);
103 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<1024, false>)>::get().allocate()) tlm_gp_mm_t<1024, false>(sz);
107 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<256, true>)>::get().allocate()) tlm_gp_mm_t<256, true>(sz);
109 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<256, false>)>::get().allocate()) tlm_gp_mm_t<256, false>(sz);
113 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<64, true>)>::get().allocate()) tlm_gp_mm_t<64, true>(sz);
115 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<64, false>)>::get().allocate()) tlm_gp_mm_t<64, false>(sz);
118 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<16, true>)>::get().allocate()) tlm_gp_mm_t<16, true>(sz);
120 return new(
util::pool_allocator<
sizeof(tlm_gp_mm_t<16, false>)>::get().allocate()) tlm_gp_mm_t<16, false>(sz);
124 template <
typename TYPES>
125 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) {
126 auto* ext = create(sz, be);
127 gp->set_auto_extension(ext);
128 gp->set_data_ptr(ext->data_ptr);
129 gp->set_data_length(sz);
130 gp->set_byte_enable_ptr(ext->be_ptr);
132 gp->set_byte_enable_length(sz);
144 EXT* clone()
const override {
return create(*
this); }
146 template <
typename... Args>
static EXT* create(Args... args) {
151 template <
typename... Args>
155 template <
typename TYPES>
struct tlm_mm_traits {
using mm_if_type = tlm::tlm_mm_interface; };
163 template <
typename TYPES,
bool CLEANUP_DATA,
typename BASE>
class tlm_mm_t :
public BASE {
164 using payload_type =
typename TYPES::tlm_payload_type;
166 static_assert(!std::is_base_of<tlm::tlm_generic_payload, typename TYPES::tlm_payload_type>::value,
"Using cxs::tlm_network_cxs_types");
186 auto* ptr = allocator.allocate(sc_core::sc_time_stamp().value());
187 return new(ptr) payload_type(
this);
193 template <
typename PEXT> payload_type*
allocate() {
195 ptr->set_auto_extension(
new PEXT);
202 void free(payload_base* trans) {
203 trans->~payload_base();
204 allocator.
free(trans);
211 template <
typename TYPES,
bool CLEANUP_DATA>
class tlm_mm_t<TYPES, CLEANUP_DATA,
tlm::tlm_mm_interface> :
public tlm::tlm_mm_interface {
212 using payload_type =
typename TYPES::tlm_payload_type;
232 auto* ptr = allocator.allocate(sc_core::sc_time_stamp().value());
233 return new(ptr) payload_type(
this);
239 template <
typename PEXT> payload_type*
allocate() {
241 ptr->set_auto_extension(
new PEXT);
254 template <
typename PEXT> payload_type*
allocate(
size_t sz,
bool be =
false) {
263 void free(tlm::tlm_generic_payload* trans) {
264 if(CLEANUP_DATA && !trans->get_extension<
tlm_gp_mm>()) {
265 if(trans->get_data_ptr())
266 delete[] trans->get_data_ptr();
267 if(trans->get_byte_enable_ptr())
268 delete[] trans->get_byte_enable_ptr();
270 trans->set_data_ptr(
nullptr);
271 trans->set_byte_enable_ptr(
nullptr);
273 trans->~tlm_generic_payload();
274 allocator.
free(trans);
281 template <
typename TYPES = tlm_base_protocol_types,
bool CLEANUP_DATA = true>
283 :
public tlm_mm_t<TYPES, CLEANUP_DATA,
284 typename std::conditional<std::is_base_of<tlm::tlm_generic_payload, typename TYPES::tlm_payload_type>::value,
285 tlm::tlm_mm_interface, typename tlm_mm_traits<TYPES>::mm_if_type>::type> {
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(size_t sz, bool be=false)
get a tlm_payload_type with registered extension and initialize data pointer
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 tlm_payload_type with registered extension
payload_type * allocate()
get a plain tlm_payload_type without extensions
payload_type * allocate()
get a tlm_payload_type with registered extension
void free(payload_base *trans)
return the extension into the memory pool (removing the extensions)
a generic pool allocator singleton not being MT-safe
void free(void *p)
pit the memory back into the pool
static tlm_mm & get()
accessor function of the singleton