#include <iostream>
#include <queue>
#include <memory>
#include <vector>
#include <functional>
#include <chrono>
#include <thread>
#include <mutex>
#include <unistd.h>
#include <sys/time.h>
#define NOW (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()))
class Timer
{
private:
std::mutex lk_;
private:
struct TimerEvent {
TimerEvent(const std::chrono::microseconds &tp, const std::function<void()> &cb) {
timePoint = tp;
callback = cb;
}
std::chrono::microseconds timePoint; //us
std::function<void()> callback;
bool operator<(const TimerEvent& other) const {
return timePoint > other.timePoint;
}
bool operator>(const TimerEvent& other) const {
return timePoint < other.timePoint;
}
};
std::priority_queue<TimerEvent> events;
public:
void schedule(const int64_t delayus, const std::function<void()> &callback)
{
std::lock_guard<std::mutex> lg(lk_);
auto point = NOW + std::chrono::microseconds(delayus);
events.emplace(TimerEvent(point, callback));
}
void run() {
while (true) {
while (!events.empty()) {
auto head = events.top();
if (head.timePoint <= NOW) {
head.callback();
std::lock_guard<std::mutex> lg(lk_);
events.pop();
} else {
int64_t value = (head.timePoint - NOW).count();
if (value > 0) {
usleep(value);
} else {
head.callback();
std::lock_guard<std::mutex> lg(lk_);
events.pop();
}
}
}
sleep(0);
}
}
};
void exampleCallback() {
std::cout << "Timer event triggered!" << std::endl;
}
int main() {
Timer timer;
timer.schedule(1000000, exampleCallback);
timer.schedule(500000, exampleCallback);
timer.schedule(200000, exampleCallback);
timer.schedule(20000000, exampleCallback);
std::cout << "Microsecond timer started. Waiting for events..." << std::endl;
timer.run();
return 0;
}