Skip to content

Commit 4dca832

Browse files
author
pippocao
committed
Simplify wait_for posix
1 parent 0a3b95e commit 4dca832

File tree

1 file changed

+35
-57
lines changed

1 file changed

+35
-57
lines changed

src/bq_common/platform/thread/condition_variable_posix.cpp

Lines changed: 35 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -64,92 +64,70 @@ namespace bq {
6464
free(platform_data_);
6565
platform_data_ = nullptr;
6666
}
67-
static constexpr uint64_t one_billion = 1000000000ULL;
68-
69-
void condition_variable::wait(bq::platform::mutex& lock)
67+
68+
static uint64_t get_current_ns(bool use_monotonic)
7069
{
71-
int32_t result = pthread_cond_wait(&platform_data_->cond_handle, (pthread_mutex_t*)(lock.get_platform_handle()));
72-
if (result != 0) {
73-
bq::util::log_device_console(log_level::error, "pthread_cond_wait failed: %d", result);
74-
}
75-
}
76-
77-
static inline void add_timespec_ns(const struct timespec& base, uint64_t add_ns, struct timespec* out)
78-
{
79-
uint64_t ns = static_cast<uint64_t>(base.tv_nsec) + add_ns;
80-
out->tv_sec = static_cast<decltype(out->tv_sec)>(static_cast<int64_t>(base.tv_sec) + static_cast<int64_t>(ns / one_billion));
81-
out->tv_nsec = static_cast<decltype(out->tv_nsec)>(ns % one_billion);
82-
}
83-
84-
static uint64_t get_current_ns(bool prefer_monotonic)
85-
{
86-
struct timespec ts {};
70+
struct timespec ts;
8771
#if defined(BQ_POSIX_MONOTONIC_SUPPORTED)
88-
if (prefer_monotonic) {
72+
if (use_monotonic) {
8973
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
90-
return static_cast<uint64_t>(ts.tv_sec) * one_billion + static_cast<uint64_t>(ts.tv_nsec);
74+
return static_cast<uint64_t>(ts.tv_sec) * 1000000000ULL + static_cast<uint64_t>(ts.tv_nsec);
9175
}
9276
}
9377
#endif
94-
(void)prefer_monotonic;
9578
if (clock_gettime(CLOCK_REALTIME, &ts) == 0) {
96-
return static_cast<uint64_t>(ts.tv_sec) * one_billion + static_cast<uint64_t>(ts.tv_nsec);
79+
return static_cast<uint64_t>(ts.tv_sec) * 1000000000ULL + static_cast<uint64_t>(ts.tv_nsec);
9780
}
9881
return bq::platform::high_performance_epoch_ms() * 1000000ULL;
9982
}
10083

84+
void condition_variable::wait(bq::platform::mutex& lock)
85+
{
86+
int32_t result = pthread_cond_wait(&platform_data_->cond_handle, (pthread_mutex_t*)(lock.get_platform_handle()));
87+
if (result != 0) {
88+
bq::util::log_device_console(log_level::error, "pthread_cond_wait failed: %d", result);
89+
}
90+
}
91+
10192
bool condition_variable::wait_for(bq::platform::mutex& lock, uint64_t wait_time_ms)
10293
{
10394
const uint64_t wait_ns_total = wait_time_ms * 1000000ULL;
104-
const uint64_t quantum_ns = 50ULL * 1000000ULL; // 50ms
95+
const uint64_t quantum_ns = 50ULL * 1000000ULL; // 50ms slice
10596
const bool use_monotonic = platform_data_->use_monotonic_clock;
10697

10798
uint64_t start_ns = get_current_ns(use_monotonic);
10899
uint64_t deadline_ns = start_ns + wait_ns_total;
100+
uint64_t next_slice_ns = start_ns + quantum_ns;
109101

110-
for (;;) {
102+
while (true) {
111103
uint64_t now_ns = get_current_ns(use_monotonic);
112-
113-
if (now_ns >= deadline_ns)
104+
if (now_ns >= deadline_ns) {
114105
return false;
106+
}
115107

116-
uint64_t remain_ns = deadline_ns - now_ns;
117-
if (remain_ns > quantum_ns)
118-
remain_ns = quantum_ns;
108+
if (now_ns >= next_slice_ns) {
109+
uint64_t elapsed = now_ns - start_ns;
110+
uint64_t next_slice_idx = (elapsed / quantum_ns) + 1;
111+
next_slice_ns = start_ns + next_slice_idx * quantum_ns;
112+
}
119113

120-
struct timespec outtime {};
114+
uint64_t target_ns = (deadline_ns < next_slice_ns) ? deadline_ns : next_slice_ns;
121115

122-
#if defined(BQ_POSIX_MONOTONIC_SUPPORTED)
123-
if (use_monotonic) {
124-
struct timespec now_mono {};
125-
if (clock_gettime(CLOCK_MONOTONIC, &now_mono) != 0) {
126-
now_mono.tv_sec = static_cast<decltype(now_mono.tv_sec)>(now_ns / one_billion);
127-
now_mono.tv_nsec = static_cast<decltype(now_mono.tv_nsec)>(now_ns % one_billion);
128-
}
129-
add_timespec_ns(now_mono, remain_ns, &outtime);
130-
} else
131-
#endif
132-
{
133-
struct timespec now_rt {};
134-
if (clock_gettime(CLOCK_REALTIME, &now_rt) != 0) {
135-
struct timeval tv {};
136-
gettimeofday(&tv, nullptr);
137-
now_rt.tv_sec = static_cast<decltype(now_rt.tv_sec)>(tv.tv_sec);
138-
now_rt.tv_nsec = static_cast<decltype(now_rt.tv_nsec)>(tv.tv_usec * 1000L);
139-
}
140-
add_timespec_ns(now_rt, remain_ns, &outtime);
141-
}
116+
struct timespec ts;
117+
ts.tv_sec = static_cast<time_t>(target_ns / 1000000000ULL);
118+
ts.tv_nsec = static_cast<long>(target_ns % 1000000000ULL);
142119

143120
int32_t result = pthread_cond_timedwait(&platform_data_->cond_handle,
144121
(pthread_mutex_t*)(lock.get_platform_handle()),
145-
&outtime);
122+
&ts);
123+
146124
if (result == 0)
147125
return true;
148-
if (result == ETIMEDOUT)
149-
continue;
150-
151-
bq::util::log_device_console(log_level::error, "pthread_cond_timedwait failed: %d", result);
152-
return true;
126+
127+
if (result != ETIMEDOUT) {
128+
bq::util::log_device_console(log_level::error, "pthread_cond_timedwait failed: %d", result);
129+
return true;
130+
}
153131
}
154132
}
155133

0 commit comments

Comments
 (0)