summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Sardara <msardara@cisco.com>2019-07-08 15:00:58 +0200
committerMauro Sardara <msardara@cisco.com>2019-07-08 16:45:04 +0200
commit63422dfdcb1cd6827e76440cc147c9eac415952a (patch)
treeaeafaffb0e1f7a68c823611609e21983f51f5d0e
parent87cd4b4d22a08f1b56cd067770a29bcb05ebb845 (diff)
[HICN-242] Perform only one allocation for the whole buffer passed to produce()
Change-Id: Ib4628d0a7711e2d7175b3dbb5c152dd22616ff32 Signed-off-by: Mauro Sardara <msardara@cisco.com>
-rw-r--r--lib/src/compat.c2
-rw-r--r--lib/src/compat.h2
-rw-r--r--libtransport/src/hicn/transport/core/content_object.cc11
-rw-r--r--libtransport/src/hicn/transport/core/interest.cc8
-rw-r--r--libtransport/src/hicn/transport/core/name.cc69
-rw-r--r--libtransport/src/hicn/transport/core/name.h20
-rw-r--r--libtransport/src/hicn/transport/core/packet.cc5
-rw-r--r--libtransport/src/hicn/transport/http/server_publisher.cc2
-rw-r--r--libtransport/src/hicn/transport/interfaces/socket_producer.cc27
-rw-r--r--libtransport/src/hicn/transport/interfaces/socket_producer.h6
-rw-r--r--libtransport/src/hicn/transport/utils/content_store.cc6
-rw-r--r--libtransport/src/hicn/transport/utils/content_store.h2
-rw-r--r--utils/src/hiperf.cc18
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<Name &>(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<Name &>(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<Sockaddr> 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<Sockaddr> 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<NameStruct> createEmptyName() {
- NameStruct *name = new NameStruct;
- name->type = HNT_UNSPEC;
- return std::unique_ptr<NameStruct>(name);
- };
+ TRANSPORT_ALWAYS_INLINE NameStruct *getStructReference() { return &name_; }
- std::unique_ptr<NameStruct> 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<hicn_header_t *>(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<ProducerSocket>();
// 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<std::chrono::steady_clock> 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<utils::MemBuf> &&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<float>(
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<BasePortal>,
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<utils::MemBuf> &&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<std::mutex> 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<ContentObject> ContentStore::find(
const Interest &interest) {
- std::unique_lock<std::mutex> 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<std::chrono::milliseconds>(
@@ -78,7 +78,7 @@ const std::shared_ptr<ContentObject> ContentStore::find(
}
void ContentStore::erase(const Name &exact_name) {
- std::unique_lock<std::mutex> 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<ContentObject> 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<const uint8_t *>(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<utils::Microseconds>(t1 - t0).count()
+ << " us)" << std::endl;
}
std::shared_ptr<utils::Identity> setProducerIdentity(