#include "crtl/crtl_alloc.h"
#include "crtl/crtl_time.h"
#include "crtl/crtl_timer.h"
#include "crtl/crtl_types.h"
#include "crtl/crtl_log.h"
#include "crtl/crtl_assert.h"
#include "crtl/crtl_task.h"
#include "crtl/bits/crtl_lock_rwlock.h"
#include "crtl/easy/byteswap.h"
/* 定时器列表的读写锁 */
static crtl_lock_rw_t _unused __crtl_timers_list_rwlock = CRTL_LOCK_RWLOCK_INITIALIZER;
#define __crtl_timers_list_rdlock crtl_rwlock_rdlock(&__crtl_timers_list_rwlock, 0,0,0,0)
#define __crtl_timers_list_wrlock crtl_rwlock_wrlock(&__crtl_timers_list_rwlock, 0,0,0,0)
#define __crtl_timers_list_unlock crtl_rwlock_unlock(&__crtl_timers_list_rwlock)
/* 定时器链表的读写锁 */
static LIST_HEAD_UNUSED(__crtl_timers_list_head);
/* 定时器列表轮询线程初始化标识位 */
static volatile long _unused __crtl_timers_list_poll_task_init_flag = 0; /* 已初始化=1 */
static crtl_thread_t _unused __crtl_timer_schedule_threadID;
/* 查找一个定时器-线程不安全 */
inline static struct crtl_timer_struct * __crtl_timer_getbyid(__crtl_timer_id_t timeid)
{
/* 入参有误 */
if(unlikely((__crtl_timer_id_t)0==(__crtl_timer_id_t)timeid)) {
crtl_print_err("wrong params error. timeid=%ld\n", timeid);
crtl_assert_fp(stderr, 0);
return NULL;
}
struct crtl_timer_struct *__list_ite_timer = NULL;
struct crtl_timer_struct *_unused __list_ite_next_timer = NULL;
/* 轮询定时器链表 */
list_for_each_entry_safe(__list_ite_timer,__list_ite_next_timer, &__crtl_timers_list_head, list) {
// __crtl_dbg(">>> %lx, %lx\n", __list_ite_timer->timer_id, timeid);
if( __list_ite_timer->timer_id == timeid ) {
return __list_ite_timer;
}
if(list_is_last(&__list_ite_timer->list, &__crtl_timers_list_head)) {
// __crtl_dbg("Last NOde no OK.\n");
return NULL;
}
if( __list_ite_next_timer->timer_id == timeid ) {
return __list_ite_next_timer;
} else {
__list_ite_timer = __list_ite_next_timer;
}
}
__crtl_dbg("Not exist.\n");
return NULL;
}
/* 添加定时器到定时器链表 */
inline static int _unused __crtl_timer_add_to_list(struct crtl_timer_struct *__insert_timer)
{
struct crtl_timer_struct *__list_ite_timer = NULL;
struct crtl_timer_struct *_unused __list_ite_next_timer = NULL;
struct crtl_timer_struct *_unused __small_timer = NULL;
struct crtl_timer_struct *_unused __big_timer = NULL;
struct timespec time_interval = {0, 0};
/**
* 1.Find the location of insert timer
*
* __small_timer __big_timer
*
* 2.Insert new timer
* __small_timer __insert_timer __big_timer
*/
/* 如果为空,直接添加 */
if(list_empty(&__crtl_timers_list_head)) {
list_add_tail(&__insert_timer->list, &__crtl_timers_list_head);
/* 如果不为空,查找位置 */
} else {
/* 轮询定时器链表 */
list_for_each_entry_safe(__list_ite_timer,__list_ite_next_timer, &__crtl_timers_list_head, list) {
/* 比较两个定时器即将到时时间 */
int cmp = crtl_timespec_subabs(&__list_ite_timer->itimerspec_value.it_value,
&__insert_timer->itimerspec_value.it_value,
&time_interval);
/* 轮询的定时器大于即将插入的定时器,插入到前一个节点*/
if(cmp == CRTL_GT) {
struct crtl_timer_struct *_unused __list_prev_timer = list_prev_entry(__list_ite_timer, list);
list_add(&__insert_timer->list, &__list_prev_timer->list);
break;
}
/* 当 cmp == CRTL_EQ || cmp == CRTL_LT */
/* 如果是最后一个定时器(最后到时的定时器) */
if(list_is_last(&__list_ite_timer->list, &__crtl_timers_list_head)) {
list_add(&__insert_timer->list, &__list_ite_timer->list);
break;
/* 如果不是最后一个定时器, 同时使用 __list_ite_next_timer */
} else {
/* 轮询的定时器等于即将插入的定时器,插入*/
if(cmp == CRTL_EQ) {
list_add(&__insert_timer->list, &__list_ite_timer->list);
break;
/* 轮询的定时器小于即将插入的定时器,比较下一个节点 */
} else if(cmp == CRTL_LT) {
int cmp_next = crtl_timespec_subabs(&__list_ite_next_timer->itimerspec_value.it_value,
&__insert_timer->itimerspec_value.it_value,
&time_interval);
/* 下一个节点大于或者等于,直接插入 */
if(cmp_next == CRTL_GT || cmp_next == CRTL_EQ) {
list_add(&__insert_timer->list, &__list_ite_timer->list);
break;
/* 下一个节点小于,继续比较 */
} else if(cmp_next == CRTL_LT) {
continue;
}
}
}
}
}
return CRTL_SUCCESS;
}
static void _unused *__crtl_timer_schedule_task_fn(void*arg)
{
// __crtl_dbg("Start Schdule Timer list. thread id %ld\n", crtl_thread_self());
struct timespec currentTime = {0,0};
struct crtl_timer_struct *__list_ite_timer = NULL;
struct crtl_timer_struct *_unused __list_ite_next_timer = NULL;
struct timespec time_interval = {0, 0};
struct crtl_timer_struct *__this_timer = NULL;
while(1) {
usleep(__CRTL_TIMER_REFRESH_FREQUENCY_NanoSEC/10000);
/* 获取当前时间 */
crtl_gettimeofday_timespec(¤tTime);
__crtl_timers_list_wrlock;
/* 轮询定时器链表 */
list_for_each_entry_safe(__list_ite_timer,__list_ite_next_timer, &__crtl_timers_list_head, list) {
__this_timer = __list_ite_timer;
if(!list_is_last(&__list_ite_timer->list, &__crtl_timers_list_head)) {
__list_ite_timer = __list_ite_next_timer;
}
/* 计算当前时间与定时器超时时间差 */
crtl_timespec_subabs(&__this_timer->itimerspec_value.it_value, ¤tTime, &time_interval);
/* 如果时间差在刷新间隔内,调度定时器 */
if(__CRTL_TIMER_REFRESH_FREQUENCY_NanoSEC >= time_interval.tv_sec*1000000000+time_interval.tv_nsec) {
/* 调度 */
__this_timer->timer_sche_callback(__this_timer->timer_sche_arg);
/* 从链表中删除这个定时器 */
list_del_init(&__this_timer->list);
/* 是否为循环定时器 */
if(__this_timer->timer_loop == CRTL_TIMER_LOOP) {
/* 获取到期时间:轮询表中将被与GetTimeofDay比较 */
crtl_timespec_add(¤tTime, &__this_timer->itimerspec_value.it_interval,
&__this_timer->itimerspec_value.it_value);
__crtl_timer_add_to_list(__this_timer);
} else {
crtl_mfree1(__this_timer);
}
}else { /* 如果这个定时器没到时间,后面的定时器全部没有超时 */
break;
}
}
/* 如果删除后定时器列表为空 */
if(list_empty_careful(&__crtl_timers_list_head)) {
__crtl_dbg("Timer List is empty.>>>>>>>>>>\n");
CAS(&__crtl_timers_list_poll_task_init_flag, 1, 0);
__crtl_timers_list_unlock;
break;
}
__crtl_timers_list_unlock;
}
/* 退出线程 */
__crtl_dbg("Terminate Timer Schedule thread.\n");
crtl_thread_exit(NULL);
return NULL;
}
/* 创建定时器 */
__crtl_timer_id_t crtl_timer_create(int is_loop, void (*callback)(void *arg), void *arg, long sec, long nanosec)
{
/* 入参有误 */
if(unlikely(!callback) || (unlikely(!sec) && unlikely(!nanosec))) {
crtl_print_err("wrong params error.\n");
crtl_assert_fp(stderr, 0);
return 0;
}
/* 类型检测 */
typecheck_fn(__crtl_timer_cb_fn_t, callback);
struct crtl_timer_struct *__timer = crtl_malloc1(1, sizeof(struct crtl_timer_struct));
if(unlikely(!__timer)) {
/* 申请失败,退出 */
crtl_print_err("null pointer error.\n");
crtl_assert_fp(stderr, 0);
return 0;
}
if(is_loop) {
__timer->timer_loop = CRTL_TIMER_LOOP;
} else {
__timer->timer_loop = CRTL_TIMER_NONLOOP;
}
#define GEN_TIMERID(paddr) ((__crtl_timer_id_t)paddr)
__timer->timer_id = GEN_TIMERID(__timer);
struct timespec currentTime = {0,0};
/* 计算并保存间隔时间 */
crtl_timespec_generate(&__timer->itimerspec_value.it_interval, sec, nanosec);
/* 获取当前时间 */
crtl_gettimeofday_timespec(¤tTime);
/* 获取到期时间:轮询表中将被与GetTimeofDay比较 */
crtl_timespec_add(¤tTime, &__timer->itimerspec_value.it_interval, &__timer->itimerspec_value.it_value);
/* 置NULL */
__timer->list.next = __timer->list.prev = NULL;
__timer->timer_sche_callback = callback;
__timer->timer_sche_arg = arg;
__crtl_timers_list_wrlock;
/* 添加到定时器链表 */
__crtl_timer_add_to_list(__timer);
/* 创建链表轮询任务 */
if(CAS(&__crtl_timers_list_poll_task_init_flag, 0, 1)) {
__crtl_dbg("__crtl_timers_list_poll_task_init_flag = %ld.\n", __crtl_timers_list_poll_task_init_flag);
/* 创建线程 */
int ret = crtl_thread_create(&__crtl_timer_schedule_threadID, PTHREAD_CREATE_DETACHED, 0,
CRTL_THREAD_SCHED_PRIO_HIGHEST, SCHED_RR, PTHREAD_SCOPE_SYSTEM,
NULL, 0, 0, __crtl_timer_schedule_task_fn, arg, NULL, NULL);
// int ret = crtl_thread_normal(&__crtl_timer_schedule_threadID, __crtl_timer_schedule_task_fn, arg);
if(ret != CRTL_SUCCESS) {/* 初始化失败 */
crtl_print_err("crtl_thread_create error.\n");
crtl_assert_fp(stderr, 0);
__crtl_timers_list_unlock;
return 0;
}
__crtl_dbg("create timer schedule thread.\n");
}
__crtl_timers_list_unlock;
/* 获取返回值 */
// __crtl_dbg("Create Timer ID: %lx(%lx)(%d)\n", __timer->timer_id, GEN_TIMERID(__timer), sizeof(__crtl_timer_id_t));
// crtl_memprint(stdout, &__timer->timer_id, 8);
return GEN_TIMERID(__timer);
}
/* 获取定时器时间 */
_api int crtl_timer_gettime_interval(__crtl_timer_id_t timerid, long *sec, long *nanosec)
{
/* 首先找到这个定时器 */
struct crtl_timer_struct *__this_timer = NULL;
__crtl_timers_list_rdlock;
__this_timer = __crtl_timer_getbyid(timerid);
if(unlikely(!__this_timer)) {
crtl_print_err("null pointer error.\n");
crtl_assert_fp(stderr, 0);
__crtl_timers_list_unlock;
return CRTL_ERROR;
}
/* 计算并保存间隔时间 */
*sec = __this_timer->itimerspec_value.it_interval.tv_sec;
*nanosec = __this_timer->itimerspec_value.it_interval.tv_nsec;
__crtl_timers_list_unlock;
return CRTL_SUCCESS;
}
/* 更新定时器时间 */
_api int crtl_timer_settime_interval(__crtl_timer_id_t timerid, long sec, long nanosec)
{
/* 首先找到这个定时器 */
struct crtl_timer_struct *__this_timer = NULL;
__crtl_timers_list_wrlock;
__this_timer = __crtl_timer_getbyid(timerid);
if(unlikely(!__this_timer)) {
crtl_print_err("null pointer error.\n");
crtl_assert_fp(stderr, 0);
__crtl_timers_list_unlock;
return CRTL_ERROR;
}
/* 计算并保存间隔时间 */
crtl_timespec_generate(&__this_timer->itimerspec_value.it_interval, sec, nanosec);
__crtl_timers_list_unlock;
return CRTL_SUCCESS;
}
/* 更新定时器 */
_api int crtl_timer_nonloop(__crtl_timer_id_t timerid)
{
/* 首先找到这个定时器 */
struct crtl_timer_struct *__this_timer = NULL;
__crtl_timers_list_wrlock;
__this_timer = __crtl_timer_getbyid(timerid);
if(unlikely(!__this_timer)) {
crtl_print_err("null pointer error.\n");
crtl_assert_fp(stderr, 0);
__crtl_timers_list_unlock;
return CRTL_ERROR;
}
__this_timer->timer_loop = CRTL_TIMER_NONLOOP;
__crtl_timers_list_unlock;
return CRTL_SUCCESS;
}
/* 删除定时器 */
_api int crtl_timer_delete(__crtl_timer_id_t timerid)
{
struct crtl_timer_struct *__this_timer = NULL;
__crtl_timers_list_wrlock;
__this_timer = __crtl_timer_getbyid(timerid);
if(unlikely(!__this_timer)) {
crtl_print_err("null pointer error.\n");
crtl_assert_fp(stderr, 0);
__crtl_timers_list_unlock;
return CRTL_ERROR;
}
/* 从链表中删除这个定时器 */
list_del_init(&__this_timer->list);
__crtl_timers_list_unlock;
crtl_mfree1(__this_timer);
return CRTL_SUCCESS;
}
//
Linux环境下基于链表的定时器的C语言实现
猜你喜欢
转载自blog.csdn.net/Rong_Toa/article/details/105280853
今日推荐
周排行