1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "los_swtmr_pri.h"
33 #include "los_init.h"
34 #include "los_process_pri.h"
35 #include "los_queue_pri.h"
36 #include "los_sched_pri.h"
37 #include "los_sortlink_pri.h"
38 #include "los_task_pri.h"
39 #include "los_hook.h"
40
41 #ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE
42 #if (LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0)
43 #error "swtmr maxnum cannot be zero"
44 #endif /* LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0 */
45
46 LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /* First address in Timer memory space */
47 LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Handler */
48 LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */
49
50 /* spinlock for swtmr module, only available on SMP mode */
51 LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);
52 #define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))
53 #define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))
54
SwtmrTask(VOID)55 STATIC VOID SwtmrTask(VOID)
56 {
57 SwtmrHandlerItemPtr swtmrHandlePtr = NULL;
58 SwtmrHandlerItem swtmrHandle;
59 UINT32 ret, swtmrHandlerQueue;
60
61 swtmrHandlerQueue = OsSchedSwtmrHandlerQueueGet();
62 for (;;) {
63 ret = LOS_QueueRead(swtmrHandlerQueue, &swtmrHandlePtr, sizeof(CHAR *), LOS_WAIT_FOREVER);
64 if ((ret == LOS_OK) && (swtmrHandlePtr != NULL)) {
65 swtmrHandle.handler = swtmrHandlePtr->handler;
66 swtmrHandle.arg = swtmrHandlePtr->arg;
67 (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);
68 if (swtmrHandle.handler != NULL) {
69 swtmrHandle.handler(swtmrHandle.arg);
70 }
71 }
72 }
73 }
74
SwtmrTaskCreate(UINT16 cpuid,UINT32 * swtmrTaskID)75 STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID)
76 {
77 UINT32 ret;
78 TSK_INIT_PARAM_S swtmrTask;
79
80 (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
81 swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask;
82 swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
83 swtmrTask.pcName = "Swt_Task";
84 swtmrTask.usTaskPrio = 0;
85 swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;
86 #ifdef LOSCFG_KERNEL_SMP
87 swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);
88 #endif
89 ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask);
90 if (ret == LOS_OK) {
91 OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;
92 }
93
94 return ret;
95 }
96
OsIsSwtmrTask(const LosTaskCB * taskCB)97 BOOL OsIsSwtmrTask(const LosTaskCB *taskCB)
98 {
99 if (taskCB->taskEntry == (TSK_ENTRY_FUNC)SwtmrTask) {
100 return TRUE;
101 }
102 return FALSE;
103 }
104
OsSwtmrRecycle(UINT32 processID)105 LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
106 {
107 for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {
108 if (g_swtmrCBArray[index].uwOwnerPid == processID) {
109 LOS_SwtmrDelete(index);
110 }
111 }
112 }
113
OsSwtmrInit(VOID)114 LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
115 {
116 UINT32 size;
117 UINT16 index;
118 UINT32 ret;
119 SWTMR_CTRL_S *swtmr = NULL;
120 UINT32 swtmrHandlePoolSize;
121 UINT32 cpuid = ArchCurrCpuid();
122 UINT32 swtmrTaskID, swtmrHandlerQueue;
123
124 if (cpuid == 0) {
125 size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT;
126 swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource */
127 if (swtmr == NULL) {
128 ret = LOS_ERRNO_SWTMR_NO_MEMORY;
129 goto ERROR;
130 }
131
132 (VOID)memset_s(swtmr, size, 0, size);
133 g_swtmrCBArray = swtmr;
134 LOS_ListInit(&g_swtmrFreeList);
135 for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
136 swtmr->usTimerID = index;
137 LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);
138 }
139
140 swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);
141
142 g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, swtmrHandlePoolSize); /* system resident resource */
143 if (g_swtmrHandlerPool == NULL) {
144 ret = LOS_ERRNO_SWTMR_NO_MEMORY;
145 goto ERROR;
146 }
147
148 ret = LOS_MemboxInit(g_swtmrHandlerPool, swtmrHandlePoolSize, sizeof(SwtmrHandlerItem));
149 if (ret != LOS_OK) {
150 ret = LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM;
151 goto ERROR;
152 }
153 }
154
155 ret = LOS_QueueCreate(NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &swtmrHandlerQueue, 0, sizeof(CHAR *));
156 if (ret != LOS_OK) {
157 ret = LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED;
158 goto ERROR;
159 }
160
161 ret = SwtmrTaskCreate(cpuid, &swtmrTaskID);
162 if (ret != LOS_OK) {
163 ret = LOS_ERRNO_SWTMR_TASK_CREATE_FAILED;
164 goto ERROR;
165 }
166
167 OsSchedRunQueSwtmrInit(swtmrTaskID, swtmrHandlerQueue);
168 return LOS_OK;
169
170 ERROR:
171 (VOID)LOS_MemFree(m_aucSysMem0, g_swtmrCBArray);
172 g_swtmrCBArray = NULL;
173 (VOID)LOS_MemFree(m_aucSysMem1, g_swtmrHandlerPool);
174 g_swtmrHandlerPool = NULL;
175 PRINT_ERR("OsSwtmrInit error! ret = %u\n", ret);
176 return ret;
177 }
178
179 /*
180 * Description: Start Software Timer
181 * Input : swtmr --- Need to start software timer
182 */
OsSwtmrStart(SWTMR_CTRL_S * swtmr)183 LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr)
184 {
185 UINT32 ticks;
186
187 if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ||
188 (swtmr->ucMode == LOS_SWTMR_MODE_OPP) ||
189 (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {
190 ticks = swtmr->uwExpiry;
191 } else {
192 ticks = swtmr->uwInterval;
193 }
194 swtmr->ucState = OS_SWTMR_STATUS_TICKING;
195
196 OsSchedAddSwtmr2TimeList(&swtmr->stSortList, swtmr->startTime, ticks);
197 OsSchedUpdateExpireTime();
198 return;
199 }
200
201 /*
202 * Description: Delete Software Timer
203 * Input : swtmr --- Need to delete software timer, When using, Ensure that it can't be NULL.
204 */
OsSwtmrDelete(SWTMR_CTRL_S * swtmr)205 STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr)
206 {
207 /* insert to free list */
208 LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);
209 swtmr->ucState = OS_SWTMR_STATUS_UNUSED;
210 swtmr->uwOwnerPid = 0;
211 }
212
OsSwtmrWake(SchedRunQue * rq,UINT64 startTime,SortLinkList * sortList)213 VOID OsSwtmrWake(SchedRunQue *rq, UINT64 startTime, SortLinkList *sortList)
214 {
215 SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
216
217 OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr);
218 LOS_SpinLock(&g_swtmrSpin);
219 SwtmrHandlerItemPtr swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool);
220 if (swtmrHandler != NULL) {
221 swtmrHandler->handler = swtmr->pfnHandler;
222 swtmrHandler->arg = swtmr->uwArg;
223
224 if (LOS_QueueWrite(rq->swtmrHandlerQueue, swtmrHandler, sizeof(CHAR *), LOS_NO_WAIT)) {
225 (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandler);
226 }
227 }
228
229 if (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) {
230 OsSwtmrDelete(swtmr);
231
232 if (swtmr->usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) {
233 swtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT;
234 } else {
235 swtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT;
236 }
237 } else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) {
238 swtmr->ucState = OS_SWTMR_STATUS_CREATED;
239 } else {
240 swtmr->uwOverrun++;
241 swtmr->startTime = startTime;
242 OsSwtmrStart(swtmr);
243 }
244
245 LOS_SpinUnlock(&g_swtmrSpin);
246 }
247
OsSwtmrRestart(UINT64 startTime,SortLinkList * sortList)248 VOID OsSwtmrRestart(UINT64 startTime, SortLinkList *sortList)
249 {
250 UINT32 intSave;
251
252 SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
253 SWTMR_LOCK(intSave);
254 swtmr->startTime = startTime;
255 OsSwtmrStart(swtmr);
256 SWTMR_UNLOCK(intSave);
257 }
258
OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc,UINTPTR arg)259 BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg)
260 {
261 UINT32 intSave;
262
263 SWTMR_LOCK(intSave);
264 BOOL find = OsSchedSwtmrTimeListFind(checkFunc, arg);
265 SWTMR_UNLOCK(intSave);
266 return find;
267 }
268
269 /*
270 * Description: Get next timeout
271 * Return : Count of the Timer list
272 */
OsSwtmrGetNextTimeout(VOID)273 LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID)
274 {
275 UINT64 currTime = OsGetCurrSchedTimeCycle();
276 UINT64 time = (OsSortLinkGetNextExpireTime(currTime, &OsSchedRunQue()->swtmrSortLink) / OS_CYCLE_PER_TICK);
277 if (time > OS_INVALID_VALUE) {
278 time = OS_INVALID_VALUE;
279 }
280 return (UINT32)time;
281 }
282
283 /*
284 * Description: Stop of Software Timer interface
285 * Input : swtmr --- the software timer control handler
286 */
OsSwtmrStop(SWTMR_CTRL_S * swtmr)287 LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr)
288 {
289 OsSchedDeSwtmrFromTimeList(&swtmr->stSortList);
290
291 swtmr->ucState = OS_SWTMR_STATUS_CREATED;
292 swtmr->uwOverrun = 0;
293
294 OsSchedUpdateExpireTime();
295 }
296
297 /*
298 * Description: Get next software timer expiretime
299 * Input : swtmr --- the software timer control handler
300 */
OsSwtmrTimeGet(const SWTMR_CTRL_S * swtmr)301 LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
302 {
303 UINT64 currTime = OsGetCurrSchedTimeCycle();
304 UINT64 time = (OsSortLinkGetTargetExpireTime(currTime, &swtmr->stSortList) / OS_CYCLE_PER_TICK);
305 if (time > OS_INVALID_VALUE) {
306 time = OS_INVALID_VALUE;
307 }
308 return (UINT32)time;
309 }
310
LOS_SwtmrCreate(UINT32 interval,UINT8 mode,SWTMR_PROC_FUNC handler,UINT16 * swtmrID,UINTPTR arg)311 LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
312 UINT8 mode,
313 SWTMR_PROC_FUNC handler,
314 UINT16 *swtmrID,
315 UINTPTR arg)
316 {
317 SWTMR_CTRL_S *swtmr = NULL;
318 UINT32 intSave;
319 SortLinkList *sortList = NULL;
320
321 if (interval == 0) {
322 return LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED;
323 }
324
325 if ((mode != LOS_SWTMR_MODE_ONCE) && (mode != LOS_SWTMR_MODE_PERIOD) &&
326 (mode != LOS_SWTMR_MODE_NO_SELFDELETE)) {
327 return LOS_ERRNO_SWTMR_MODE_INVALID;
328 }
329
330 if (handler == NULL) {
331 return LOS_ERRNO_SWTMR_PTR_NULL;
332 }
333
334 if (swtmrID == NULL) {
335 return LOS_ERRNO_SWTMR_RET_PTR_NULL;
336 }
337
338 SWTMR_LOCK(intSave);
339 if (LOS_ListEmpty(&g_swtmrFreeList)) {
340 SWTMR_UNLOCK(intSave);
341 return LOS_ERRNO_SWTMR_MAXSIZE;
342 }
343
344 sortList = LOS_DL_LIST_ENTRY(g_swtmrFreeList.pstNext, SortLinkList, sortLinkNode);
345 swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
346 LOS_ListDelete(LOS_DL_LIST_FIRST(&g_swtmrFreeList));
347 SWTMR_UNLOCK(intSave);
348
349 swtmr->uwOwnerPid = OsCurrProcessGet()->processID;
350 swtmr->pfnHandler = handler;
351 swtmr->ucMode = mode;
352 swtmr->uwOverrun = 0;
353 swtmr->uwInterval = interval;
354 swtmr->uwExpiry = interval;
355 swtmr->uwArg = arg;
356 swtmr->ucState = OS_SWTMR_STATUS_CREATED;
357 SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME);
358 *swtmrID = swtmr->usTimerID;
359 OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr);
360 return LOS_OK;
361 }
362
LOS_SwtmrStart(UINT16 swtmrID)363 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
364 {
365 SWTMR_CTRL_S *swtmr = NULL;
366 UINT32 intSave;
367 UINT32 ret = LOS_OK;
368 UINT16 swtmrCBID;
369
370 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
371 return LOS_ERRNO_SWTMR_ID_INVALID;
372 }
373
374 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
375 swtmr = g_swtmrCBArray + swtmrCBID;
376
377 SWTMR_LOCK(intSave);
378 if (swtmr->usTimerID != swtmrID) {
379 SWTMR_UNLOCK(intSave);
380 return LOS_ERRNO_SWTMR_ID_INVALID;
381 }
382
383 switch (swtmr->ucState) {
384 case OS_SWTMR_STATUS_UNUSED:
385 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
386 break;
387 /*
388 * If the status of swtmr is timing, it should stop the swtmr first,
389 * then start the swtmr again.
390 */
391 case OS_SWTMR_STATUS_TICKING:
392 OsSwtmrStop(swtmr);
393 /* fall-through */
394 case OS_SWTMR_STATUS_CREATED:
395 swtmr->startTime = OsGetCurrSchedTimeCycle();
396 OsSwtmrStart(swtmr);
397 break;
398 default:
399 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
400 break;
401 }
402
403 SWTMR_UNLOCK(intSave);
404 OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr);
405 return ret;
406 }
407
LOS_SwtmrStop(UINT16 swtmrID)408 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
409 {
410 SWTMR_CTRL_S *swtmr = NULL;
411 UINT32 intSave;
412 UINT32 ret = LOS_OK;
413 UINT16 swtmrCBID;
414
415 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
416 return LOS_ERRNO_SWTMR_ID_INVALID;
417 }
418
419 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
420 swtmr = g_swtmrCBArray + swtmrCBID;
421 SWTMR_LOCK(intSave);
422
423 if (swtmr->usTimerID != swtmrID) {
424 SWTMR_UNLOCK(intSave);
425 return LOS_ERRNO_SWTMR_ID_INVALID;
426 }
427
428 switch (swtmr->ucState) {
429 case OS_SWTMR_STATUS_UNUSED:
430 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
431 break;
432 case OS_SWTMR_STATUS_CREATED:
433 ret = LOS_ERRNO_SWTMR_NOT_STARTED;
434 break;
435 case OS_SWTMR_STATUS_TICKING:
436 OsSwtmrStop(swtmr);
437 break;
438 default:
439 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
440 break;
441 }
442
443 SWTMR_UNLOCK(intSave);
444 OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr);
445 return ret;
446 }
447
LOS_SwtmrTimeGet(UINT16 swtmrID,UINT32 * tick)448 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
449 {
450 SWTMR_CTRL_S *swtmr = NULL;
451 UINT32 intSave;
452 UINT32 ret = LOS_OK;
453 UINT16 swtmrCBID;
454
455 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
456 return LOS_ERRNO_SWTMR_ID_INVALID;
457 }
458
459 if (tick == NULL) {
460 return LOS_ERRNO_SWTMR_TICK_PTR_NULL;
461 }
462
463 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
464 swtmr = g_swtmrCBArray + swtmrCBID;
465 SWTMR_LOCK(intSave);
466
467 if (swtmr->usTimerID != swtmrID) {
468 SWTMR_UNLOCK(intSave);
469 return LOS_ERRNO_SWTMR_ID_INVALID;
470 }
471 switch (swtmr->ucState) {
472 case OS_SWTMR_STATUS_UNUSED:
473 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
474 break;
475 case OS_SWTMR_STATUS_CREATED:
476 ret = LOS_ERRNO_SWTMR_NOT_STARTED;
477 break;
478 case OS_SWTMR_STATUS_TICKING:
479 *tick = OsSwtmrTimeGet(swtmr);
480 break;
481 default:
482 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
483 break;
484 }
485 SWTMR_UNLOCK(intSave);
486 return ret;
487 }
488
LOS_SwtmrDelete(UINT16 swtmrID)489 LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
490 {
491 SWTMR_CTRL_S *swtmr = NULL;
492 UINT32 intSave;
493 UINT32 ret = LOS_OK;
494 UINT16 swtmrCBID;
495
496 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
497 return LOS_ERRNO_SWTMR_ID_INVALID;
498 }
499
500 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
501 swtmr = g_swtmrCBArray + swtmrCBID;
502 SWTMR_LOCK(intSave);
503
504 if (swtmr->usTimerID != swtmrID) {
505 SWTMR_UNLOCK(intSave);
506 return LOS_ERRNO_SWTMR_ID_INVALID;
507 }
508
509 switch (swtmr->ucState) {
510 case OS_SWTMR_STATUS_UNUSED:
511 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
512 break;
513 case OS_SWTMR_STATUS_TICKING:
514 OsSwtmrStop(swtmr);
515 /* fall-through */
516 case OS_SWTMR_STATUS_CREATED:
517 OsSwtmrDelete(swtmr);
518 break;
519 default:
520 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
521 break;
522 }
523
524 SWTMR_UNLOCK(intSave);
525 OsHookCall(LOS_HOOK_TYPE_SWTMR_DELETE, swtmr);
526 return ret;
527 }
528
529 #endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */
530