16#ifndef CYBER_TRANSPORT_SHM_PROTOBUF_ARENA_MANAGER_H_
17#define CYBER_TRANSPORT_SHM_PROTOBUF_ARENA_MANAGER_H_
21#include <unordered_map>
24#include <google/protobuf/arena.h>
110 std::vector<std::shared_ptr<google::protobuf::Arena>>
arenas_;
161 uint64_t channel_id);
170 uint64_t block_index);
172 std::shared_ptr<ArenaSegment>
GetSegment(uint64_t channel_id);
175 const void* message)
override;
179 typename std::enable_if<
180 google::protobuf::Arena::is_arena_constructable<M>::value,
184 cyber::common::GlobalData::Instance()->GetChannelArenaConf(channel_id);
185 google::protobuf::ArenaOptions options;
186 options.start_block_size = arena_conf.max_msg_size();
187 options.max_block_size = arena_conf.max_msg_size();
199 if (!segment->AcquireBlockToWrite(size, &wb)) {
202 options.initial_block =
reinterpret_cast<char*
>(
204 options.initial_block_size = segment->message_capacity_;
209 std::make_shared<google::protobuf::Arena>(options);
213 ret_msg = std::shared_ptr<M>(google::protobuf::Arena::CreateMessage<M>(
214 segment->arenas_[wb.
block_index_].get()), [segment, wb](M* ptr){
215 int32_t lock_num = segment->blocks_[
216 wb.block_index_].lock_num_.load();
217 if (lock_num < ArenaSegmentBlock::kRWLockFree) {
218 segment->ReleaseWrittenBlock(wb);
225 typename std::enable_if<
226 !google::protobuf::Arena::is_arena_constructable<M>::value,
234 std::unordered_map<uint64_t, std::shared_ptr<ArenaSegment>> segments_;
235 std::mutex segments_mutex_;
237 std::shared_ptr<ArenaAddressAllocator> address_allocator_;
239 static ArenaAllocCallback arena_alloc_cb_;
240 static void* ArenaAlloc(uint64_t size);
241 static void ArenaDealloc(
void* addr, uint64_t size);
243 std::mutex arena_alloc_cb_mutex_;
245 std::unordered_map<uint64_t, uint64_t> managed_wrappers_;
void RemoveBlockReadLock(uint64_t block_index)
bool Init(uint64_t message_size, uint64_t block_num)
ArenaSegmentState * state_
bool Open(uint64_t message_size, uint64_t block_num)
std::vector< std::shared_ptr< google::protobuf::Arena > > arenas_
bool OpenOrCreate(uint64_t message_size, uint64_t block_num)
ArenaSegmentBlock * blocks_
uint64_t GetNextWritableBlockIndex()
bool AddBlockReadLock(uint64_t block_index)
bool AcquireBlockToRead(ArenaSegmentBlockInfo *block_info)
void RemoveBlockWriteLock(uint64_t block_index)
void ReleaseReadBlock(const ArenaSegmentBlockInfo &block_info)
void ReleaseWrittenBlock(const ArenaSegmentBlockInfo &block_info)
bool AddBlockWriteLock(uint64_t block_index)
bool AcquireBlockToWrite(uint64_t size, ArenaSegmentBlockInfo *block_info)
std::vector< uint64_t > arena_block_address_
uint64_t message_capacity_
uint64_t GetBaseAddress(const message::ArenaMessageWrapper *wrapper) override
std::shared_ptr< ArenaSegment > GetSegment(uint64_t channel_id)
void ResetMessageRelatedBlocks(message::ArenaMessageWrapper *wrapper)
void AcquireArenaMessage(uint64_t channel_id, std::shared_ptr< M > &ret_msg)
std::function< void *(uint64_t)> ArenaAllocCallback
void * GetMessage(message::ArenaMessageWrapper *wrapper) override
void SetMessageAddressOffset(message::ArenaMessageWrapper *wrapper, uint64_t offset)
uint64_t GetMessageAddressOffset(message::ArenaMessageWrapper *wrapper)
bool EnableSegment(uint64_t channel_id)
void SetMessageChannelId(message::ArenaMessageWrapper *wrapper, uint64_t channel_id)
uint64_t GetMessageChannelId(message::ArenaMessageWrapper *wrapper)
void * SetMessage(message::ArenaMessageWrapper *wrapper, const void *message) override
void AddMessageRelatedBlock(message::ArenaMessageWrapper *wrapper, uint64_t block_index)
std::vector< uint64_t > GetMessageRelatedBlocks(message::ArenaMessageWrapper *wrapper)
#define DECLARE_SINGLETON(classname)
void * block_buffer_address_
ArenaSegmentBlock * block_
static const int32_t kMaxTryLockTimes
static const int32_t kRWLockFree
std::atomic< int32_t > lock_num_
static const int32_t kWriteExclusive
std::atomic< uint64_t > reading_ref_count_
base::PthreadRWLock read_write_mutex_
std::atomic< uint64_t > writing_ref_count_
struct apollo::cyber::transport::ArenaSegmentBlockDescriptor::@4 struct_
std::atomic< uint64_t > message_seq_
std::atomic< bool > auto_extended_
struct apollo::cyber::transport::ArenaSegmentState::@3 struct_
std::atomic< uint64_t > ref_count_
std::atomic< uint64_t > message_size_
std::atomic< uint64_t > block_num_
uint64_t related_blocks_[4]
struct apollo::cyber::transport::ExtendedStruct::@5 meta_
uint64_t related_blocks_size_