#ifndef __PTIMER_H__
#define __PTIMER_H__
// #define __USE_POSIX199309
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <error.h>
#include <errno.h>
#include <time.h>
#include <signal.h> 
#include <pthread.h>
#include <sys/time.h>  //struct timeval
#include <termios.h>
#include <netdb.h> // struct addrinfo

// CLOCK_REALTIME :Systemwide realtime clock.
// CLOCK_MONOTONIC:Represents monotonic time. Cannot be set.
// CLOCK_PROCESS_CPUTIME_ID :High resolution per-process timer.
// CLOCK_THREAD_CPUTIME_ID :Thread-specific timer.
// CLOCK_REALTIME_HR :High resolution version of CLOCK_REALTIME.
// CLOCK_MONOTONIC_HR :High resolution version of CLOCK_MONOTONIC.

// union sigval
// {
//     int sival_int; //integer value
//     void *sival_ptr; //pointer value
// }

// struct sigevent
// {
//     int sigev_notify; //notification type
//     int sigev_signo; //signal number
//     union sigval   sigev_value; //signal value
//     void (*sigev_notify_function)(union sigval);
//     pthread_attr_t *sigev_notify_attributes;
// }

// 通过将evp->sigev_notify设定为如下值来定制定时器到期后的行为：
// SIGEV_NONE：什么都不做，只提供通过timer_gettime和timer_getoverrun查询超时信息。
// SIGEV_SIGNAL: 当定时器到期，内核会将sigev_signo所指定的信号传送给进程。在信号处理程序中，si_value会被设定会sigev_value。
// SIGEV_THREAD: 当定时器到期，内核会(在此进程内)以sigev_notification_attributes为线程属性创建一个线程，并且让它执行sigev_notify_function，传入sigev_value作为为一个参数。
// sigev_signo的值是SIGALRM以及sigev_value的值是定时器的标识符
 
// struct timespec{
//     time_t tv_sec;
//     long tv_nsec; 
// };
// struct itimespec{
//     struct timespec it_interval;
//     struct timespec it_value;
// };

// int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
// int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue);
// int timer_gettime(timer_t timerid, struct itimerspec *value);
// int timer_getoverrun(timer_t timerid);
// int timer_delete (timer_t timerid);

int mtimer_init_pthread(timer_t timerid, void (*pthread_timer_callback)(union sigval sv), void* priv);

// int mtimer_init_sigaction(timer_t timerid, void (*sigaction_timer_callback)(int sig, siginfo_t *sinfo, void *ucontext), void* priv);

int mtimer_settime(timer_t timerid, int start_ms, int interval_ms);

int mtimer_exit(timer_t timerid);

void set_normalized_timespec(struct timespec* ts, time_t sec, int64_t nsec);
struct timespec timespec_add(struct timespec lhs, struct timespec rhs);
struct timespec timespec_sub(struct timespec lhs, struct timespec rhs);
void timespec_add_ms(struct timespec* ts, long long msec);
int timespec_compare(const struct timespec* lhs, const struct timespec* rhs);
long long timespec_to_ms(struct timespec ts);
long long timespec_to_us(struct timespec ts);

#endif//__PTIMER_H__
