27std::atomic<uint64_t> global_timer_id = {0};
28uint64_t GenerateTimerId() {
return global_timer_id.fetch_add(1); }
32 timing_wheel_ = TimingWheel::Instance();
33 timer_id_ = GenerateTimerId();
37 timing_wheel_ = TimingWheel::Instance();
38 timer_id_ = GenerateTimerId();
41Timer::Timer(uint32_t period, std::function<
void()> callback,
bool oneshot) {
42 timing_wheel_ = TimingWheel::Instance();
43 timer_id_ = GenerateTimerId();
44 timer_opt_.
period = period;
51bool Timer::InitTimerTask() {
52 if (timer_opt_.
period == 0) {
53 AERROR <<
"Max interval must great than 0";
57 if (timer_opt_.
period >= TIMER_MAX_INTERVAL_MS) {
58 AERROR <<
"Max interval must less than " << TIMER_MAX_INTERVAL_MS;
62 task_.reset(
new TimerTask(timer_id_));
63 task_->interval_ms = timer_opt_.
period;
64 task_->next_fire_duration_ms = task_->interval_ms;
66 std::weak_ptr<TimerTask> task_weak_ptr = task_;
67 task_->callback = [callback = this->timer_opt_.
callback, task_weak_ptr]() {
68 auto task = task_weak_ptr.lock();
70 std::lock_guard<std::mutex> lg(task->mutex);
75 std::weak_ptr<TimerTask> task_weak_ptr = task_;
76 task_->callback = [callback = this->timer_opt_.
callback, task_weak_ptr]() {
77 auto task = task_weak_ptr.lock();
81 std::lock_guard<std::mutex> lg(task->mutex);
85 uint64_t execute_time_ns = end - start;
86 uint64_t execute_time_ms =
87#if defined(__aarch64__)
88 ::llround(
static_cast<double>(execute_time_ns) / 1e6);
90 std::llround(
static_cast<double>(execute_time_ns) / 1e6);
92 if (task->last_execute_time_ns == 0) {
93 task->last_execute_time_ns = start;
95 task->accumulated_error_ns +=
96 start - task->last_execute_time_ns - task->interval_ms * 1000000;
98 ADEBUG <<
"start: " << start <<
"\t last: " << task->last_execute_time_ns
99 <<
"\t execut time:" << execute_time_ms
100 <<
"\t accumulated_error_ns: " << task->accumulated_error_ns;
101 task->last_execute_time_ns = start;
102 if (execute_time_ms >= task->interval_ms) {
103 task->next_fire_duration_ms = TIMER_RESOLUTION_MS;
105#if defined(__aarch64__)
106 int64_t accumulated_error_ms = ::llround(
108 int64_t accumulated_error_ms = std::llround(
110 static_cast<double>(task->accumulated_error_ns) / 1e6);
111 if (
static_cast<int64_t
>(task->interval_ms - execute_time_ms -
112 TIMER_RESOLUTION_MS) >= accumulated_error_ms) {
113 task->next_fire_duration_ms =
114 task->interval_ms - execute_time_ms - accumulated_error_ms;
116 task->next_fire_duration_ms = TIMER_RESOLUTION_MS;
118 ADEBUG <<
"error ms: " << accumulated_error_ms
119 <<
" execute time: " << execute_time_ms
120 <<
" next fire: " << task->next_fire_duration_ms
121 <<
" error ns: " << task->accumulated_error_ns;
123 TimingWheel::Instance()->AddTask(task);
130 if (!common::GlobalData::Instance()->IsRealityMode()) {
134 if (!started_.exchange(
true)) {
135 if (InitTimerTask()) {
137 AINFO <<
"start timer [" << task_->timer_id_ <<
"]";
143 if (started_.exchange(
false) && task_) {
144 AINFO <<
"stop timer, the timer_id: " << timer_id_;
146 auto tmp_task = task_;
148 std::lock_guard<std::mutex> lg(tmp_task->mutex);
uint64_t ToNanosecond() const
convert time to nanosecond.
void Stop()
Stop the timer
void SetTimerOption(TimerOption opt)
Set the Timer Option object
void Start()
Start the timer
void AddTask(const std::shared_ptr< TimerTask > &task)
uint32_t period
The period of the timer, unit is ms max: 512 * 64 min: 1
bool oneshot
True: perform the callback only after the first timing cycle False: perform the callback every timed ...
std::function< void()> callback
The task that the timer needs to perform