Permalink
Browse files

Fixed concurrent_spsc test issues. Added time_val::local_time().

  • Loading branch information...
1 parent 9b36955 commit ec9e7e7595f6cd5bc36dd6f394f7c371fc9b4523 @saleyn committed Jul 9, 2014
@@ -283,7 +283,7 @@ ::free(void* object)
BOOST_ASSERT(((p - m_begin) % m_object_size) == 0); // "Invalid object alignment!"
#ifdef USE_PID_RECOVERY
- pg->freed = 1;
+ obj->freed = 1;
#endif
size_t old_head, new_head;
@@ -111,9 +111,7 @@ class concurrent_spsc_queue : private boost::noncopyable
typedef T value_type;
/// @return memory size needed for allocating internal queue data.
- /// XXX: this does not tale into account that the actual capacity may be
- /// lower (a rounded-down power of 2):
- ///
+ /// Note that the actual capacity may be lower (a rounded-down power of 2).
static uint32_t memory_size(uint32_t a_capacity)
{ return sizeof(header) + a_capacity * sizeof(T); }
@@ -160,7 +158,7 @@ class concurrent_spsc_queue : private boost::noncopyable
: m_header (a_capacity)
, m_header_ptr (&m_header)
, m_rec_ptr (reinterpret_cast<T*>
- (::malloc(sizeof(T)*m_header.m_count)))
+ (::malloc(sizeof(T)*m_header.m_capacity)))
, m_shared_data(false)
, m_is_producer(false) // irrelevant in this case
, m_mask (m_header.m_capacity-1)
@@ -204,7 +202,7 @@ class concurrent_spsc_queue : private boost::noncopyable
// de-allocate the storage space:
if (StaticCapacity == 0 && !m_shared_data)
{
- assert(m_rec_ptr != NULL && m_rec_ptr != &m_records);
+ assert(m_rec_ptr != NULL && m_rec_ptr != m_records);
::free(m_rec_ptr);
}
}
View
@@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <boost/static_assert.hpp>
#include <utxx/detail/gettimeofday.hpp>
+#include <utxx/compiler_hints.hpp>
#include <cstddef>
#include <stdint.h>
#include <ctime>
@@ -167,6 +168,53 @@ namespace utxx {
time_val tv; ::gettimeofday(&tv, 0); return tv;
}
+ /// Construct a time_val from UTC "y/m/d-H:M:S"
+ static time_val universal_time(int year, int month, int day,
+ int hour, int min, int sec, int usec) {
+ static __thread int s_y, s_m, s_d;
+ static __thread time_t s_ymd;
+
+ if (year != s_y || month != s_m || day != s_d) {
+ struct tm tm = {0, 0, 0, day, month-1, year-1900};
+ s_ymd = ::mktime(&tm);
+ s_y = year;
+ s_m = month;
+ s_d = day;
+ }
+
+ time_val tv;
+ tv.m_tv.tv_sec = s_ymd + hour*3600 + min*60 + sec;
+ tv.m_tv.tv_usec = usec;
+ return tv;
+ };
+
+ /// Construct a time_val from local "y/m/d-H:M:S"
+ static time_val local_time(int year, int month, int day,
+ int hour, int min, int sec, int usec) {
+ static __thread int s_y, s_m, s_d, s_tzoffset;
+ static __thread time_t s_ymd;
+
+ if (year != s_y || month != s_m || day != s_d) {
+ if (unlikely(!s_tzoffset))
+ {
+ time_t now; time(&now);
+ struct tm ltm;
+ localtime_r(&now, &ltm);
+ s_tzoffset = ltm.tm_gmtoff;
+ }
+ struct tm tm = {0, 0, 0, day, month-1, year-1900};
+ s_ymd = ::mktime(&tm) + s_tzoffset;
+ s_y = year;
+ s_m = month;
+ s_d = day;
+ }
+
+ time_val tv;
+ tv.m_tv.tv_sec = s_ymd + hour*3600 + min*60 + sec;
+ tv.m_tv.tv_usec = usec;
+ return tv;
+ };
+
time_val& now(long addS, long addUS=0) {
::gettimeofday(&m_tv, 0); add(addS, addUS);
return *this;
@@ -169,8 +169,8 @@ class timestamp {
// We allow up to N usec to rely on HR timer readings between
// successive calls to gettimeofday.
- if ((l_hrtime_diff <= high_res_timer::global_scale_factor() << 2) &&
- (l_hr_now >= s_last_hrtime)) {
+ if ((l_hrtime_diff <= (high_res_timer::global_scale_factor() << 2)) &&
+ (l_hr_now >= s_last_hrtime)) {
#ifdef DEBUG_TIMESTAMP
atomic::inc(&s_hrcalls);
#endif
View
@@ -47,12 +47,15 @@ std::string to_bin_string(const char* buf, size_t sz, bool hex, bool readable) {
out << "<<" << (printable ? "\"" : "");
for(const char* p = begin; p != end; ++p) {
out << (p == begin || printable ? "" : ",");
- if (hex) out << std::hex;
- else if (printable) out << *p;
- else out << (int)*(unsigned char*)p;
+ if (printable)
+ out << *p;
+ else {
+ if (hex) out << std::hex;
+ out << (int)*(unsigned char*)p;
+ }
}
out << (printable ? "\"" : "") << ">>";
return out.str();
}
-} // namespace utxx
+} // namespace utxx
View
@@ -23,6 +23,7 @@ TEST_UTXX_SRCS = \
test_concurrent_stack.cpp \
test_concurrent_update.cpp \
test_concurrent_spsc_queue.cpp \
+ test_concurrent_mpsc_queue.cpp \
test_config_validator.cpp \
test_convert.cpp \
test_file_reader.cpp \
@@ -56,7 +56,7 @@ struct PerfTest {
} else {
while (!done_) {
T data;
- queue_.pop(data);
+ queue_.pop(&data);
}
}
}
@@ -139,14 +139,14 @@ struct CorrectnessTest {
for (auto expect : testData_) {
again:
T data;
- if (!queue_.pop(data)) {
+ if (!queue_.pop(&data)) {
if (!done_)
goto again;
// Try one more read; unless there's a bug in the queue class
// there should still be more data sitting in the queue even
// though the producer thread exited.
- if (!queue_.pop(data)) {
+ if (!queue_.pop(&data)) {
BOOST_REQUIRE(0 && "Finished too early ...");
return;
}
@@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE( test_concurrent_spsc_empty ) {
BOOST_REQUIRE(queue.full()); // Tricky: full after 3 writes, not 2.
BOOST_REQUIRE(!queue.push(4));
- BOOST_REQUIRE_EQUAL(queue.unsafe_size(), 3);
+ BOOST_REQUIRE_EQUAL(queue.count(), 3);
}
BOOST_AUTO_TEST_CASE( test_concurrent_spsc_correctness ) {
@@ -226,8 +226,8 @@ BOOST_AUTO_TEST_CASE( test_concurrent_spsc_destructor ) {
{
DtorChecker ignore;
- BOOST_REQUIRE(queue.pop(ignore));
- BOOST_REQUIRE(queue.pop(ignore));
+ BOOST_REQUIRE(queue.pop(&ignore));
+ BOOST_REQUIRE(queue.pop(&ignore));
}
BOOST_REQUIRE_EQUAL(DtorChecker::numInstances, 8);
@@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE( test_concurrent_spsc_destructor ) {
BOOST_REQUIRE_EQUAL(DtorChecker::numInstances, 3);
{
DtorChecker ignore;
- BOOST_REQUIRE(queue.pop(ignore));
+ BOOST_REQUIRE(queue.pop(&ignore));
}
BOOST_REQUIRE_EQUAL(DtorChecker::numInstances, 2);
BOOST_REQUIRE(queue.push(DtorChecker()));
View
@@ -38,6 +38,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <stdio.h>
#include <sstream>
#include <iostream>
+#include <time.h>
using namespace utxx;
@@ -67,6 +68,17 @@ BOOST_AUTO_TEST_CASE( test_time_val )
BOOST_REQUIRE_EQUAL(now.microseconds() + 2004003, add.microseconds());
BOOST_REQUIRE_EQUAL(4003, rel.usec());
+
+ {
+ time_t t; time(&t);
+ struct tm tm; localtime_r(&t, &tm);
+ time_val gmt = time_val::universal_time(2014, 7, 10, 0,0,0, 0);
+ time_val loc = time_val::local_time (2014, 7, 10, 0,0,0, 0);
+ BOOST_MESSAGE("TZ offset: " << tm.tm_gmtoff);
+ BOOST_MESSAGE("GMT time: " << gmt.sec());
+ BOOST_MESSAGE("Local time: " << loc.sec());
+ BOOST_REQUIRE_NE(gmt.sec() - loc.sec(), tm.tm_gmtoff);
+ }
}
View
@@ -181,7 +181,7 @@ struct test2 {
// Testing gettimeofday speed
{
caller test(id, "gettimeofday()", iterations);
- test(&time_val::universal_time);
+ test([]{ return time_val::universal_time(); });
}
// Testing boost::universal_time speed

0 comments on commit ec9e7e7

Please sign in to comment.