Skip to content

Commit

Permalink
get rid of libatomic
Browse files Browse the repository at this point in the history
  • Loading branch information
mbehr1 committed Nov 14, 2015
1 parent 64c5ec0 commit 9c92c77
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 15 deletions.
10 changes: 9 additions & 1 deletion include/protocols/MeterS0.hpp
Expand Up @@ -32,6 +32,12 @@

#include <protocols/Protocol.hpp>

// some helper functions. might need a namespace
void timespec_sub(const struct timespec &a, const struct timespec &b, struct timespec &res);
void timespec_add_ms(struct timespec &a, unsigned long ms);
unsigned long timespec_sub_ms(const struct timespec &a, const struct timespec &b);


class MeterS0 : public vz::protocol::Protocol {
public:
class HWIF {
Expand Down Expand Up @@ -104,6 +110,7 @@ class MeterS0 : public vz::protocol::Protocol {

protected:
void counter_thread();
void check_ref_for_overflow();

HWIF * _hwif;
HWIF * _hwif_dir; // for dir gpio pin
Expand All @@ -119,7 +126,8 @@ class MeterS0 : public vz::protocol::Protocol {
int _nonblocking_delay_ns;

struct timespec _time_last_read; // timestamp of last read. 1s interval based on this timestamp
std::atomic<struct timespec> _time_last_impulse; // timestamp of last impulse
struct timespec _time_last_ref; // reference timestamp for the millisecond delta
std::atomic<unsigned long> _ms_last_impulse; // ms of last impulse relative to _time_last_ref
struct timespec _time_last_impulse_returned; // timestamp of last impulse returned
bool _first_impulse;
};
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Expand Up @@ -70,7 +70,7 @@ if( TARGET )
target_link_libraries(vzlogger dl)
endif( ${TARGET} STREQUAL "ar71xx")
endif( TARGET )
target_link_libraries(vzlogger ${CURL_STATIC_LIBRARIES} ${CURL_LIBRARIES} ${GNUTLS_LIBRARIES} ${OPENSSL_LIBRARIES} atomic)
target_link_libraries(vzlogger ${CURL_STATIC_LIBRARIES} ${CURL_LIBRARIES} ${GNUTLS_LIBRARIES} ${OPENSSL_LIBRARIES} )

# add programs to the install target
INSTALL(PROGRAMS
Expand Down
4 changes: 2 additions & 2 deletions src/protocols/CMakeLists.txt
Expand Up @@ -25,8 +25,8 @@ else ( OMS_SUPPORT )
endif( OMS_SUPPORT )

set(proto_srcs
MeterS0.cpp
MeterD0.cpp
MeterS0.cpp ../../include/protocols/MeterS0.hpp
MeterD0.cpp ../../include/protocols/MeterD0.hpp
${sml_srcs}
MeterFluksoV2.cpp
${ocr_srcs}
Expand Down
58 changes: 50 additions & 8 deletions src/protocols/MeterS0.cpp
Expand Up @@ -156,7 +156,46 @@ void timespec_sub(const struct timespec &a, const struct timespec &b, struct tim
res.tv_nsec = a.tv_nsec - b.tv_nsec;
if (res.tv_nsec < 0) {
--res.tv_sec;
res.tv_nsec += 1e9;
res.tv_nsec += 1000000000ul;
}
}

unsigned long timespec_sub_ms(const struct timespec &a, const struct timespec &b)
{
unsigned long ret;
ret = a.tv_sec - b.tv_sec;
if (a.tv_nsec < b.tv_nsec) {
--ret;
ret *= 1000ul;
ret += (1000000000ul + a.tv_nsec - b.tv_nsec) / 1000000ul;
} else {
ret *= 1000ul;
ret += (a.tv_nsec - b.tv_nsec) / 1000000ul;
}
return ret;
}

void timespec_add_ms(struct timespec &a, unsigned long ms)
{
a.tv_sec += ms/1000ul;
a.tv_nsec += (ms%1000ul)*1000000ul;
// normalize nsec
while (a.tv_nsec >= 1000000000l) {
++a.tv_sec;
a.tv_nsec -= 1000000000l;
}
}

void MeterS0::check_ref_for_overflow()
{
// check whether _ms_last_impulse get's too long
// and has risk for overflow (roughly once a month with 32bit unsigned long)

if (_ms_last_impulse > (1ul<<30)) {
// now we enter a race condition so there might be wrong impulse now!
timespec_add_ms(_time_last_ref, 1ul<<30 );
_ms_last_impulse -= 1ul << 30;

}
}

Expand Down Expand Up @@ -186,7 +225,7 @@ void MeterS0::counter_thread()
if (_hwif->waitForImpulse()) {
struct timespec temp_ts;
clock_gettime(CLOCK_REALTIME, &temp_ts);
_time_last_impulse = temp_ts; // uses atomic operator=
_ms_last_impulse = timespec_sub_ms(temp_ts, _time_last_ref); // uses atomic operator=
if (_hwif_dir && ( _hwif_dir->status()>0 ) )
++_impulses_neg;
else
Expand Down Expand Up @@ -243,15 +282,16 @@ int MeterS0::open() {
_impulses = 0;
_impulses_neg = 0;

// create counter_thread and pass this as param
_counter_thread_stop = false;
_counter_thread = std::thread(&MeterS0::counter_thread, this);

clock_gettime(CLOCK_REALTIME, &_time_last_read); // we use realtime as this is returned as well (clock_monotonic would be better but...)
// store current time as last_time. Next read will return after 1s.
_time_last_impulse = _time_last_read;
_time_last_ref = _time_last_read;
_ms_last_impulse = 0;
_time_last_impulse_returned = _time_last_read;

// create counter_thread and pass this as param
_counter_thread_stop = false;
_counter_thread = std::thread(&MeterS0::counter_thread, this);

print(log_finest, "counter_thread created", name().c_str());

return SUCCESS;
Expand Down Expand Up @@ -306,7 +346,9 @@ ssize_t MeterS0::read(std::vector<Reading> &rds, size_t n) {
if (_hwif->is_blocking()) {
// we use the time from last impulse
t1 = _time_last_impulse_returned.tv_sec + _time_last_impulse_returned.tv_nsec / 1e9;
struct timespec temp_ts = _time_last_impulse; // uses atomic operator T
struct timespec temp_ts = _time_last_ref;
timespec_add_ms(temp_ts, _ms_last_impulse);
check_ref_for_overflow();
t2 = temp_ts.tv_sec + temp_ts.tv_nsec / 1e9;
_time_last_impulse_returned = temp_ts;
_time_last_read = req;
Expand Down
2 changes: 1 addition & 1 deletion tests/CMakeLists.txt
Expand Up @@ -38,7 +38,7 @@ target_link_libraries(vzlogger_unit_tests
${LIBUUID}
dl
pthread)
target_link_libraries(vzlogger_unit_tests ${CURL_STATIC_LIBRARIES} ${CURL_LIBRARIES} ${GNUTLS_LIBRARIES} ${OCR_LIBRARIES} atomic)
target_link_libraries(vzlogger_unit_tests ${CURL_STATIC_LIBRARIES} ${CURL_LIBRARIES} ${GNUTLS_LIBRARIES} ${OCR_LIBRARIES})

if( OMS_SUPPORT )
target_link_libraries(vzlogger_unit_tests ${MBUS_LIBRARY} ${OPENSSL_LIBRARIES})
Expand Down
4 changes: 2 additions & 2 deletions tests/mocks/CMakeLists.txt
Expand Up @@ -49,7 +49,7 @@ target_link_libraries(mock_metermap
pthread
${JSON_LIBRARY}
${LIBUUID}
dl atomic
dl
)
if(SML_FOUND)
target_link_libraries(mock_metermap ${SML_LIBRARY})
Expand Down Expand Up @@ -114,7 +114,7 @@ target_link_libraries(mock_MeterS0
pthread
${JSON_LIBRARY}
${LIBUUID}
dl atomic
dl
)
add_test(mock_MeterS0 mock_MeterS0)

Expand Down
53 changes: 53 additions & 0 deletions tests/mocks/mock_MeterS0.cpp
Expand Up @@ -31,6 +31,59 @@ class mock_S0hwif : public MeterS0::HWIF
protected:
};

TEST(mock_MeterS0, timespec_add_ms)
{
struct timespec a;
a.tv_sec = 1;
a.tv_nsec = 0;
timespec_add_ms(a, 1001);
ASSERT_EQ(2, a.tv_sec);
ASSERT_EQ(1000000, a.tv_nsec);
}

TEST(mock_MeterS0, timespec_add_ms2)
{
struct timespec a;
a.tv_sec = 1;
a.tv_nsec = 1000000000;
timespec_add_ms(a, 1000);
EXPECT_EQ(3, a.tv_sec);
ASSERT_EQ(0, a.tv_nsec);
}

TEST(mock_MeterS0, timespec_add_ms3)
{
struct timespec a;
a.tv_sec = 1;
a.tv_nsec = 1001000000;
timespec_add_ms(a, 1999);
EXPECT_EQ(4, a.tv_sec);
EXPECT_EQ(0, a.tv_nsec);
}

TEST(mock_MeterS0, timespec_sub_ms)
{
struct timespec a;
a.tv_sec = 1;
a.tv_nsec = 0;
struct timespec b;
b=a;
timespec_add_ms(a, 1999);
EXPECT_EQ(1999ul, timespec_sub_ms(a, b) );
}

TEST(mock_MeterS0, timespec_sub_ms2)
{
struct timespec a;
a.tv_sec = 2;
a.tv_nsec = 0;
struct timespec b;
b.tv_sec = 1;
b.tv_nsec = 1000000;
EXPECT_EQ(999ul, timespec_sub_ms(a, b) );
}


TEST(mock_MeterS0, basic_noopen)
{
mock_S0hwif *hwif = new mock_S0hwif();
Expand Down

0 comments on commit 9c92c77

Please sign in to comment.