From afe807c61372fe2481e73af63c8382af1e1d3011 Mon Sep 17 00:00:00 2001 From: Mauro Sardara Date: Wed, 4 Mar 2020 16:21:54 +0100 Subject: [HICN-540] Optimizations for libhicntransport Change-Id: I8b46b4eb2ef5488c09041887cc8296a216440f33 Signed-off-by: Mauro Sardara --- .../includes/hicn/transport/core/content_object.h | 2 - .../includes/hicn/transport/core/interest.h | 2 - libtransport/includes/hicn/transport/core/packet.h | 72 ++++++++++- .../includes/hicn/transport/utils/CMakeLists.txt | 1 + .../hicn/transport/utils/fixed_block_allocator.h | 136 +++++++++++++++++++++ 5 files changed, 204 insertions(+), 9 deletions(-) create mode 100644 libtransport/includes/hicn/transport/utils/fixed_block_allocator.h (limited to 'libtransport/includes') diff --git a/libtransport/includes/hicn/transport/core/content_object.h b/libtransport/includes/hicn/transport/core/content_object.h index 5af548fe4..822790e56 100644 --- a/libtransport/includes/hicn/transport/core/content_object.h +++ b/libtransport/includes/hicn/transport/core/content_object.h @@ -46,8 +46,6 @@ class ContentObject : public Packet { ~ContentObject() override; - void replace(MemBufPtr &&buffer) override; - const Name &getName() const override; Name &getWritableName() override; diff --git a/libtransport/includes/hicn/transport/core/interest.h b/libtransport/includes/hicn/transport/core/interest.h index f0c546a8e..c572afbff 100644 --- a/libtransport/includes/hicn/transport/core/interest.h +++ b/libtransport/includes/hicn/transport/core/interest.h @@ -44,8 +44,6 @@ class Interest ~Interest() override; - void replace(MemBufPtr &&buffer) override; - const Name &getName() const override; Name &getWritableName() override; diff --git a/libtransport/includes/hicn/transport/core/packet.h b/libtransport/includes/hicn/transport/core/packet.h index e758aa13e..3ddc4a595 100644 --- a/libtransport/includes/hicn/transport/core/packet.h +++ b/libtransport/includes/hicn/transport/core/packet.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -81,7 +82,12 @@ class Packet : public std::enable_shared_from_this { virtual ~Packet(); static std::size_t getHeaderSizeFromFormat(Format format, - std::size_t signature_size = 0); + std::size_t signature_size = 0) { + std::size_t header_length; + hicn_packet_get_header_length_from_format(format, &header_length); + int is_ah = _is_ah(format); + return is_ah * (header_length + signature_size) + (!is_ah) * header_length; + } static std::size_t getHeaderSizeFromBuffer(Format format, const uint8_t *buffer); @@ -91,9 +97,26 @@ class Packet : public std::enable_shared_from_this { static bool isInterest(const uint8_t *buffer); - static Format getFormatFromBuffer(const uint8_t *buffer); + static Format getFormatFromBuffer(const uint8_t *buffer) { + Format format = HF_UNSPEC; - virtual void replace(MemBufPtr &&buffer); + if (TRANSPORT_EXPECT_FALSE( + hicn_packet_get_format((const hicn_header_t *)buffer, &format) < + 0)) { + throw errors::MalformedPacketException(); + } + + return format; + } + + TRANSPORT_ALWAYS_INLINE void replace(MemBufPtr &&buffer) { + packet_ = std::move(buffer); + packet_start_ = reinterpret_cast(packet_->writableData()); + header_head_ = packet_.get(); + payload_head_ = nullptr; + format_ = getFormatFromBuffer(reinterpret_cast(packet_start_)); + name_.clear(); + } std::size_t payloadSize() const; @@ -123,6 +146,19 @@ class Packet : public std::enable_shared_from_this { std::unique_ptr getPayload() const; + std::pair getPayloadReference() const { + int signature_size = 0; + if (_is_ah(format_)) { + signature_size = (uint32_t)getSignatureSize(); + } + + auto header_size = getHeaderSizeFromFormat(format_, signature_size); + auto payload_length = packet_->length() - header_size; + + return std::make_pair(packet_->data() + header_size, + payload_length); + } + Packet &updateLength(std::size_t length = 0); PayloadType getPayloadType() const; @@ -152,7 +188,21 @@ class Packet : public std::enable_shared_from_this { virtual utils::CryptoHash computeDigest( utils::CryptoHashType algorithm) const; - void setChecksum(); + void setChecksum() { + uint16_t partial_csum = 0; + + for (utils::MemBuf *current = header_head_->next(); + current && current != header_head_; current = current->next()) { + if (partial_csum != 0) { + partial_csum = ~partial_csum; + } + partial_csum = csum(current->data(), current->length(), partial_csum); + } + if (hicn_packet_compute_header_checksum(format_, packet_start_, + partial_csum) < 0) { + throw errors::MalformedPacketException(); + } + } bool checkIntegrity() const; @@ -184,7 +234,19 @@ class Packet : public std::enable_shared_from_this { private: virtual void resetForHash() = 0; void setSignatureSize(std::size_t size_bytes); - std::size_t getSignatureSize() const; + + std::size_t getSignatureSize() const { + size_t size_bytes; + int ret = + hicn_packet_get_signature_size(format_, packet_start_, &size_bytes); + + if (ret < 0) { + throw errors::RuntimeException("Packet without Authentication Header."); + } + + return size_bytes; + } + uint8_t *getSignature() const; void separateHeaderPayload(); diff --git a/libtransport/includes/hicn/transport/utils/CMakeLists.txt b/libtransport/includes/hicn/transport/utils/CMakeLists.txt index 396bd06d6..38ecc3d37 100644 --- a/libtransport/includes/hicn/transport/utils/CMakeLists.txt +++ b/libtransport/includes/hicn/transport/utils/CMakeLists.txt @@ -28,6 +28,7 @@ list(APPEND HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/object_pool.h ${CMAKE_CURRENT_SOURCE_DIR}/membuf.h ${CMAKE_CURRENT_SOURCE_DIR}/spinlock.h + ${CMAKE_CURRENT_SOURCE_DIR}/fixed_block_allocator.h ) if(NOT WIN32) diff --git a/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h b/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h new file mode 100644 index 000000000..1ade1516e --- /dev/null +++ b/libtransport/includes/hicn/transport/utils/fixed_block_allocator.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2019 Cisco and/or its affiliates. + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace utils { +template +class FixedBlockAllocator { + FixedBlockAllocator(std::size_t size = DEFAULT_SIZE, + std::size_t objects = OBJECTS) + : block_size_(size < sizeof(void*) ? sizeof(long*) : size), + object_size_(size), + max_objects_(objects), + p_head_(NULL), + pool_index_(0), + block_count_(0), + blocks_in_use_(0), + allocations_(0), + deallocations_(0) { + p_pool_ = (uint8_t*)new uint8_t[block_size_ * max_objects_]; + } + + public: + static FixedBlockAllocator* getInstance() { + if (!instance_) { + instance_ = std::unique_ptr( + new FixedBlockAllocator(DEFAULT_SIZE, OBJECTS)); + } + + return instance_.get(); + } + + ~FixedBlockAllocator() { delete[] p_pool_; } + + TRANSPORT_ALWAYS_INLINE void* allocateBlock(size_t size = DEFAULT_SIZE) { + assert(size <= DEFAULT_SIZE); + uint32_t index; + + void* p_block = pop(); + if (!p_block) { + if (pool_index_ < max_objects_) { + { + SpinLock::Acquire locked(lock_); + index = pool_index_++; + } + p_block = (void*)(p_pool_ + (index * block_size_)); + } else { + // TODO Consider increasing pool here instead of throwing an exception + throw std::runtime_error("No more memory available from packet pool!"); + } + } + + blocks_in_use_++; + allocations_++; + + return p_block; + } + + TRANSPORT_ALWAYS_INLINE void deallocateBlock(void* pBlock) { + push(pBlock); + { + SpinLock::Acquire locked(lock_); + blocks_in_use_--; + deallocations_++; + } + } + + TRANSPORT_ALWAYS_INLINE std::size_t blockSize() { return block_size_; } + + TRANSPORT_ALWAYS_INLINE uint32_t blockCount() { return block_count_; } + + TRANSPORT_ALWAYS_INLINE uint32_t blocksInUse() { return blocks_in_use_; } + + TRANSPORT_ALWAYS_INLINE uint32_t allocations() { return allocations_; } + + TRANSPORT_ALWAYS_INLINE uint32_t deallocations() { return deallocations_; } + + private: + TRANSPORT_ALWAYS_INLINE void push(void* p_memory) { + Block* p_block = (Block*)p_memory; + { + SpinLock::Acquire locked(lock_); + p_block->p_next = p_head_; + p_head_ = p_block; + } + } + + TRANSPORT_ALWAYS_INLINE void* pop() { + Block* p_block = nullptr; + + { + SpinLock::Acquire locked(lock_); + if (p_head_) { + p_block = p_head_; + p_head_ = p_head_->p_next; + } + } + + return (void*)p_block; + } + + struct Block { + Block* p_next; + }; + + static std::unique_ptr instance_; + + const std::size_t block_size_; + const std::size_t object_size_; + const std::size_t max_objects_; + + Block* p_head_; + uint8_t* p_pool_; + uint32_t pool_index_; + uint32_t block_count_; + uint32_t blocks_in_use_; + uint32_t allocations_; + uint32_t deallocations_; + + SpinLock lock_; +}; + +template +std::unique_ptr> + FixedBlockAllocator::instance_ = nullptr; + +} // namespace utils \ No newline at end of file -- cgit 1.2.3-korg