From 63422dfdcb1cd6827e76440cc147c9eac415952a Mon Sep 17 00:00:00 2001 From: Mauro Sardara Date: Mon, 8 Jul 2019 15:00:58 +0200 Subject: [HICN-242] Perform only one allocation for the whole buffer passed to produce() Change-Id: Ib4628d0a7711e2d7175b3dbb5c152dd22616ff32 Signed-off-by: Mauro Sardara --- lib/src/compat.c | 2 +- lib/src/compat.h | 2 +- .../src/hicn/transport/core/content_object.cc | 11 ++-- libtransport/src/hicn/transport/core/interest.cc | 8 +-- libtransport/src/hicn/transport/core/name.cc | 69 ++++++++-------------- libtransport/src/hicn/transport/core/name.h | 20 ++----- libtransport/src/hicn/transport/core/packet.cc | 5 +- .../src/hicn/transport/http/server_publisher.cc | 2 +- .../hicn/transport/interfaces/socket_producer.cc | 27 ++++++--- .../hicn/transport/interfaces/socket_producer.h | 6 ++ .../src/hicn/transport/utils/content_store.cc | 6 +- .../src/hicn/transport/utils/content_store.h | 2 +- utils/src/hiperf.cc | 18 ++++-- 13 files changed, 86 insertions(+), 92 deletions(-) diff --git a/lib/src/compat.c b/lib/src/compat.c index 63431a384..633037a0f 100644 --- a/lib/src/compat.c +++ b/lib/src/compat.c @@ -1033,7 +1033,7 @@ hicn_data_get_name (hicn_format_t format, const hicn_header_t * data, int hicn_data_set_name (hicn_format_t format, hicn_header_t * data, - hicn_name_t * name) + const hicn_name_t * name) { int ret_err = hicn_packet_set_ece (data); //data packet -> ece flag set if (ret_err < 0) diff --git a/lib/src/compat.h b/lib/src/compat.h index e174414a4..7228843bb 100644 --- a/lib/src/compat.h +++ b/lib/src/compat.h @@ -423,7 +423,7 @@ int hicn_interest_reset_for_hash (hicn_format_t format, int hicn_data_get_name (hicn_format_t format, const hicn_header_t * data, hicn_name_t * name); int hicn_data_set_name (hicn_format_t format, hicn_header_t * data, - hicn_name_t * name); + const hicn_name_t * name); int hicn_data_get_locator (hicn_format_t format, const hicn_header_t * data, ip_address_t * ip_address); int hicn_data_set_locator (hicn_format_t format, hicn_header_t * data, diff --git a/libtransport/src/hicn/transport/core/content_object.cc b/libtransport/src/hicn/transport/core/content_object.cc index 764d753cd..83b545c05 100644 --- a/libtransport/src/hicn/transport/core/content_object.cc +++ b/libtransport/src/hicn/transport/core/content_object.cc @@ -33,10 +33,8 @@ namespace core { ContentObject::ContentObject(const Name &name, Packet::Format format) : Packet(format) { - if (TRANSPORT_EXPECT_FALSE( - hicn_data_set_name(format, packet_start_, name.getStructReference()) < - 0)) { + hicn_data_set_name(format, packet_start_, &name.name_) < 0)) { throw errors::RuntimeException("Error filling the packet name."); } @@ -99,7 +97,8 @@ void ContentObject::replace(MemBufPtr &&buffer) { const Name &ContentObject::getName() const { if (!name_) { if (hicn_data_get_name(format_, packet_start_, - (hicn_name_t *)name_.getStructReference()) < 0) { + (hicn_name_t *)name_.getConstStructReference()) < + 0) { throw errors::MalformedPacketException(); } } @@ -110,8 +109,8 @@ const Name &ContentObject::getName() const { Name &ContentObject::getWritableName() { return const_cast(getName()); } void ContentObject::setName(const Name &name) { - if (hicn_data_set_name(format_, packet_start_, name.getStructReference()) < - 0) { + if (hicn_data_set_name(format_, packet_start_, + name.getConstStructReference()) < 0) { throw errors::RuntimeException("Error setting content object name."); } diff --git a/libtransport/src/hicn/transport/core/interest.cc b/libtransport/src/hicn/transport/core/interest.cc index e7d47d565..60ab10967 100644 --- a/libtransport/src/hicn/transport/core/interest.cc +++ b/libtransport/src/hicn/transport/core/interest.cc @@ -34,7 +34,7 @@ namespace core { Interest::Interest(const Name &interest_name, Packet::Format format) : Packet(format) { if (hicn_interest_set_name(format_, packet_start_, - interest_name.getStructReference()) < 0) { + interest_name.getConstStructReference()) < 0) { throw errors::MalformedPacketException(); } @@ -44,7 +44,6 @@ Interest::Interest(const Name &interest_name, Packet::Format format) } } - #ifdef __ANDROID__ Interest::Interest(hicn_format_t format) : Interest(Name("0::0|0"), format) {} #else @@ -85,7 +84,8 @@ void Interest::replace(MemBufPtr &&buffer) { const Name &Interest::getName() const { if (!name_) { if (hicn_interest_get_name(format_, packet_start_, - (hicn_name_t *)name_.getStructReference()) < 0) { + (hicn_name_t *)name_.getConstStructReference()) < + 0) { throw errors::MalformedPacketException(); } } @@ -97,7 +97,7 @@ Name &Interest::getWritableName() { return const_cast(getName()); } void Interest::setName(const Name &name) { if (hicn_interest_set_name(format_, packet_start_, - name.getStructReference()) < 0) { + name.getConstStructReference()) < 0) { throw errors::RuntimeException("Error setting interest name."); } diff --git a/libtransport/src/hicn/transport/core/name.cc b/libtransport/src/hicn/transport/core/name.cc index 867d3a755..0621eeeb5 100644 --- a/libtransport/src/hicn/transport/core/name.cc +++ b/libtransport/src/hicn/transport/core/name.cc @@ -24,21 +24,22 @@ namespace transport { namespace core { -Name::Name() { name_ = createEmptyName(); } +Name::Name() { name_ = {}; } Name::Name(int family, const uint8_t *ip_address, std::uint32_t suffix) - : name_(createEmptyName()) { + : name_({}) { + name_.type = HNT_UNSPEC; std::size_t length; uint8_t *dst = NULL; if (family == AF_INET) { - dst = name_->ip4.prefix_as_u8; + dst = name_.ip4.prefix_as_u8; length = IPV4_ADDR_LEN; - name_->type = HNT_CONTIGUOUS_V4; + name_.type = HNT_CONTIGUOUS_V4; } else if (family == AF_INET6) { - dst = name_->ip6.prefix_as_u8; + dst = name_.ip6.prefix_as_u8; length = IPV6_ADDR_LEN; - name_->type = HNT_CONTIGUOUS_V6; + name_.type = HNT_CONTIGUOUS_V6; } else { throw errors::RuntimeException("Specified name family does not exist."); } @@ -48,9 +49,8 @@ Name::Name(int family, const uint8_t *ip_address, std::uint32_t suffix) } Name::Name(const char *name, uint32_t segment) { - name_ = createEmptyName(); - - if (hicn_name_create(name, segment, name_.get()) < 0) { + name_.type = HNT_UNSPEC; + if (hicn_name_create(name, segment, &name_) < 0) { throw errors::InvalidIpAddressException(); } } @@ -59,6 +59,7 @@ Name::Name(const std::string &uri, uint32_t segment) : Name(uri.c_str(), segment) {} Name::Name(const std::string &uri) { + name_.type = HNT_UNSPEC; utils::StringTokenizer tokenizer(uri, "|"); std::string ip_address; std::string seq_number; @@ -71,30 +72,16 @@ Name::Name(const std::string &uri) { seq_number = "0"; } - name_ = createEmptyName(); - if (hicn_name_create(ip_address.c_str(), (uint32_t)atoi(seq_number.c_str()), - name_.get()) < 0) { + &name_) < 0) { throw errors::InvalidIpAddressException(); } } -Name::Name(const Name &name, bool hard_copy) { - name_ = createEmptyName(); - - if (hard_copy) { - if (hicn_name_copy(this->name_.get(), name.name_.get()) < 0) { - throw errors::MalformedNameException(); - } - } else { - *this->name_ = *name.name_; - } -} - -Name::Name(Name &&name) : name_(std::move(name.name_)) {} +Name::Name(const Name &name) { this->name_ = name.name_; } Name &Name::operator=(const Name &name) { - if (hicn_name_copy(this->name_.get(), name.name_.get()) < 0) { + if (hicn_name_copy(&this->name_, &name.name_) < 0) { throw errors::MalformedNameException(); } @@ -110,16 +97,16 @@ bool Name::operator!=(const Name &name) const { } Name::operator bool() const { - return bool(hicn_name_empty((hicn_name_t *)name_.get())); + return bool(hicn_name_empty((hicn_name_t *)&name_)); } bool Name::equals(const Name &name, bool consider_segment) const { - return !hicn_name_compare(name_.get(), name.name_.get(), consider_segment); + return !hicn_name_compare(&name_, &name.name_, consider_segment); } std::string Name::toString() const { char *name = new char[100]; - int ret = hicn_name_ntop(name_.get(), name, standard_name_string_length); + int ret = hicn_name_ntop(&name_, name, standard_name_string_length); if (ret < 0) { throw errors::MalformedNameException(); } @@ -131,22 +118,19 @@ std::string Name::toString() const { uint32_t Name::getHash32() const { uint32_t hash; - if (hicn_name_hash((hicn_name_t *)name_.get(), &hash) < 0) { + if (hicn_name_hash((hicn_name_t *)&name_, &hash) < 0) { throw errors::RuntimeException("Error computing the hash of the name!"); } return hash; } -void Name::clear() { - name_.reset(); - name_ = createEmptyName(); -}; +void Name::clear() { name_.type = HNT_UNSPEC; }; -Name::Type Name::getType() const { return name_->type; } +Name::Type Name::getType() const { return name_.type; } uint32_t Name::getSuffix() const { uint32_t ret = 0; - if (hicn_name_get_seq_number((hicn_name_t *)name_.get(), &ret) < 0) { + if (hicn_name_get_seq_number((hicn_name_t *)&name_, &ret) < 0) { throw errors::RuntimeException( "Impossible to retrieve the sequence number from the name."); } @@ -154,7 +138,7 @@ uint32_t Name::getSuffix() const { } Name &Name::setSuffix(uint32_t seq_number) { - if (hicn_name_set_seq_number(name_.get(), seq_number) < 0) { + if (hicn_name_set_seq_number(&name_, seq_number) < 0) { throw errors::RuntimeException( "Impossible to set the sequence number to the name."); } @@ -165,7 +149,7 @@ Name &Name::setSuffix(uint32_t seq_number) { std::shared_ptr Name::getAddress() const { Sockaddr *ret = nullptr; - switch (name_->type) { + switch (name_.type) { case HNT_CONTIGUOUS_V4: case HNT_IOV_V4: ret = (Sockaddr *)new Sockaddr4; @@ -178,7 +162,7 @@ std::shared_ptr Name::getAddress() const { throw errors::MalformedNameException(); } - if (hicn_name_to_sockaddr_address((hicn_name_t *)name_.get(), ret) < 0) { + if (hicn_name_to_sockaddr_address((hicn_name_t *)&name_, ret) < 0) { throw errors::MalformedNameException(); } @@ -189,7 +173,7 @@ ip_address_t Name::toIpAddress() const { ip_address_t ret; std::memset(&ret, 0, sizeof(ret)); - if (hicn_name_to_ip_address(name_.get(), &ret) < 0) { + if (hicn_name_to_ip_address(&name_, &ret) < 0) { throw errors::InvalidIpAddressException(); } @@ -199,7 +183,7 @@ ip_address_t Name::toIpAddress() const { int Name::getAddressFamily() const { int ret = 0; - if (hicn_name_get_family(name_.get(), &ret) < 0) { + if (hicn_name_get_family(&name_, &ret) < 0) { throw errors::InvalidIpAddressException(); } @@ -207,8 +191,7 @@ int Name::getAddressFamily() const { } void Name::copyToDestination(uint8_t *destination, bool include_suffix) const { - if (hicn_name_copy_to_destination(destination, name_.get(), include_suffix) < - 0) { + if (hicn_name_copy_to_destination(destination, &name_, include_suffix) < 0) { throw errors::RuntimeException( "Impossibe to copy the name into the " "provided destination"); diff --git a/libtransport/src/hicn/transport/core/name.h b/libtransport/src/hicn/transport/core/name.h index b2f913986..061371be5 100644 --- a/libtransport/src/hicn/transport/core/name.h +++ b/libtransport/src/hicn/transport/core/name.h @@ -67,9 +67,7 @@ class Name { Name(const std::string &uri); - Name(const Name &name, bool hard_copy = false); - - Name(Name &&name); + Name(const Name &name); Name &operator=(const Name &name); @@ -103,21 +101,13 @@ class Name { int getAddressFamily() const; private: - TRANSPORT_ALWAYS_INLINE NameStruct *getStructReference() const { - if (TRANSPORT_EXPECT_TRUE(name_ != nullptr)) { - return name_.get(); - } - - return nullptr; + TRANSPORT_ALWAYS_INLINE const NameStruct *getConstStructReference() const { + return &name_; } - static TRANSPORT_ALWAYS_INLINE std::unique_ptr createEmptyName() { - NameStruct *name = new NameStruct; - name->type = HNT_UNSPEC; - return std::unique_ptr(name); - }; + TRANSPORT_ALWAYS_INLINE NameStruct *getStructReference() { return &name_; } - std::unique_ptr name_; + NameStruct name_; }; std::ostream &operator<<(std::ostream &os, const Name &name); diff --git a/libtransport/src/hicn/transport/core/packet.cc b/libtransport/src/hicn/transport/core/packet.cc index 04ec74660..954266664 100644 --- a/libtransport/src/hicn/transport/core/packet.cc +++ b/libtransport/src/hicn/transport/core/packet.cc @@ -29,7 +29,7 @@ namespace transport { namespace core { - const core::Name Packet::base_name("0::0|0"); +const core::Name Packet::base_name("0::0|0"); Packet::Packet(Format format) : packet_(utils::MemBuf::create(getHeaderSizeFromFormat(format, 256)) @@ -37,8 +37,7 @@ Packet::Packet(Format format) packet_start_(reinterpret_cast(packet_->writableData())), header_head_(packet_.get()), payload_head_(nullptr), - format_(format){ - + format_(format) { if (hicn_packet_init_header(format, packet_start_) < 0) { throw errors::RuntimeException("Unexpected error initializing the packet."); } diff --git a/libtransport/src/hicn/transport/http/server_publisher.cc b/libtransport/src/hicn/transport/http/server_publisher.cc index 6a4bb9c48..b4deb5333 100644 --- a/libtransport/src/hicn/transport/http/server_publisher.cc +++ b/libtransport/src/hicn/transport/http/server_publisher.cc @@ -21,7 +21,7 @@ namespace transport { namespace http { HTTPServerPublisher::HTTPServerPublisher(const core::Name &content_name) - : content_name_(content_name, true) { + : content_name_(content_name) { std::string identity = "acceptor_producer"; producer_ = std::make_unique(); // utils::Identity::generateIdentity(identity)); diff --git a/libtransport/src/hicn/transport/interfaces/socket_producer.cc b/libtransport/src/hicn/transport/interfaces/socket_producer.cc index c85b8af32..9ca004c41 100644 --- a/libtransport/src/hicn/transport/interfaces/socket_producer.cc +++ b/libtransport/src/hicn/transport/interfaces/socket_producer.cc @@ -22,6 +22,8 @@ namespace transport { namespace interface { +namespace details {} + typedef std::chrono::time_point Time; typedef std::chrono::microseconds TimeDuration; @@ -133,13 +135,15 @@ void ProducerSocket::produce(ContentObject &content_object) { portal_->sendContentObject(content_object); } -uint32_t ProducerSocket::produce(Name content_name, const uint8_t *buf, - size_t buffer_size, bool is_last, - uint32_t start_offset) { - if (TRANSPORT_EXPECT_FALSE(buffer_size == 0)) { +uint32_t ProducerSocket::produce(Name content_name, + std::unique_ptr &&buffer, + bool is_last, uint32_t start_offset) { + if (TRANSPORT_EXPECT_FALSE(buffer->length() == 0)) { return 0; } + auto buffer_size = buffer->length(); + const std::size_t hash_size = 32; int bytes_segmented = 0; @@ -198,6 +202,8 @@ uint32_t ProducerSocket::produce(Name content_name, const uint8_t *buf, number_of_segments++; } + // TODO allocate space for all the headers + if (making_manifest_) { auto segment_in_manifest = static_cast( std::floor(double(data_packet_size_ - manifest_header_size - @@ -267,9 +273,11 @@ uint32_t ProducerSocket::produce(Name content_name, const uint8_t *buf, content_name.setSuffix(current_segment), format); content_object->setLifetime(content_object_expiry_time_); - if (packaged_segments == number_of_segments - 1) { - content_object->appendPayload(&buf[bytes_segmented], - buffer_size - bytes_segmented); + auto b = buffer->cloneOne(); + b->trimStart(free_space_for_content * packaged_segments); + b->trimEnd(b->length()); + if (TRANSPORT_EXPECT_FALSE(packaged_segments == number_of_segments - 1)) { + b->append(buffer_size - bytes_segmented); bytes_segmented += (int)(buffer_size - bytes_segmented); if (is_last && making_manifest_) { @@ -279,11 +287,12 @@ uint32_t ProducerSocket::produce(Name content_name, const uint8_t *buf, } } else { - content_object->appendPayload(&buf[bytes_segmented], - free_space_for_content); + b->append(free_space_for_content); bytes_segmented += (int)(free_space_for_content); } + content_object->appendPayload(std::move(b)); + if (making_manifest_) { using namespace std::chrono_literals; utils::CryptoHash hash = content_object->computeDigest(hash_algorithm_); diff --git a/libtransport/src/hicn/transport/interfaces/socket_producer.h b/libtransport/src/hicn/transport/interfaces/socket_producer.h index 744ddd86d..cd1c5a374 100644 --- a/libtransport/src/hicn/transport/interfaces/socket_producer.h +++ b/libtransport/src/hicn/transport/interfaces/socket_producer.h @@ -51,6 +51,12 @@ class ProducerSocket : public Socket, void connect() override; uint32_t produce(Name content_name, const uint8_t *buffer, size_t buffer_size, + bool is_last = true, uint32_t start_offset = 0) { + return produce(content_name, utils::MemBuf::copyBuffer(buffer, buffer_size), + is_last, start_offset); + } + + uint32_t produce(Name content_name, std::unique_ptr &&buffer, bool is_last = true, uint32_t start_offset = 0); void produce(ContentObject &content_object); diff --git a/libtransport/src/hicn/transport/utils/content_store.cc b/libtransport/src/hicn/transport/utils/content_store.cc index c3864310e..1e6b9fcea 100644 --- a/libtransport/src/hicn/transport/utils/content_store.cc +++ b/libtransport/src/hicn/transport/utils/content_store.cc @@ -31,7 +31,7 @@ void ContentStore::insert( return; } - std::unique_lock lock(cs_mutex_); + utils::SpinLock::Acquire locked(cs_mutex_); if (TRANSPORT_EXPECT_FALSE(content_store_hash_table_.size() != fifo_list_.size())) { @@ -64,7 +64,7 @@ void ContentStore::insert( const std::shared_ptr ContentStore::find( const Interest &interest) { - std::unique_lock lock(cs_mutex_); + utils::SpinLock::Acquire locked(cs_mutex_); auto it = content_store_hash_table_.find(interest.getName()); if (it != content_store_hash_table_.end()) { if (std::chrono::duration_cast( @@ -78,7 +78,7 @@ const std::shared_ptr ContentStore::find( } void ContentStore::erase(const Name &exact_name) { - std::unique_lock lock(cs_mutex_); + utils::SpinLock::Acquire locked(cs_mutex_); auto it = content_store_hash_table_.find(exact_name); fifo_list_.erase(it->second.second); content_store_hash_table_.erase(exact_name); diff --git a/libtransport/src/hicn/transport/utils/content_store.h b/libtransport/src/hicn/transport/utils/content_store.h index ba8ee5bd2..a89403a01 100644 --- a/libtransport/src/hicn/transport/utils/content_store.h +++ b/libtransport/src/hicn/transport/utils/content_store.h @@ -69,7 +69,7 @@ class ContentStore { FIFOList fifo_list_; std::shared_ptr empty_reference_; std::size_t max_content_store_size_; - std::mutex cs_mutex_; + utils::SpinLock cs_mutex_; }; } // end namespace utils \ No newline at end of file diff --git a/utils/src/hiperf.cc b/utils/src/hiperf.cc index 3f9cffd0c..b62173be8 100644 --- a/utils/src/hiperf.cc +++ b/utils/src/hiperf.cc @@ -610,15 +610,23 @@ class HIperfServer { void produceContent(uint32_t suffix) { core::Name name = configuration_.name.getName(); - std::string content(configuration_.download_size, '?'); + auto b = utils::MemBuf::create(configuration_.download_size); + std::memset(b->writableData(), '?', configuration_.download_size); + b->append(configuration_.download_size); uint32_t total; + utils::TimePoint t0 = utils::SteadyClock::now(); + total = producer_socket_->produce( - name, reinterpret_cast(content.data()), content.size(), - !configuration_.multiphase_produce_, suffix); + name, std::move(b), !configuration_.multiphase_produce_, suffix); - std::cout << "Written " << total << "pieces of data in output buffer" - << std::endl; + utils::TimePoint t1 = utils::SteadyClock::now(); + + std::cout + << "Written " << total + << " data packets in output buffer (Segmentation time: " + << std::chrono::duration_cast(t1 - t0).count() + << " us)" << std::endl; } std::shared_ptr setProducerIdentity( -- cgit 1.2.3-korg