From 2f9faedb8d1aa6c1d98a2af09dfa90dcb821ea58 Mon Sep 17 00:00:00 2001 From: coffee Date: Tue, 7 Apr 2026 21:07:40 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BF=AE=E6=94=B9=E6=88=90=E6=9C=80?= =?UTF-8?q?=E5=B0=8F=E5=A0=86=E5=AE=9A=E6=97=B6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HTimer.h | 55 +++--- src/HTimer.c | 497 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 380 insertions(+), 172 deletions(-) diff --git a/include/HTimer.h b/include/HTimer.h index 9a7240a..fc8c434 100644 --- a/include/HTimer.h +++ b/include/HTimer.h @@ -1,7 +1,7 @@ /** * 日期: 2025-03-08 * 作者: coffee - * 描述: 毫秒级定时器, 添加即可使用, 定时器最大数量为 HTIMER_MAX + * 描述: 毫秒级定时器, 最小堆实现 */ @@ -10,13 +10,16 @@ #include -#include "HList.h" // 无效值 #ifndef HTIMER_INVALID #define HTIMER_INVALID (-1) #endif +// 定时器长度/索引类型,方便统一修改 +typedef uint8_t HTimerLen_t; +#define HTIMER_LEN_MAX UINT8_MAX + // 检查添加定时任务超出限制后进入死循环, 方便调试 #ifdef HTIMER_CHECK_LOOP #define HTIMER_CHECK_INVALID_LOOP @@ -36,26 +39,30 @@ typedef enum typedef void (*HTimerCallType)(); typedef int16_t HTimer_t; -///< 注册的定时器信息, 定义为数组, 数量由外部控制 +///< 定时器信息 typedef struct HTimerInfo { - uint32_t flags : 1; ///< 定时器标志, eTimerFlags - uint32_t enable : 2; ///< 定时器使能 - uint32_t curr : 1; ///< 当前回调者 - uint32_t duration : 28; ///< 定时触发时长, 毫秒为计数单元 - uint32_t lastTime; ///< 上次触发时间 - HTimerCallType call; ///< 定时触发函数 + uint32_t flags : 1; ///< 定时器标志, eHTimerFlags + uint32_t curr : 1; ///< 当前回调者 + uint32_t duration : 28; ///< 定时触发时长, 毫秒为计数单元 + + volatile uint8_t state; ///< 定时器状态 (内部使用, 原子操作) + HTimerLen_t heapIndex; ///< 堆索引, HTIMER_LEN_MAX 表示不在堆中 + HTimerLen_t heapMem; ///< 堆内存, 提供给最小堆使用 + + uint32_t lastTime; ///< 上次触发时间 + HTimerCallType call; ///< 定时触发函数 + #if HTIMER_USE_USERDATA - long userData; ///< 用户数据 + long userData; ///< 用户数据 #endif - HList node; ///< 定时器节点 - uint8_t id; ///< 定时器ID } HTimerInfo; +///< 定时器注册信息 typedef struct TimeRegisterInfo { - HList workNode; ///< 工作节点 - HTimerInfo *timers; ///< 定时器信息 - uint8_t schedu : 1; ///< 需要重新调度工作队列 - uint8_t len : 7; ///< 定时器个数 + HTimerInfo *timers; ///< 定时器信息数组 + HTimerLen_t heapSize; ///< 堆当前大小 + HTimerLen_t len; ///< 定时器个数 + volatile uint8_t schedu; ///< 需要重新调度 (原子操作) } TimeRegisterInfo; ///< 初始化毫秒定时器, 需要传递获取毫秒的函数 @@ -65,16 +72,16 @@ void HTimerInitMs(uint32_t (*func)(void)); uint32_t HTimerGetMs(); /** - * @brief 注册定时器注册列表信息内存(外部提供数组) - * @param info 定时器注册信息 + * @brief 注册定时器注册列表信息内存 + * @param info 定时器注册信息数组 * @param len 定时器个数 */ -void HTimerInitRegister(TimeRegisterInfo *info, uint8_t len); +void HTimerInitRegister(TimeRegisterInfo *info, HTimerLen_t len); /** - * @brief 注册定时器信息(外部提供定时器数组) + * @brief 注册定时器信息 * @param id 定时器ID - * @param info 定时器信息, 由外部提供定时器数组 + * @param info 定时器信息数组 * @param infoLen 定时器信息长度 * @return 1成功 0失败 */ @@ -100,9 +107,9 @@ long HTimerGetUserData(HTimer_t index); long HTimerGetCurrCallUserData(uint8_t id); #else -static inline void HTimerSetUserData(HTimer_t index, long data) {} -static inline long HTimerGetUserData(HTimer_t index) { return 0; } -static inline long HTimerGetCurrCallUserData(uint8_t id) { return 0; } +static inline void HTimerSetUserData(HTimer_t index, long data) { (void)index; (void)data; } +static inline long HTimerGetUserData(HTimer_t index) { (void)index; return 0; } +static inline long HTimerGetCurrCallUserData(uint8_t id) { (void)id; return 0; } #endif #endif //__H_TIMER_H__ diff --git a/src/HTimer.c b/src/HTimer.c index be6bf25..96cac79 100644 --- a/src/HTimer.c +++ b/src/HTimer.c @@ -1,4 +1,8 @@ - +/** + * 日期: 2025-03-08 + * 作者: coffee + * 描述: 毫秒级定时器, 最小堆实现, 中断/多线程安全 + */ #include "HTimer.h" #include "HDLog.h" @@ -9,13 +13,68 @@ #define LogD(...) #endif +// ==================== 原子操作支持 ==================== +#if defined(__GNUC__) || defined(__clang__) + // STM32/GD32/ESP32 都支持 GCC 扩展 + // 使用 __atomic_* 系列函数,提供明确的内存序语义 + static inline int htimer_cas(volatile uint8_t *ptr, uint8_t oldv, uint8_t newv) { + return __atomic_compare_exchange_n(ptr, &oldv, newv, 0, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE); + } + static inline void htimer_store(volatile uint8_t *ptr, uint8_t val) { + __atomic_store_n(ptr, val, __ATOMIC_RELEASE); + } + #define HTIMER_CAS(ptr, oldv, newv) htimer_cas(ptr, oldv, newv) + #define HTIMER_STORE(ptr, val) htimer_store(ptr, val) + #define HTIMER_BARRIER() __atomic_thread_fence(__ATOMIC_SEQ_CST) + #define HTIMER_ATOMIC_OR(ptr, val) __atomic_fetch_or(ptr, val, __ATOMIC_RELEASE) + #define HTIMER_ATOMIC_XCHG(ptr, val) __atomic_exchange_n(ptr, val, __ATOMIC_ACQ_REL) + #define HTIMER_ATOMIC_LOAD(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE) + #define HTIMER_RELEASE_FENCE() __atomic_thread_fence(__ATOMIC_RELEASE) + #define HTIMER_ACQUIRE_FENCE() __atomic_thread_fence(__ATOMIC_ACQUIRE) +#elif defined(_MSC_VER) + #include + #define HTIMER_CAS(ptr, oldv, newv) (_InterlockedCompareExchange8((volatile char*)(ptr), (char)(newv), (char)(oldv)) == (char)(oldv)) + #define HTIMER_STORE(ptr, val) (*(ptr) = (val)) + #define HTIMER_BARRIER() _ReadWriteBarrier() + #define HTIMER_ATOMIC_OR(ptr, val) _InterlockedOr8((volatile char*)(ptr), (char)(val)) + #define HTIMER_ATOMIC_XCHG(ptr, val) _InterlockedExchange8((volatile char*)(ptr), (char)(val)) + #define HTIMER_ATOMIC_LOAD(ptr) (*(volatile uint8_t*)(ptr)) + #define HTIMER_RELEASE_FENCE() _ReadWriteBarrier() + #define HTIMER_ACQUIRE_FENCE() _ReadWriteBarrier() +#else +#pragma message("HTimer Not use atomic ops") + static inline int htimer_cas_simple(volatile uint8_t *ptr, uint8_t oldv, uint8_t newv) { + if (*ptr == oldv) { *ptr = newv; return 1; } + return 0; + } + static inline uint8_t htimer_xchg_simple(volatile uint8_t *ptr, uint8_t newv) { + uint8_t old = *ptr; *ptr = newv; return old; + } + #define HTIMER_CAS(ptr, oldv, newv) htimer_cas_simple(ptr, oldv, newv) + #define HTIMER_STORE(ptr, val) (*(ptr) = (val)) + #define HTIMER_BARRIER() ((void)0) + #define HTIMER_ATOMIC_OR(ptr, val) (*(ptr) |= (val)) + #define HTIMER_ATOMIC_XCHG(ptr, val) htimer_xchg_simple(ptr, val) + #define HTIMER_ATOMIC_LOAD(ptr) (*(ptr)) + #define HTIMER_RELEASE_FENCE() ((void)0) + #define HTIMER_ACQUIRE_FENCE() ((void)0) +#endif + +// 定时器内部状态 +typedef enum { + kTimerUnused = 0, ///< 未使用 + kTimerAdding, ///< 添加中 (单核中断安全: 初始化字段期间) + kTimerActive, ///< 活跃状态 + kTimerDelete ///< 待删除 +} eHTimerState; + static uint32_t (*GetCurrentMs)(void); #define CHECK_VALUE (0x0FFFFFFF) #define CREATE_INDEX(id, index) ((id << 8) | index) #define GET_ID(index) ((index >> 8) & 0xFF) #define GET_INDEX(index) (index & 0xFF) - +#define HEAP_INVALID_INDEX (HTIMER_LEN_MAX) struct __attribute__((packed)) TimerInfo { TimeRegisterInfo *info; @@ -24,54 +83,125 @@ struct __attribute__((packed)) TimerInfo { static struct TimerInfo sInfo; -static void InsertWorkNode(uint8_t id, HList *node) { - HTimerInfo *info = HLIST_ENTRY(node, HTimerInfo, node); - const uint32_t triggerTime = info->lastTime + info->duration; - HList *entry = NULL; +// ==================== 最小堆操作 ==================== +// 堆使用 timers[i].heapMem 存储堆位置 i 处的定时器索引 +// 注意:堆操作在 HTimerRun 中单线程执行,无需加锁 - HLIST_FOR_EACH(entry, &sInfo.info[id].workNode) { - HTimerInfo *nodeInfo = HLIST_ENTRY(entry, HTimerInfo, node); - if ((nodeInfo->lastTime + nodeInfo->duration) < triggerTime) { - continue; +#define HEAP_AT(reg, heapIdx) ((reg)->timers[heapIdx].heapMem) +#define HEAP_SET(reg, heapIdx, timerIdx) ((reg)->timers[heapIdx].heapMem = (timerIdx)) + +static inline HTimerInfo* getTimer(TimeRegisterInfo *reg, int heapIdx) +{ + return ®->timers[HEAP_AT(reg, heapIdx)]; +} + +static void heapSwap(TimeRegisterInfo *reg, int a, int b) +{ + HTimerLen_t ta = HEAP_AT(reg, a); + HTimerLen_t tb = HEAP_AT(reg, b); + + HEAP_SET(reg, a, tb); + HEAP_SET(reg, b, ta); + + reg->timers[ta].heapIndex = b; + reg->timers[tb].heapIndex = a; +} + +static void heapUp(TimeRegisterInfo *reg, int i) +{ + while (i > 0) { + int p = (i - 1) >> 1; + + HTimerInfo *ti = getTimer(reg, i); + HTimerInfo *tp = getTimer(reg, p); + + uint32_t iTime = ti->lastTime + ti->duration; + uint32_t pTime = tp->lastTime + tp->duration; + + int32_t diff = (int32_t)(iTime - pTime); + if (diff > 0) { + break; } - HListAddTail(node, entry); + if (diff == 0 && HEAP_AT(reg, i) > HEAP_AT(reg, p)) { + break; + } + + heapSwap(reg, i, p); + i = p; + } +} + +static void heapDown(TimeRegisterInfo *reg, int i) +{ + int size = reg->heapSize; + + while (1) { + int l = i * 2 + 1; + int r = l + 1; + int s = i; + + if (l < size) { + HTimerInfo *tl = getTimer(reg, l); + HTimerInfo *ts = getTimer(reg, s); + int32_t diff = (int32_t)((tl->lastTime + tl->duration) - (ts->lastTime + ts->duration)); + if (diff < 0 || (diff == 0 && HEAP_AT(reg, l) < HEAP_AT(reg, s))) { + s = l; + } + } + + if (r < size) { + HTimerInfo *tr = getTimer(reg, r); + HTimerInfo *ts = getTimer(reg, s); + int32_t diff = (int32_t)((tr->lastTime + tr->duration) - (ts->lastTime + ts->duration)); + if (diff < 0 || (diff == 0 && HEAP_AT(reg, r) < HEAP_AT(reg, s))) { + s = r; + } + } + + if (s == i) { + break; + } + + heapSwap(reg, i, s); + i = s; + } +} + +static void heapPush(TimeRegisterInfo *reg, HTimerLen_t timerIdx) +{ + if (reg->heapSize >= reg->len) { return; } - HListAddTail(node, entry); + HTimerLen_t i = reg->heapSize++; + HEAP_SET(reg, i, timerIdx); + reg->timers[timerIdx].heapIndex = i; + heapUp(reg, i); } -static void CallTimer(uint8_t id, HList *node) { - if (id >= sInfo.infoLen) { - LogD("error id[%d]", id); - return ; +static HTimerLen_t heapPop(TimeRegisterInfo *reg) +{ + if (reg->heapSize == 0) { + return HEAP_INVALID_INDEX; } - HTimerInfo *info = HLIST_ENTRY(node, HTimerInfo, node); - // 检查是不是已经删除的定时器 - if (info->enable == 0) { - return ; + HTimerLen_t ret = HEAP_AT(reg, 0); + reg->timers[ret].heapIndex = HEAP_INVALID_INDEX; + + if (--reg->heapSize > 0) { + HEAP_SET(reg, 0, HEAP_AT(reg, reg->heapSize)); + reg->timers[HEAP_AT(reg, 0)].heapIndex = 0; + heapDown(reg, 0); } - if (info->flags == kHTimerOnce) { - info->enable = 0; - } - - info->curr = 1; - if (info->call) { - info->call(); - } - - info->curr = 0; - info->lastTime = GetCurrentMs(); - if (info->enable) { - // 定时器还活跃, 需要重新调度回工作队列 - sInfo.info[id].schedu = 1; - } + return ret; } -static HTimer_t AddTimerData(uint8_t id, uint32_t duration, HTimerCallType call, eHTimerFlags flags) { +// ==================== 定时器操作 ==================== + +static HTimer_t AddTimerData(uint8_t id, uint32_t duration, HTimerCallType call, eHTimerFlags flags) +{ if (!GetCurrentMs) { LogD("GetCurrentMs not init"); return HTIMER_INVALID; @@ -87,198 +217,272 @@ static HTimer_t AddTimerData(uint8_t id, uint32_t duration, HTimerCallType call, return HTIMER_INVALID; } - sInfo.info[id].schedu = 1; - for (uint16_t i = 0; i < sInfo.info[id].len; ++i) { - if (sInfo.info[id].timers[i].enable) { + TimeRegisterInfo *reg = &sInfo.info[id]; + uint32_t now = GetCurrentMs(); + + // 原子地查找并占用空闲槽位 + for (HTimerLen_t i = 0; i < reg->len; ++i) { + HTimerInfo *t = ®->timers[i]; + + // 第一步:CAS 原子占用,kTimerUnused -> kTimerAdding + // 单核中断安全:即使中断发生,HTimerRun 也不会处理 kTimerAdding 状态 + if (!HTIMER_CAS(&t->state, kTimerUnused, kTimerAdding)) { continue; } - // 防中断导致数据重叠 - sInfo.info[id].timers[i].enable = 1; - if (sInfo.info[id].timers[i].enable != 1) { - continue; - } - - sInfo.info[id].timers[i].duration = duration; - sInfo.info[id].timers[i].lastTime = GetCurrentMs(); - sInfo.info[id].timers[i].call = call; - sInfo.info[id].timers[i].flags = flags; + // 成功占用槽位,设置其他字段 #if HTIMER_USE_USERDATA - sInfo.info[id].timers[i].userData = 0; + t->userData = 0; #endif - sInfo.info[id].timers[i].enable = 2; + t->duration = duration; + t->lastTime = now; + t->call = call; + t->flags = flags; + t->heapIndex = HEAP_INVALID_INDEX; + HTIMER_RELEASE_FENCE(); // 确保上述写入在状态变更前完成 + + // 第二步:kTimerAdding -> kTimerActive,标记初始化完成 + HTIMER_STORE(&t->state, kTimerActive); + + // 标记需要调度 + HTIMER_ATOMIC_OR(®->schedu, 1); + return CREATE_INDEX(id, i); } + // 槽位满,尝试紧急回收已删除的定时器 + for (HTimerLen_t i = 0; i < reg->len; ++i) { + HTimerInfo *t = ®->timers[i]; + + // 原子地将 kTimerDelete 转为 kTimerUnused + if (!HTIMER_CAS(&t->state, kTimerDelete, kTimerUnused)) { + continue; + } + + // 回收成功,再次尝试占用 + if (HTIMER_CAS(&t->state, kTimerUnused, kTimerAdding)) { +#if HTIMER_USE_USERDATA + t->userData = 0; +#endif + t->duration = duration; + t->lastTime = now; + t->call = call; + t->flags = flags; + t->heapIndex = HEAP_INVALID_INDEX; + HTIMER_RELEASE_FENCE(); + HTIMER_STORE(&t->state, kTimerActive); + HTIMER_ATOMIC_OR(®->schedu, 1); + return CREATE_INDEX(id, i); + } + } + LogD("timers full, id[%d], duration[%d], flags[%d]", id, duration, flags); return HTIMER_INVALID; } -void HTimerInitMs(uint32_t (*func)(void)) { +void HTimerInitMs(uint32_t (*func)(void)) +{ GetCurrentMs = func; } -uint32_t HTimerGetMs() { +uint32_t HTimerGetMs() +{ if (!GetCurrentMs) { return 0; } - return GetCurrentMs(); } -void HTimerInitRegister(TimeRegisterInfo *info, uint8_t len) +void HTimerInitRegister(TimeRegisterInfo *info, HTimerLen_t len) { memset(info, 0, sizeof(*info) * len); sInfo.info = info; sInfo.infoLen = len; - for (uint8_t i = 0; i < len; ++i) { - HListInit(&info[i].workNode); - } } -uint8_t HTimerRegisterTimerInfo(uint8_t id, HTimerInfo *info, uint16_t infoLen) { +uint8_t HTimerRegisterTimerInfo(uint8_t id, HTimerInfo *info, uint16_t infoLen) +{ if (id >= sInfo.infoLen) { LogD("error id[%d], max[%d]", id, sInfo.infoLen); return 0; } + if (infoLen > 255) { + LogD("infoLen too large, max 255"); + return 0; + } + memset(info, 0, sizeof(*info) * infoLen); - sInfo.info[id].timers = info; - sInfo.info[id].len = infoLen; - for (uint16_t i = 0; i < infoLen; ++i) { - info[i].id = id; - HListInit(&info[i].node); + + TimeRegisterInfo *reg = &sInfo.info[id]; + reg->timers = info; + reg->len = (HTimerLen_t)infoLen; + reg->heapSize = 0; + + for (HTimerLen_t i = 0; i < infoLen; ++i) { + info[i].heapIndex = HEAP_INVALID_INDEX; } return 1; } -void HTimerRun(uint8_t id) { - if (!GetCurrentMs) { - return ; +void HTimerRun(uint8_t id) +{ + if (!GetCurrentMs || id >= sInfo.infoLen) { + return; } - if (id >= sInfo.infoLen) { - return ; - } + TimeRegisterInfo *reg = &sInfo.info[id]; + uint32_t now = GetCurrentMs(); - do { - if (sInfo.info[id].schedu == 0) { - break; + // schedu 阶段:只有 HTimerRun 修改堆,单线程安全 + // 使用 acquire-release 语义确保看到其他线程的写入 + while (HTIMER_ATOMIC_XCHG(®->schedu, 0)) { + HTIMER_ACQUIRE_FENCE(); // 确保看到 AddTimerData 中的写入 + // 1. 清理堆中已删除的定时器 + for (HTimerLen_t i = reg->heapSize; i > 0;) { + i--; + HTimerLen_t tIdx = HEAP_AT(reg, i); + HTimerInfo *t = ®->timers[tIdx]; + if (HTIMER_ATOMIC_LOAD(&t->state) == kTimerDelete) { + HEAP_SET(reg, i, HEAP_AT(reg, --reg->heapSize)); + t->heapIndex = HEAP_INVALID_INDEX; + t->state = kTimerUnused; + HTIMER_BARRIER(); + if (i < reg->heapSize) { + heapDown(reg, i); + } + } } - // 清空工作队列, 重新添加 - HListInit(&sInfo.info[id].workNode); - for (uint16_t i = 0; i < sInfo.info[id].len; ++i) { - if (sInfo.info[id].timers[i].enable != 2) { + // 2. 清理不在堆中的已删除定时器 + 添加活跃定时器 + for (HTimerLen_t i = 0; i < reg->len; i++) { + HTimerInfo *t = ®->timers[i]; + uint8_t state = HTIMER_ATOMIC_LOAD(&t->state); + + if (state == kTimerDelete) { + t->state = kTimerUnused; continue; } - HListInit(&sInfo.info[id].timers[i].node); - InsertWorkNode(id, &sInfo.info[id].timers[i].node); + if (state == kTimerActive && t->heapIndex == HEAP_INVALID_INDEX) { + heapPush(reg, i); + } } - } while (0); - - // 检查是否有任务 - if (HListEmpty(&sInfo.info[id].workNode)) { - return ; } - HList readyNode; - HListInit(&readyNode); - // 工作队列按触发时间有序, 只需要连续取出队头的就绪任务 - while (!HListEmpty(&sInfo.info[id].workNode)) { - HTimerInfo *info = HLIST_FIRST_ENTRY(&sInfo.info[id].workNode, HTimerInfo, node); - uint32_t diff = GetCurrentMs() - info->lastTime; - uint32_t timeDuration = info->duration; - if (diff < timeDuration) { + // 执行到期的定时器 + while (reg->heapSize > 0) { + HTimerLen_t tIdx = HEAP_AT(reg, 0); + HTimerInfo *t = ®->timers[tIdx]; + + if (HTIMER_ATOMIC_LOAD(&t->state) == kTimerDelete) { + heapPop(reg); + t->state = kTimerUnused; + t->heapIndex = HEAP_INVALID_INDEX; + continue; + } + + uint32_t triggerTime = t->lastTime + t->duration; + if ((int32_t)(now - triggerTime) < 0) { break; } - HListMoveTail(&info->node, &readyNode); - } + heapPop(reg); - // 执行就绪队列 - while (!HListEmpty(&readyNode)) { - HList *node = HListPop(&readyNode); - CallTimer(id, node); + t->curr = 1; + HTIMER_BARRIER(); + if (t->call) { + t->call(); + } + t->curr = 0; + HTIMER_BARRIER(); + + if (HTIMER_ATOMIC_LOAD(&t->state) != kTimerActive) { + continue; + } + + t->lastTime = now; + + if (t->flags == kHTimerLoop) { + heapPush(reg, tIdx); + } else { + t->state = kTimerDelete; + HTIMER_ATOMIC_OR(®->schedu, 1); + } } } -HTimer_t HTimerAdd(uint8_t id, uint32_t ms, HTimerCallType call, eHTimerFlags flags) { +HTimer_t HTimerAdd(uint8_t id, uint32_t ms, HTimerCallType call, eHTimerFlags flags) +{ #ifdef HTIMER_CHECK_INVALID_LOOP HTimer_t result = AddTimerData(id, ms, call, flags); - if (result == HTIMER_INVALID) { - while (1); - } + if (result == HTIMER_INVALID) { while (1); } return result; #else return AddTimerData(id, ms, call, flags); #endif } -void HTimerRemove(HTimer_t index) { +void HTimerRemove(HTimer_t index) +{ if (index == HTIMER_INVALID) { - return ; + return; } - const uint8_t id = GET_ID(index); - index = GET_INDEX(index); + uint8_t id = GET_ID(index); + uint8_t i = GET_INDEX(index); + if (id >= sInfo.infoLen) { - LogD("error id[%d]", id); - return ; + return; } - if (index < 0 || index >= sInfo.info[id].len) { - LogD("error index[%d]", index); - return ; + TimeRegisterInfo *reg = &sInfo.info[id]; + if (i >= reg->len) { + return; } - sInfo.info[id].timers[index].enable = 0; - sInfo.info[id].schedu = 1; + HTimerInfo *t = ®->timers[i]; + + // 原子设置状态 + uint8_t oldState; + do { + oldState = t->state; + if (oldState == kTimerUnused) { + return; // 已经删除 + } + } while (!HTIMER_CAS(&t->state, oldState, kTimerDelete)); + + // 标记需要调度 + HTIMER_ATOMIC_OR(®->schedu, 1); } #if HTIMER_USE_USERDATA + void HTimerSetUserData(HTimer_t index, long data) { if (index == HTIMER_INVALID) { - return ; + return; } - - const uint8_t id = GET_ID(index); - index = GET_INDEX(index); - if (id >= sInfo.infoLen) { - LogD("error id[%d]", id); - return ; + uint8_t id = GET_ID(index); + uint8_t i = GET_INDEX(index); + if (id >= sInfo.infoLen || i >= sInfo.info[id].len) { + return; } - - if (index < 0 || index >= sInfo.info[id].len) { - LogD("error index[%d]", index); - return ; - } - - sInfo.info[id].timers[index].userData = data; + sInfo.info[id].timers[i].userData = data; } long HTimerGetUserData(HTimer_t index) { - if (index == HTIMER_INVALID) { + if (index == HTIMER_INVALID) { return 0; } - - const uint8_t id = GET_ID(index); - index = GET_INDEX(index); - if (id >= sInfo.infoLen) { - LogD("error id[%d]", id); + uint8_t id = GET_ID(index); + uint8_t i = GET_INDEX(index); + if (id >= sInfo.infoLen || i >= sInfo.info[id].len) { return 0; } - - if (index < 0 || index >= sInfo.info[id].len) { - LogD("error index[%d]", index); - return 0; - } - - return sInfo.info[id].timers[index].userData; + return sInfo.info[id].timers[i].userData; } long HTimerGetCurrCallUserData(uint8_t id) @@ -286,16 +490,13 @@ long HTimerGetCurrCallUserData(uint8_t id) if (id >= sInfo.infoLen) { return 0; } - - for (uint16_t i = 0; i < sInfo.info[id].len; ++i) { - if (sInfo.info[id].timers[i].curr == 0) { - continue; + TimeRegisterInfo *reg = &sInfo.info[id]; + for (HTimerLen_t i = 0; i < reg->len; ++i) { + if (reg->timers[i].curr) { + return reg->timers[i].userData; } - - return sInfo.info[id].timers[i].userData; } - return 0; } -#endif // HTIMER_USE_USERDATA +#endif