Branch data Line data Source code
1 : : /* 2 : : * Copyright (C) 2026 by Thun Lu. All rights reserved. 3 : : * Author: Thun Lu <thun.lu@zohomail.cn> 4 : : * Repo: https://github.com/thun-res/vlink 5 : : * _ __ __ _ __ 6 : : * | | / / / / (_) ____ / /__ 7 : : * | | / / / / / / / __ \ / //_/ 8 : : * | |/ / / /___ / / / / / / / ,< 9 : : * |___/ /_____/ /_/ /_/ /_/ /_/|_| 10 : : * 11 : : * Licensed under the Apache License, Version 2.0 (the "License"); 12 : : * you may not use this file except in compliance with the License. 13 : : * You may obtain a copy of the License at 14 : : * 15 : : * http://www.apache.org/licenses/LICENSE-2.0 16 : : * 17 : : * Unless required by applicable law or agreed to in writing, software 18 : : * distributed under the License is distributed on an "AS IS" BASIS, 19 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 : : * See the License for the specific language governing permissions and 21 : : * limitations under the License. 22 : : */ 23 : : 24 : : #include "./base/deadline_timer.h" 25 : : 26 : : #include <algorithm> 27 : : #include <limits> 28 : : 29 : : namespace vlink { 30 : : 31 : : // DeadlineTimer 32 : 11 : DeadlineTimer::DeadlineTimer() noexcept = default; 33 : : 34 : 13 : DeadlineTimer::DeadlineTimer(int64_t interval, Accuracy accuracy) noexcept : accuracy_(accuracy) { 35 : 13 : set_deadline(interval); 36 : 13 : } 37 : : 38 : 1 : DeadlineTimer::DeadlineTimer(const DeadlineTimer& other) noexcept 39 : 2 : : deadline_(other.deadline_.load(std::memory_order_acquire)), accuracy_(other.accuracy_) {} 40 : : 41 : 1 : DeadlineTimer::DeadlineTimer(DeadlineTimer&& other) noexcept 42 : 2 : : deadline_(other.deadline_.load(std::memory_order_acquire)), accuracy_(other.accuracy_) {} 43 : : 44 : 26 : DeadlineTimer::~DeadlineTimer() noexcept = default; 45 : : 46 : 1 : DeadlineTimer& DeadlineTimer::operator=(const DeadlineTimer& other) noexcept { 47 [ - + ]: 1 : if VUNLIKELY (this == &other) { 48 : 0 : return *this; 49 : : } 50 : : 51 : 1 : accuracy_ = other.accuracy_; 52 : 2 : deadline_.store(other.deadline_.load(std::memory_order_acquire), std::memory_order_release); 53 : : 54 : 1 : return *this; 55 : : } 56 : : 57 : 1 : DeadlineTimer& DeadlineTimer::operator=(DeadlineTimer&& other) noexcept { 58 [ - + ]: 1 : if VUNLIKELY (this == &other) { 59 : 0 : return *this; 60 : : } 61 : : 62 : 1 : accuracy_ = other.accuracy_; 63 : 2 : deadline_.store(other.deadline_.load(std::memory_order_acquire), std::memory_order_release); 64 : : 65 : 1 : return *this; 66 : : } 67 : : 68 : 19 : void DeadlineTimer::set_deadline(int64_t interval) noexcept { 69 [ + + ]: 19 : if VUNLIKELY (interval <= 0) { 70 : 1 : deadline_.store(0, std::memory_order_release); 71 : 1 : return; 72 : : } 73 : : 74 : : // Use the same monotonic time source as set_deadline_abs() callers are 75 : : // expected to use via ElapsedTimer::get_cpu_timestamp(accuracy_). 76 : 18 : uint64_t start_time = ElapsedTimer::get_cpu_timestamp(accuracy_); 77 : 18 : uint64_t new_deadline = start_time + static_cast<uint64_t>(interval); 78 : : 79 : 18 : deadline_.store(new_deadline, std::memory_order_release); 80 : : } 81 : : 82 : 4 : void DeadlineTimer::set_deadline_abs(uint64_t abs_deadline) noexcept { 83 : 4 : deadline_.store(abs_deadline, std::memory_order_release); 84 : 4 : } 85 : : 86 : 2 : void DeadlineTimer::reset() noexcept { deadline_.store(0, std::memory_order_release); } 87 : : 88 : 30 : uint64_t DeadlineTimer::deadline() const noexcept { return deadline_.load(std::memory_order_acquire); } 89 : : 90 : 6 : int64_t DeadlineTimer::remaining_time() const noexcept { 91 : 6 : uint64_t deadline_val = deadline_.load(std::memory_order_acquire); 92 : : 93 [ - + ]: 6 : if (deadline_val == 0) { 94 : 0 : return 0; 95 : : } 96 : : 97 : 6 : uint64_t now = ElapsedTimer::get_cpu_timestamp(accuracy_); 98 : : 99 [ + + ]: 6 : if (now >= deadline_val) { 100 : 1 : return 0; 101 : : } 102 : : 103 : 5 : return static_cast<int64_t>(std::min(deadline_val - now, static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))); 104 : : } 105 : : 106 : 9 : bool DeadlineTimer::has_expired() const noexcept { 107 : 9 : uint64_t deadline_val = deadline_.load(std::memory_order_acquire); 108 : : 109 [ + + ]: 9 : if (deadline_val == 0) { 110 : 2 : return false; 111 : : } 112 : : 113 : 7 : uint64_t now = ElapsedTimer::get_cpu_timestamp(accuracy_); 114 : : 115 : 7 : return now >= deadline_val; 116 : : } 117 : : 118 : 32 : bool DeadlineTimer::is_valid() const noexcept { return deadline_.load(std::memory_order_acquire) != 0; } 119 : : 120 : 3 : DeadlineTimer::Accuracy DeadlineTimer::get_accuracy() const noexcept { return accuracy_; } 121 : : 122 : : } // namespace vlink