Derecho  0.9
Distributed systems toolkit for RDMA
HLC.cpp
Go to the documentation of this file.
2 #include <errno.h>
3 #include <time.h>
4 
5 // return microsecond
6 uint64_t read_rtc_us() noexcept(false) {
7  struct timespec tp;
8  if(clock_gettime(CLOCK_REALTIME, &tp) != 0) {
9  throw HLC_EXP_READ_RTC(errno);
10  } else {
11  return (uint64_t)tp.tv_sec * 1000000 + tp.tv_nsec / 1000;
12  }
13 }
14 
15 HLC::HLC() noexcept(false) {
16  this->m_rtc_us = read_rtc_us();
17  this->m_logic = 0L;
18  if(pthread_spin_init(&this->m_oLck, PTHREAD_PROCESS_SHARED) != 0) {
19  throw HLC_EXP_SPIN_INIT(errno);
20  }
21 }
22 
23 HLC::HLC(uint64_t _r, uint64_t _l) : m_rtc_us(_r), m_logic(_l) {
24  if(pthread_spin_init(&this->m_oLck, PTHREAD_PROCESS_SHARED) != 0) {
25  throw HLC_EXP_SPIN_INIT(errno);
26  }
27 }
28 
29 HLC::~HLC() noexcept(false) {
30  if(pthread_spin_destroy(&this->m_oLck) != 0) {
31  throw HLC_EXP_SPIN_DESTROY(errno);
32  }
33 }
34 
35 #define HLC_LOCK \
36  if(pthread_spin_lock(&this->m_oLck) != 0) { \
37  throw HLC_EXP_SPIN_LOCK(errno); \
38  }
39 #define HLC_UNLOCK \
40  if(pthread_spin_unlock(&this->m_oLck) != 0) { \
41  throw HLC_EXP_SPIN_UNLOCK(errno); \
42  }
43 
44 void HLC::tick(bool thread_safe) noexcept(false) {
45  if(thread_safe) {
46  HLC_LOCK
47  }
48 
49  uint64_t rtc = read_rtc_us();
50  if(rtc <= this->m_rtc_us) {
51  this->m_logic++;
52  } else {
53  this->m_rtc_us = rtc;
54  this->m_logic = 0ull;
55  }
56 
57  if(thread_safe) {
59  }
60 }
61 
62 void HLC::tick(const HLC &msgHlc, bool thread_safe) noexcept(false) {
63  if(thread_safe) {
64  HLC_LOCK
65  }
66 
67  uint64_t rtc = read_rtc_us();
68  if((rtc > this->m_rtc_us) && (rtc > msgHlc.m_rtc_us)) {
69  // use rtc
70  this->m_rtc_us = rtc;
71  this->m_logic = 0ull;
72  } else if(*this >= msgHlc) {
73  // use this hlc
74  this->m_logic++;
75  } else {
76  // use msg hlc
77  this->m_rtc_us = msgHlc.m_rtc_us;
78  this->m_logic = msgHlc.m_logic + 1;
79  }
80 
81  if(thread_safe) {
83  }
84 }
85 
86 bool HLC::operator>(const HLC &hlc) const
87  noexcept(true) {
88  return (this->m_rtc_us > hlc.m_rtc_us) || (this->m_rtc_us == hlc.m_rtc_us && this->m_logic > hlc.m_logic);
89 }
90 
91 bool HLC::operator<(const HLC &hlc) const
92  noexcept(true) {
93  return hlc > *this && !(hlc == *this);
94 }
95 
96 bool HLC::operator==(const HLC &hlc) const
97  noexcept(true) {
98  return this->m_rtc_us == hlc.m_rtc_us && this->m_logic == hlc.m_logic;
99 }
100 
101 bool HLC::operator>=(const HLC &hlc) const
102  noexcept(true) {
103  return !(hlc > *this);
104 }
105 
106 bool HLC::operator<=(const HLC &hlc) const
107  noexcept(true) {
108  return !(*this > hlc);
109 }
110 
111 void HLC::operator=(const HLC &hlc) noexcept(true) {
112  this->m_rtc_us = hlc.m_rtc_us;
113  this->m_logic = hlc.m_logic;
114 }
virtual bool operator>(const HLC &hlc) const noexcept(true)
Definition: HLC.cpp:86
#define HLC_EXP_READ_RTC(x)
Definition: HLC.hpp:42
virtual bool operator<=(const HLC &hlc) const noexcept(true)
Definition: HLC.cpp:106
pthread_spinlock_t m_oLck
Definition: HLC.hpp:9
uint64_t read_rtc_us() noexcept(false)
Definition: HLC.cpp:6
virtual bool operator<(const HLC &hlc) const noexcept(true)
Definition: HLC.cpp:91
virtual void operator=(const HLC &hlc) noexcept(true)
Definition: HLC.cpp:111
virtual bool operator>=(const HLC &hlc) const noexcept(true)
Definition: HLC.cpp:101
#define HLC_UNLOCK
Definition: HLC.cpp:39
HLC(uint64_t _r, uint64_t _l)
Definition: HLC.cpp:15
Definition: HLC.hpp:7
#define HLC_EXP_SPIN_INIT(x)
Definition: HLC.hpp:43
virtual void tick(bool thread_safe=true) noexcept(false)
Definition: HLC.cpp:44
noexcept(false)
#define HLC_LOCK
Definition: HLC.cpp:35
virtual ~HLC() noexcept(false)
Definition: HLC.cpp:29
#define HLC_EXP_SPIN_DESTROY(x)
Definition: HLC.hpp:44
virtual bool operator==(const HLC &hlc) const noexcept(true)
Definition: HLC.cpp:96
uint64_t m_logic
Definition: HLC.hpp:13
uint64_t m_rtc_us
Definition: HLC.hpp:12