/***************************************************************************** * file lib/management/mtimer.c * author Yuliang * version 1.0.0 * date 22-Sep-2021 * brief This file provides all the timer related operation functions. ****************************************************************************** * Attention * *

© COPYRIGHT(c) 2021 LandPower

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of LandPower nor the names of its contributors may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************/ /* Includes ------------------------------------------------------------------*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "array.h" #include "mtimer.h" #include "cmd.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ static pthread_t mtimer_pid; static array_t *mtimer_array; static pthread_mutex_t mtimer_mutex; /* Private function prototypes -----------------------------------------------*/ extern void _mtimer_lock(void); extern void _mtimer_unlock(void); /* 485设备显示. */ CMD(mtime_show, mtime_show_cmd, "show mtime", SHOW_STR "mtime\n") { mtimer_t *entry = NULL; uint32_t i = 0; /* 遍历所有外设 */ _mtimer_lock(); vty_out(vty, "ID %-32s INR%s", "NAME", VTY_NEWLINE); for (i = 0; i < array_active(mtimer_array); i++) { entry = array_lookup(mtimer_array, i); if (NULL == entry) { continue; } vty_out(vty, "%-02d %-32s %d%s", i, entry->name, entry->interval, VTY_NEWLINE); } _mtimer_unlock(); return CMD_SUCCESS; } /* Internal functions --------------------------------------------------------*/ void _mtimer_lock(void) { pthread_mutex_lock(&mtimer_mutex); } void _mtimer_unlock(void) { pthread_mutex_unlock(&mtimer_mutex); } /* 定时器线程. */ void *_mtimer_process(void *arg) { uint32_t i = 0; uint32_t t = 0; mtimer_t *entry = NULL; while(1) { /* 最小粒度1s */ sleep(1); /* 遍历所有定时器 */ _mtimer_lock(); t = time(NULL); for (i = 0; i < array_active(mtimer_array); i++) { entry = array_lookup(mtimer_array, i); if (NULL == entry) { continue; } /* 判断时间有没有到 */ if (abs(t - entry->time) < entry->interval) { continue; } /* 调用回调函数 */ entry->handle(entry->arg); /* 删除定时器 */ array_unset(mtimer_array, i); XFREE(MTYPE_MTIMER, entry); } _mtimer_unlock(); } return NULL; } /* Interface functions -------------------------------------------------------*/ /* description: 添加定时器. param: return: (E_NONE)成功,(其他)失败 */ int32_t mtimer_add(MTIMER_CALLBACK func, void *arg, uint16_t interval, char *name) { mtimer_t *timer = NULL; _mtimer_lock(); timer = XMALLOC(MTYPE_MTIMER, sizeof(mtimer_t)); if (NULL == timer) { DBG(DBG_M_MTIMER, "Malloc error!\r\n"); _mtimer_unlock(); return E_MEM; } timer->handle = func; timer->arg = arg; snprintf(timer->name, DEV_NAME_STR_LEN, "%s", name); timer->interval = interval; timer->time = time(NULL); array_append(mtimer_array, timer, MTYPE_MTIMER); _mtimer_unlock(); return E_NONE; } /* description: 删除定时器. param: return: (E_NONE)成功,(其他)失败 */ int32_t mtimer_del(MTIMER_CALLBACK func, void *arg) { uint32_t i = 0; mtimer_t *entry = NULL; _mtimer_lock(); /* 遍历数组 */ for (i = 0; i < array_active(mtimer_array); i++) { entry = array_lookup(mtimer_array, i); if (NULL == entry) { continue; } /* 比较数据 */ if (entry->handle == func && entry->arg == arg) { /* 删除定时器 */ array_unset(mtimer_array, i); XFREE(MTYPE_MTIMER, entry); } } _mtimer_unlock(); return E_NONE; } /* description: 定时器初始化. param: return: (E_NONE)成功,(其他)失败 */ int32_t mtimer_init(void) { #if 0 struct sched_param param; pthread_attr_t attr; pthread_mutexattr_t attr_m; /* 初始化用户列表 */ mtimer_array = array_init(16, MTYPE_MTIMER); /* 递归锁 */ pthread_mutexattr_init(&attr_m); pthread_mutexattr_settype(&attr_m, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mtimer_mutex, &attr_m); /* 配置线程RR调度,优先级50 */ pthread_attr_init(&attr); param.sched_priority = 50; pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); /* 创建接收数据线程. */ if (pthread_create(&mtimer_pid, &attr, _mtimer_process, NULL) != 0) { log_err(LOG_DEFAULT, "mtimer_init can't create pthread!"); } else { thread_m_add("TIMER", mtimer_pid); } pthread_attr_destroy(&attr); #endif cmd_install_element(COMMON_NODE, &mtime_show_cmd); return E_NONE; } /************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/