osaf/libs/core/cplusplus/base/buffer.h | 26 +-
osaf/libs/core/cplusplus/base/log_message.cc | 106 -------------
osaf/libs/core/cplusplus/base/log_message.h | 126 +++++++++++++++-
osaf/libs/core/cplusplus/base/tests/log_message_test.cc | 14 +-
osaf/libs/core/mds/mds_log.cc | 4 +-
5 files changed, 141 insertions(+), 135 deletions(-)
Make the use of temporary Buffer instances on the stack more efficient, by
storing the buffer data in a character array inside the class instead of
allocating it dynamically.
diff --git a/osaf/libs/core/cplusplus/base/buffer.h
b/osaf/libs/core/cplusplus/base/buffer.h
--- a/osaf/libs/core/cplusplus/base/buffer.h
+++ b/osaf/libs/core/cplusplus/base/buffer.h
@@ -25,19 +25,14 @@
namespace base {
-// An output buffer that can be used to build e.g. a message to be sent over a
-// network.
+// An output buffer with enough space to store @a Capacity bytes of data. It
can
+// be used to build e.g. a message to be sent over a network.
+template <size_t Capacity>
class Buffer {
public:
- // Allocate a buffer with enough space to store @a capacity bytes of data.
- explicit Buffer(size_t capacity) :
- buffer_{new char[capacity]},
- capacity_{capacity},
+ Buffer() :
size_{0} {
}
- ~Buffer() {
- delete [] buffer_;
- }
// Reset the write position to the start of the buffer.
void clear() { size_ = 0; }
// Returns true if the buffer is empty.
@@ -45,16 +40,18 @@ class Buffer {
// Returns a pointer to the start of the buffer.
const char* data() const { return buffer_; }
// Returns a pointer to the end of the buffer where new data can be appended.
- char* end() const { return buffer_ + size_; }
+ char* end() { return buffer_ + size_; }
+ // Returns a read-only pointer to the end of the buffer.
+ const char* end() const { return buffer_ + size_; }
// Returns the number of bytes that have been written to the buffer.
size_t size() const { return size_; }
// Set new size of the buffer (e.g. after manually adding data at the end).
void set_size(size_t s) { size_ = s; }
// Returns the maximum number of bytes that can be stored in this buffer.
- size_t capacity() const { return capacity_; }
+ static size_t capacity() { return Capacity; }
// Append a single character to the end of the buffer.
void AppendChar(char c) {
- if (size_ != capacity_) buffer_[size_++] = c;
+ if (size_ != Capacity) buffer_[size_++] = c;
}
// This function is similar to AppendNumber(), except that leading zeros will
// be printed - i.e. this method implements a fixed field width.
@@ -77,7 +74,7 @@ class Buffer {
}
// Append a string of @a size characters to the end of the buffer.
void AppendString(const char* str, size_t size) {
- size_t bytes_to_copy = capacity_ - size_;
+ size_t bytes_to_copy = Capacity - size_;
if (size < bytes_to_copy) bytes_to_copy = size;
memcpy(buffer_ + size_, str, bytes_to_copy);
size_ += bytes_to_copy;
@@ -88,9 +85,8 @@ class Buffer {
}
private:
- char* buffer_;
- size_t capacity_;
size_t size_;
+ char buffer_[Capacity];
DELETE_COPY_AND_MOVE_OPERATORS(Buffer);
};
diff --git a/osaf/libs/core/cplusplus/base/log_message.cc
b/osaf/libs/core/cplusplus/base/log_message.cc
--- a/osaf/libs/core/cplusplus/base/log_message.cc
+++ b/osaf/libs/core/cplusplus/base/log_message.cc
@@ -16,115 +16,9 @@
*/
#include "osaf/libs/core/cplusplus/base/log_message.h"
-#include <time.h>
-#include <cstdint>
-#include "osaf/libs/core/common/include/osaf_time.h"
-#include "osaf/libs/core/cplusplus/base/buffer.h"
-#include "osaf/libs/core/cplusplus/base/time.h"
namespace base {
const struct timespec LogMessage::kNullTime{0, -1};
-void LogMessage::Write(Facility facility, Severity severity,
- const struct timespec& time_stamp,
- const HostName& host_name,
- const AppName& app_name,
- const ProcId& proc_id,
- const MsgId& msg_id,
- const StructuredElements& structured_elements,
- const std::string& message,
- Buffer* buffer) {
- uint32_t priority = static_cast<uint32_t>(facility) * uint32_t{8}
- + static_cast<uint32_t>(severity);
- buffer->AppendChar('<');
- buffer->AppendNumber(priority, 100);
- buffer->AppendString(">1 ", 3);
- WriteTime(time_stamp, buffer);
- buffer->AppendChar(' ');
- buffer->AppendString(host_name.data(), host_name.size());
- buffer->AppendChar(' ');
- buffer->AppendString(app_name.data(), app_name.size());
- buffer->AppendChar(' ');
- buffer->AppendString(proc_id.data(), proc_id.size());
- buffer->AppendChar(' ');
- buffer->AppendString(msg_id.data(), msg_id.size());
- buffer->AppendChar(' ');
- if (structured_elements.empty()) {
- buffer->AppendChar('-');
- } else {
- for (const auto& elem : structured_elements) elem.Write(buffer);
- }
- if (!message.empty()) {
- buffer->AppendChar(' ');
- buffer->AppendString(message.data(), message.size());
- }
-}
-
-void LogMessage::WriteTime(const struct timespec& ts, Buffer* buffer) {
- struct tm local_time;
- struct tm* local_ptr = localtime_r(&ts.tv_sec, &local_time);
- if (local_ptr != nullptr && local_ptr->tm_year >= -1900
- && local_ptr->tm_year <= (9999 - 1900)
- && ts.tv_nsec >= 0 && ts.tv_nsec < kNanosPerSec) {
- buffer->AppendFixedWidthNumber(local_ptr->tm_year + 1900, 1000);
- buffer->AppendChar('-');
- buffer->AppendFixedWidthNumber(local_ptr->tm_mon + 1, 10);
- buffer->AppendChar('-');
- buffer->AppendFixedWidthNumber(local_ptr->tm_mday, 10);
- buffer->AppendChar('T');
- buffer->AppendFixedWidthNumber(local_ptr->tm_hour, 10);
- buffer->AppendChar(':');
- buffer->AppendFixedWidthNumber(local_ptr->tm_min, 10);
- buffer->AppendChar(':');
- buffer->AppendFixedWidthNumber(local_ptr->tm_sec, 10);
- uint32_t decimals = ts.tv_nsec / 1000;
- if (decimals != 0) {
- uint32_t power = 100000;
- while (decimals % 10 == 0) {
- decimals /= 10;
- power /= 10;
- }
- buffer->AppendChar('.');
- buffer->AppendFixedWidthNumber(decimals, power);
- }
- char* buf = buffer->end();
- if ((buffer->capacity() - buffer->size()) >= 6 &&
- strftime(buf, 6, "%z", local_ptr) == 5) {
- if (buf[1] != '0' || buf[2] != '0' ||
- buf[3] != '0' || buf[4] != '0') {
- buf[5] = buf[4];
- buf[4] = buf[3];
- buf[3] = ':';
- buffer->set_size(buffer->size() + 6);
- } else {
- buffer->AppendChar('Z');
- }
- }
- } else {
- buffer->AppendChar('-');
- }
-}
-
-void LogMessage::Element::Write(Buffer* buffer) const {
- buffer->AppendChar('[');
- buffer->AppendString(id_.data(), id_.size());
- for (const Parameter& param : parameter_list_) {
- buffer->AppendChar(' ');
- param.Write(buffer);
- }
- buffer->AppendChar(']');
-}
-
-void LogMessage::Parameter::Write(Buffer* buffer) const {
- buffer->AppendString(name_.data(), name_.size());
- buffer->AppendChar('=');
- buffer->AppendChar('"');
- for (const char& c : value_) {
- if (c == '"' || c == '\\' || c == ']') buffer->AppendChar('\\');
- buffer->AppendChar(c);
- }
- buffer->AppendChar('"');
-}
-
} // namespace base
diff --git a/osaf/libs/core/cplusplus/base/log_message.h
b/osaf/libs/core/cplusplus/base/log_message.h
--- a/osaf/libs/core/cplusplus/base/log_message.h
+++ b/osaf/libs/core/cplusplus/base/log_message.h
@@ -18,13 +18,19 @@
#ifndef OSAF_LIBS_CORE_CPLUSPLUS_BASE_LOG_MESSAGE_H_
#define OSAF_LIBS_CORE_CPLUSPLUS_BASE_LOG_MESSAGE_H_
+#include <time.h>
+#include <cstddef>
+#include <cstdint>
#include <list>
#include <set>
#include <string>
+#include "osaf/libs/core/common/include/osaf_time.h"
+#include "osaf/libs/core/cplusplus/base/buffer.h"
+#include "osaf/libs/core/cplusplus/base/time.h"
namespace base {
-class Buffer;
+template <size_t Capacity> class Buffer;
// The LogMessage class implements support for formatting log records according
// to RFC 5424
@@ -135,7 +141,8 @@ class LogMessage {
Parameter(const SdName& name, const std::string& value) :
name_{name},
value_{value} {}
- void Write(Buffer* buffer) const;
+ template <size_t Capacity>
+ void Write(Buffer<Capacity>* buffer) const;
bool operator==(const Parameter& param) const {
return name_ == param.name_ && value_ == param.value_;
}
@@ -153,7 +160,8 @@ class LogMessage {
const ParameterList& parameter_list) :
id_{id},
parameter_list_{parameter_list} {}
- void Write(Buffer* buffer) const;
+ template <size_t Capacity>
+ void Write(Buffer<Capacity>* buffer) const;
bool operator<(const Element& elem) const { return id_ < elem.id_; }
bool operator==(const Element& elem) const {
return id_ == elem.id_ && parameter_list_ == elem.parameter_list_;
@@ -169,6 +177,7 @@ class LogMessage {
static const struct timespec kNullTime;
// Format a log record according to rfc5424 and write it to the provided
// buffer.
+ template <size_t Capacity>
static void Write(Facility facility, Severity severity,
const struct timespec& time_stamp,
const HostName& host_name,
@@ -177,10 +186,117 @@ class LogMessage {
const MsgId& msg_id,
const StructuredElements& structured_elements,
const std::string& message,
- Buffer* buffer);
- static void WriteTime(const struct timespec& ts, Buffer* buffer);
+ Buffer<Capacity>* buffer);
+ template <size_t Capacity>
+ static void WriteTime(const struct timespec& ts, Buffer<Capacity>* buffer);
};
+template <size_t Capacity>
+void LogMessage::Write(Facility facility, Severity severity,
+ const struct timespec& time_stamp,
+ const HostName& host_name,
+ const AppName& app_name,
+ const ProcId& proc_id,
+ const MsgId& msg_id,
+ const StructuredElements& structured_elements,
+ const std::string& message,
+ Buffer<Capacity>* buffer) {
+ uint32_t priority = static_cast<uint32_t>(facility) * uint32_t{8}
+ + static_cast<uint32_t>(severity);
+ buffer->AppendChar('<');
+ buffer->AppendNumber(priority, 100);
+ buffer->AppendString(">1 ", 3);
+ WriteTime(time_stamp, buffer);
+ buffer->AppendChar(' ');
+ buffer->AppendString(host_name.data(), host_name.size());
+ buffer->AppendChar(' ');
+ buffer->AppendString(app_name.data(), app_name.size());
+ buffer->AppendChar(' ');
+ buffer->AppendString(proc_id.data(), proc_id.size());
+ buffer->AppendChar(' ');
+ buffer->AppendString(msg_id.data(), msg_id.size());
+ buffer->AppendChar(' ');
+ if (structured_elements.empty()) {
+ buffer->AppendChar('-');
+ } else {
+ for (const auto& elem : structured_elements) elem.Write(buffer);
+ }
+ if (!message.empty()) {
+ buffer->AppendChar(' ');
+ buffer->AppendString(message.data(), message.size());
+ }
+}
+
+template <size_t Capacity>
+void LogMessage::WriteTime(const struct timespec& ts,
+ Buffer<Capacity>* buffer) {
+ struct tm local_time;
+ struct tm* local_ptr = localtime_r(&ts.tv_sec, &local_time);
+ if (local_ptr != nullptr && local_ptr->tm_year >= -1900
+ && local_ptr->tm_year <= (9999 - 1900)
+ && ts.tv_nsec >= 0 && ts.tv_nsec < kNanosPerSec) {
+ buffer->AppendFixedWidthNumber(local_ptr->tm_year + 1900, 1000);
+ buffer->AppendChar('-');
+ buffer->AppendFixedWidthNumber(local_ptr->tm_mon + 1, 10);
+ buffer->AppendChar('-');
+ buffer->AppendFixedWidthNumber(local_ptr->tm_mday, 10);
+ buffer->AppendChar('T');
+ buffer->AppendFixedWidthNumber(local_ptr->tm_hour, 10);
+ buffer->AppendChar(':');
+ buffer->AppendFixedWidthNumber(local_ptr->tm_min, 10);
+ buffer->AppendChar(':');
+ buffer->AppendFixedWidthNumber(local_ptr->tm_sec, 10);
+ uint32_t decimals = ts.tv_nsec / 1000;
+ if (decimals != 0) {
+ uint32_t power = 100000;
+ while (decimals % 10 == 0) {
+ decimals /= 10;
+ power /= 10;
+ }
+ buffer->AppendChar('.');
+ buffer->AppendFixedWidthNumber(decimals, power);
+ }
+ char* buf = buffer->end();
+ if ((buffer->capacity() - buffer->size()) >= 6 &&
+ strftime(buf, 6, "%z", local_ptr) == 5) {
+ if (buf[1] != '0' || buf[2] != '0' ||
+ buf[3] != '0' || buf[4] != '0') {
+ buf[5] = buf[4];
+ buf[4] = buf[3];
+ buf[3] = ':';
+ buffer->set_size(buffer->size() + 6);
+ } else {
+ buffer->AppendChar('Z');
+ }
+ }
+ } else {
+ buffer->AppendChar('-');
+ }
+}
+
+template <size_t Capacity>
+void LogMessage::Element::Write(Buffer<Capacity>* buffer) const {
+ buffer->AppendChar('[');
+ buffer->AppendString(id_.data(), id_.size());
+ for (const Parameter& param : parameter_list_) {
+ buffer->AppendChar(' ');
+ param.Write(buffer);
+ }
+ buffer->AppendChar(']');
+}
+
+template <size_t Capacity>
+void LogMessage::Parameter::Write(Buffer<Capacity>* buffer) const {
+ buffer->AppendString(name_.data(), name_.size());
+ buffer->AppendChar('=');
+ buffer->AppendChar('"');
+ for (const char& c : value_) {
+ if (c == '"' || c == '\\' || c == ']') buffer->AppendChar('\\');
+ buffer->AppendChar(c);
+ }
+ buffer->AppendChar('"');
+}
+
} // namespace base
#endif // OSAF_LIBS_CORE_CPLUSPLUS_BASE_LOG_MESSAGE_H_
diff --git a/osaf/libs/core/cplusplus/base/tests/log_message_test.cc
b/osaf/libs/core/cplusplus/base/tests/log_message_test.cc
--- a/osaf/libs/core/cplusplus/base/tests/log_message_test.cc
+++ b/osaf/libs/core/cplusplus/base/tests/log_message_test.cc
@@ -39,7 +39,7 @@ static const char null_text[] = "<0>1 -
TEST(LogMessageTest, WriteHelloWorld1) {
setenv("TZ", "Europe/Stockholm", 1);
tzset();
- base::Buffer buf{256};
+ base::Buffer<256> buf{};
base::LogMessage::Write(
base::LogMessage::Facility::kLocal0,
base::LogMessage::Severity::kNotice,
@@ -66,7 +66,7 @@ TEST(LogMessageTest, WriteHelloWorld1) {
TEST(LogMessageTest, WriteHelloWorld2) {
setenv("TZ", "Europe/Stockholm", 1);
tzset();
- base::Buffer buf{256};
+ base::Buffer<256> buf{};
base::LogMessage::Write(
base::LogMessage::Facility::kLocal7,
base::LogMessage::Severity::kDebug,
@@ -93,7 +93,7 @@ TEST(LogMessageTest, WriteHelloWorld2) {
TEST(LogMessageTest, WriteNullMessage) {
setenv("TZ", "Europe/Stockholm", 1);
tzset();
- base::Buffer buf(256);
+ base::Buffer<256> buf{};
base::LogMessage::Write(
base::LogMessage::Facility::kKern,
base::LogMessage::Severity::kEmerg,
@@ -116,7 +116,7 @@ TEST(LogMessageTest, WriteNullMessage) {
TEST(LogMessageTimeTest, WriteBCTime) {
setenv("TZ", "Europe/Stockholm", 1);
tzset();
- base::Buffer buf(256);
+ base::Buffer<256> buf{};
base::LogMessage::WriteTime({-62188992000, 0}, &buf);
EXPECT_EQ(buf.size(), 1);
EXPECT_EQ(memcmp(buf.data(), "-", 1), 0);
@@ -125,7 +125,7 @@ TEST(LogMessageTimeTest, WriteBCTime) {
TEST(LogMessageTimeTest, WriteFarFutureTime) {
setenv("TZ", "Europe/Stockholm", 1);
tzset();
- base::Buffer buf(256);
+ base::Buffer<256> buf{};
base::LogMessage::WriteTime({253423296000, 0}, &buf);
EXPECT_EQ(buf.size(), 1);
EXPECT_EQ(memcmp(buf.data(), "-", 1), 0);
@@ -136,7 +136,7 @@ TEST(LogMessageTimeTest, WriteTimeInSmal
static const char expected_result[] = "2016-10-10T16:24:02.505489";
setenv("TZ", "Europe/Stockholm", 1);
tzset();
- base::Buffer buf(30);
+ base::Buffer<30> buf{};
base::LogMessage::WriteTime({1476109442, 505489184}, &buf);
EXPECT_EQ(buf.size(), sizeof(expected_result) - 1);
EXPECT_EQ(memcmp(buf.data(), expected_result, buf.size()), 0);
@@ -146,7 +146,7 @@ TEST(LogMessageTimeTest, WriteTimeWithUt
static const char expected_result[] = "2016-10-10T14:33:32.82328Z";
setenv("TZ", "UTC", 1);
tzset();
- base::Buffer buf(256);
+ base::Buffer<256> buf{};
base::LogMessage::WriteTime({1476110012, 823280288}, &buf);
EXPECT_EQ(buf.size(), sizeof(expected_result) - 1);
EXPECT_EQ(memcmp(buf.data(), expected_result, buf.size()), 0);
diff --git a/osaf/libs/core/mds/mds_log.cc b/osaf/libs/core/mds/mds_log.cc
--- a/osaf/libs/core/mds/mds_log.cc
+++ b/osaf/libs/core/mds/mds_log.cc
@@ -59,7 +59,7 @@ class MdsLog {
base::LogMessage::AppName app_name_;
base::LogMessage::ProcId proc_id_;
uint64_t msg_id_;
- base::Buffer buffer_;
+ base::Buffer<512> buffer_;
base::UnixClientSocket log_socket_;
DELETE_COPY_AND_MOVE_OPERATORS(MdsLog);
@@ -75,7 +75,7 @@ MdsLog::MdsLog(const char* host_name, co
app_name_{base::LogMessage::AppName{app_name}},
proc_id_{base::LogMessage::ProcId{std::to_string(proc_id)}},
msg_id_{0},
- buffer_{512},
+ buffer_{},
log_socket_{socket_name} {
pthread_mutexattr_t attr;
int result = pthread_mutexattr_init(&attr);
------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel