1f9f848faSopenharmony_ci/*- 2f9f848faSopenharmony_ci * Copyright (c) 2017 Mark Johnston <markj@FreeBSD.org> 3f9f848faSopenharmony_ci * 4f9f848faSopenharmony_ci * Redistribution and use in source and binary forms, with or without 5f9f848faSopenharmony_ci * modification, are permitted provided that the following conditions 6f9f848faSopenharmony_ci * are met: 7f9f848faSopenharmony_ci * 1. Redistributions of source code must retain the above copyright 8f9f848faSopenharmony_ci * notice unmodified, this list of conditions, and the following 9f9f848faSopenharmony_ci * disclaimer. 10f9f848faSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 11f9f848faSopenharmony_ci * notice, this list of conditions and the following disclaimer in the 12f9f848faSopenharmony_ci * documentation and/or other materials provided with the distribution. 13f9f848faSopenharmony_ci * 14f9f848faSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15f9f848faSopenharmony_ci * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16f9f848faSopenharmony_ci * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17f9f848faSopenharmony_ci * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18f9f848faSopenharmony_ci * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19f9f848faSopenharmony_ci * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20f9f848faSopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21f9f848faSopenharmony_ci * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22f9f848faSopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23f9f848faSopenharmony_ci * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24f9f848faSopenharmony_ci */ 25f9f848faSopenharmony_ci 26f9f848faSopenharmony_ci#include "linux/hrtimer.h" 27f9f848faSopenharmony_ci 28f9f848faSopenharmony_ci#include "los_task_pri.h" 29f9f848faSopenharmony_ci#include "los_spinlock.h" 30f9f848faSopenharmony_ci#include "target_config.h" 31f9f848faSopenharmony_ci#include "los_init.h" 32f9f848faSopenharmony_ci 33f9f848faSopenharmony_ci#define US_PER_SECOND 1000000 34f9f848faSopenharmony_ci 35f9f848faSopenharmony_ci/* spinlock for hrtimer module only available on SMP mode */ 36f9f848faSopenharmony_ciLITE_OS_SEC_BSS SPIN_LOCK_INIT(g_hrtimerSpin); 37f9f848faSopenharmony_ci 38f9f848faSopenharmony_ciLITE_OS_SEC_BSS struct hrtimer_list_node *g_hrtimerList; 39f9f848faSopenharmony_ci 40f9f848faSopenharmony_ciSTATIC VOID HandlerNodeAdd(struct hrtimer_list_node *htrimer, struct handler_list_node *handlerNode) 41f9f848faSopenharmony_ci{ 42f9f848faSopenharmony_ci struct handler_list_node *tmpNode = NULL; 43f9f848faSopenharmony_ci 44f9f848faSopenharmony_ci if (htrimer == NULL) { 45f9f848faSopenharmony_ci return; 46f9f848faSopenharmony_ci } 47f9f848faSopenharmony_ci 48f9f848faSopenharmony_ci tmpNode = htrimer->HandlerHead; 49f9f848faSopenharmony_ci if (tmpNode == NULL) { 50f9f848faSopenharmony_ci htrimer->HandlerHead = handlerNode; 51f9f848faSopenharmony_ci } else { 52f9f848faSopenharmony_ci while (tmpNode->pstNext != NULL) { 53f9f848faSopenharmony_ci tmpNode = tmpNode->pstNext; 54f9f848faSopenharmony_ci } 55f9f848faSopenharmony_ci tmpNode->pstNext = handlerNode; 56f9f848faSopenharmony_ci } /* FIFO */ 57f9f848faSopenharmony_ci} 58f9f848faSopenharmony_ci 59f9f848faSopenharmony_ciSTATIC VOID HrtimerNodeAdd(struct hrtimer_list_node *htrimer, struct handler_list_node *handlerNode) 60f9f848faSopenharmony_ci{ 61f9f848faSopenharmony_ci struct hrtimer_list_node *prevNode = NULL; 62f9f848faSopenharmony_ci struct hrtimer_list_node *curNode = NULL; 63f9f848faSopenharmony_ci struct hrtimer_list_node *tmpNode = NULL; 64f9f848faSopenharmony_ci UINT32 temp; 65f9f848faSopenharmony_ci 66f9f848faSopenharmony_ci if (g_hrtimerList == NULL) { 67f9f848faSopenharmony_ci g_hrtimerList = htrimer; 68f9f848faSopenharmony_ci HrtimerClockStart(htrimer->set_time_reload); 69f9f848faSopenharmony_ci } else { 70f9f848faSopenharmony_ci temp = HrtimerClockValueGet(); 71f9f848faSopenharmony_ci g_hrtimerList->set_time_reload = temp; 72f9f848faSopenharmony_ci curNode = g_hrtimerList; 73f9f848faSopenharmony_ci while (curNode != NULL) { 74f9f848faSopenharmony_ci if (curNode->set_time_reload > htrimer->set_time_reload) { 75f9f848faSopenharmony_ci break; 76f9f848faSopenharmony_ci } 77f9f848faSopenharmony_ci if (curNode->set_time_reload == htrimer->set_time_reload) { 78f9f848faSopenharmony_ci HandlerNodeAdd(curNode, handlerNode); 79f9f848faSopenharmony_ci (VOID)LOS_MemFree(m_aucSysMem0, htrimer); 80f9f848faSopenharmony_ci return; 81f9f848faSopenharmony_ci } 82f9f848faSopenharmony_ci htrimer->set_time_reload -= curNode->set_time_reload; 83f9f848faSopenharmony_ci prevNode = curNode; 84f9f848faSopenharmony_ci curNode = curNode->pstNext; 85f9f848faSopenharmony_ci } 86f9f848faSopenharmony_ci if (curNode == g_hrtimerList) { 87f9f848faSopenharmony_ci tmpNode = g_hrtimerList; 88f9f848faSopenharmony_ci HrtimerClockStop(); 89f9f848faSopenharmony_ci HrtimerClockStart(htrimer->set_time_reload); 90f9f848faSopenharmony_ci 91f9f848faSopenharmony_ci tmpNode->set_time_reload -= htrimer->set_time_reload; 92f9f848faSopenharmony_ci htrimer->pstNext = curNode; 93f9f848faSopenharmony_ci g_hrtimerList = htrimer; 94f9f848faSopenharmony_ci } else if (curNode == NULL) { 95f9f848faSopenharmony_ci prevNode->pstNext = htrimer; 96f9f848faSopenharmony_ci } else { 97f9f848faSopenharmony_ci htrimer->pstNext = curNode; 98f9f848faSopenharmony_ci prevNode->pstNext = htrimer; 99f9f848faSopenharmony_ci curNode->set_time_reload -= htrimer->set_time_reload; 100f9f848faSopenharmony_ci } 101f9f848faSopenharmony_ci } 102f9f848faSopenharmony_ci if (handlerNode != NULL) { 103f9f848faSopenharmony_ci HandlerNodeAdd(htrimer, handlerNode); 104f9f848faSopenharmony_ci } 105f9f848faSopenharmony_ci} 106f9f848faSopenharmony_ci 107f9f848faSopenharmony_ciSTATIC VOID HrtimerHandlerRunAddNode(struct hrtimer_list_node *hrtimer, struct handler_list_node *handlerHead) 108f9f848faSopenharmony_ci{ 109f9f848faSopenharmony_ci if (handlerHead == NULL) { 110f9f848faSopenharmony_ci (VOID)LOS_MemFree(m_aucSysMem0, hrtimer); 111f9f848faSopenharmony_ci } else { 112f9f848faSopenharmony_ci hrtimer->set_time_reload = (UINT32)((hrtimer->_softexpires.tv.sec * US_PER_SECOND + 113f9f848faSopenharmony_ci hrtimer->_softexpires.tv.usec) * HRTIMER_PERUS); 114f9f848faSopenharmony_ci LOS_SpinLock(&g_hrtimerSpin); 115f9f848faSopenharmony_ci HrtimerNodeAdd(hrtimer, handlerHead); 116f9f848faSopenharmony_ci LOS_SpinUnlock(&g_hrtimerSpin); 117f9f848faSopenharmony_ci } 118f9f848faSopenharmony_ci} 119f9f848faSopenharmony_ci 120f9f848faSopenharmony_ciSTATIC VOID HrtimerHandlerRun(VOID) 121f9f848faSopenharmony_ci{ 122f9f848faSopenharmony_ci struct hrtimer_list_node *hrtimer = NULL; 123f9f848faSopenharmony_ci struct handler_list_node *curNode = NULL; 124f9f848faSopenharmony_ci struct handler_list_node *handler = NULL; 125f9f848faSopenharmony_ci struct handler_list_node *handlerTail = NULL; 126f9f848faSopenharmony_ci struct handler_list_node *handlerHead = NULL; 127f9f848faSopenharmony_ci struct hrtimer timer; 128f9f848faSopenharmony_ci enum hrtimer_restart restart; 129f9f848faSopenharmony_ci 130f9f848faSopenharmony_ci LOS_SpinLock(&g_hrtimerSpin); 131f9f848faSopenharmony_ci if (g_hrtimerList == NULL) { 132f9f848faSopenharmony_ci LOS_SpinUnlock(&g_hrtimerSpin); 133f9f848faSopenharmony_ci return; 134f9f848faSopenharmony_ci } 135f9f848faSopenharmony_ci hrtimer = g_hrtimerList; 136f9f848faSopenharmony_ci g_hrtimerList = hrtimer->pstNext; 137f9f848faSopenharmony_ci if (g_hrtimerList != NULL) { 138f9f848faSopenharmony_ci HrtimerClockStop(); 139f9f848faSopenharmony_ci HrtimerClockStart(g_hrtimerList->set_time_reload); 140f9f848faSopenharmony_ci } 141f9f848faSopenharmony_ci LOS_SpinUnlock(&g_hrtimerSpin); 142f9f848faSopenharmony_ci 143f9f848faSopenharmony_ci timer._softexpires.tv.usec = hrtimer->_softexpires.tv.usec; 144f9f848faSopenharmony_ci timer._softexpires.tv.sec = hrtimer->_softexpires.tv.sec; 145f9f848faSopenharmony_ci handler = hrtimer->HandlerHead; 146f9f848faSopenharmony_ci hrtimer->pstNext = NULL; 147f9f848faSopenharmony_ci hrtimer->HandlerHead = NULL; 148f9f848faSopenharmony_ci 149f9f848faSopenharmony_ci while ((handler != NULL) && (handler->pfnHandler != NULL)) { 150f9f848faSopenharmony_ci timer.function = handler->pfnHandler; 151f9f848faSopenharmony_ci restart = handler->pfnHandler(&timer); 152f9f848faSopenharmony_ci curNode = handler; 153f9f848faSopenharmony_ci handler = handler->pstNext; 154f9f848faSopenharmony_ci curNode->pstNext = NULL; 155f9f848faSopenharmony_ci 156f9f848faSopenharmony_ci if (restart == HRTIMER_NORESTART) { 157f9f848faSopenharmony_ci (VOID)LOS_MemFree(m_aucSysMem0, curNode); 158f9f848faSopenharmony_ci } else if (restart == HRTIMER_RESTART) { 159f9f848faSopenharmony_ci if (handlerHead != NULL) { 160f9f848faSopenharmony_ci handlerTail->pstNext = curNode; 161f9f848faSopenharmony_ci handlerTail = curNode; 162f9f848faSopenharmony_ci } else { 163f9f848faSopenharmony_ci handlerHead = curNode; 164f9f848faSopenharmony_ci handlerTail = curNode; 165f9f848faSopenharmony_ci } 166f9f848faSopenharmony_ci } else { 167f9f848faSopenharmony_ci PRINT_ERR("The return value of hrtimer function is not defined!\n"); 168f9f848faSopenharmony_ci } 169f9f848faSopenharmony_ci } 170f9f848faSopenharmony_ci 171f9f848faSopenharmony_ci HrtimerHandlerRunAddNode(hrtimer, handlerHead); 172f9f848faSopenharmony_ci} 173f9f848faSopenharmony_ci 174f9f848faSopenharmony_ciSTATIC VOID HrtimerListScan(VOID) 175f9f848faSopenharmony_ci{ 176f9f848faSopenharmony_ci HrtimerClockIrqClear(); 177f9f848faSopenharmony_ci HrtimerHandlerRun(); 178f9f848faSopenharmony_ci} 179f9f848faSopenharmony_ci 180f9f848faSopenharmony_ciSTATIC VOID GetHandlerNodePosition(const struct hrtimer *timer, struct hrtimer_list_node *hrtimerNode, 181f9f848faSopenharmony_ci struct handler_list_node **prevNode, struct handler_list_node **curNode) 182f9f848faSopenharmony_ci{ 183f9f848faSopenharmony_ci struct handler_list_node *curHandler = NULL; 184f9f848faSopenharmony_ci struct handler_list_node *prevHandler = NULL; 185f9f848faSopenharmony_ci 186f9f848faSopenharmony_ci curHandler = hrtimerNode->HandlerHead; 187f9f848faSopenharmony_ci while (curHandler != NULL) { 188f9f848faSopenharmony_ci if ((curHandler->pfnHandler == timer->function) && 189f9f848faSopenharmony_ci (curHandler->_softexpires.tv.sec == timer->_softexpires.tv.sec) && 190f9f848faSopenharmony_ci (curHandler->_softexpires.tv.usec == timer->_softexpires.tv.usec)) { 191f9f848faSopenharmony_ci *prevNode = prevHandler; 192f9f848faSopenharmony_ci *curNode = curHandler; 193f9f848faSopenharmony_ci return; 194f9f848faSopenharmony_ci } 195f9f848faSopenharmony_ci prevHandler = curHandler; 196f9f848faSopenharmony_ci curHandler = curHandler->pstNext; 197f9f848faSopenharmony_ci } 198f9f848faSopenharmony_ci} 199f9f848faSopenharmony_ci 200f9f848faSopenharmony_ciSTATIC VOID GetHrtimerNodePosition(const struct hrtimer *timer, struct hrtimer_list_node **prevNode, 201f9f848faSopenharmony_ci struct hrtimer_list_node **curNode) 202f9f848faSopenharmony_ci{ 203f9f848faSopenharmony_ci struct handler_list_node *curHandler = NULL; 204f9f848faSopenharmony_ci 205f9f848faSopenharmony_ci *curNode = g_hrtimerList; 206f9f848faSopenharmony_ci while (*curNode != NULL) { 207f9f848faSopenharmony_ci curHandler = (*curNode)->HandlerHead; 208f9f848faSopenharmony_ci while (curHandler != NULL) { 209f9f848faSopenharmony_ci if ((curHandler->pfnHandler == timer->function) && 210f9f848faSopenharmony_ci (curHandler->_softexpires.tv.sec == timer->_softexpires.tv.sec) && 211f9f848faSopenharmony_ci (curHandler->_softexpires.tv.usec == timer->_softexpires.tv.usec)) { 212f9f848faSopenharmony_ci return; 213f9f848faSopenharmony_ci } 214f9f848faSopenharmony_ci curHandler = curHandler->pstNext; 215f9f848faSopenharmony_ci } 216f9f848faSopenharmony_ci *prevNode = *curNode; 217f9f848faSopenharmony_ci *curNode = (*curNode)->pstNext; 218f9f848faSopenharmony_ci } 219f9f848faSopenharmony_ci} 220f9f848faSopenharmony_ci 221f9f848faSopenharmony_ciSTATIC struct hrtimer_list_node *HrtimerListNodeInit(union ktime time) 222f9f848faSopenharmony_ci{ 223f9f848faSopenharmony_ci struct hrtimer_list_node *hrtimer = (struct hrtimer_list_node *)LOS_MemAlloc(m_aucSysMem0, 224f9f848faSopenharmony_ci sizeof(struct hrtimer_list_node)); 225f9f848faSopenharmony_ci if (hrtimer == NULL) { 226f9f848faSopenharmony_ci return NULL; 227f9f848faSopenharmony_ci } 228f9f848faSopenharmony_ci hrtimer->_softexpires = time; 229f9f848faSopenharmony_ci hrtimer->set_time_reload = (UINT32)((time.tv.sec * US_PER_SECOND + time.tv.usec) * HRTIMER_PERUS); 230f9f848faSopenharmony_ci hrtimer->HandlerHead = NULL; 231f9f848faSopenharmony_ci hrtimer->pstNext = NULL; 232f9f848faSopenharmony_ci return hrtimer; 233f9f848faSopenharmony_ci} 234f9f848faSopenharmony_ci 235f9f848faSopenharmony_ciSTATIC UINT32 ChangeNodePosition(struct hrtimer_list_node *prevNode, struct hrtimer_list_node *curNode, 236f9f848faSopenharmony_ci struct handler_list_node *prevHandler, struct handler_list_node *curHandler, 237f9f848faSopenharmony_ci union ktime time) 238f9f848faSopenharmony_ci{ 239f9f848faSopenharmony_ci struct hrtimer_list_node *htrimer = NULL; 240f9f848faSopenharmony_ci 241f9f848faSopenharmony_ci if ((prevHandler != NULL) || (curHandler->pstNext != NULL)) { 242f9f848faSopenharmony_ci if (prevHandler == NULL) { 243f9f848faSopenharmony_ci curNode->HandlerHead = curHandler->pstNext; 244f9f848faSopenharmony_ci } else { 245f9f848faSopenharmony_ci prevHandler->pstNext = curHandler->pstNext; 246f9f848faSopenharmony_ci } 247f9f848faSopenharmony_ci 248f9f848faSopenharmony_ci curHandler->pstNext = NULL; 249f9f848faSopenharmony_ci curHandler->_softexpires = time; 250f9f848faSopenharmony_ci 251f9f848faSopenharmony_ci htrimer = HrtimerListNodeInit(time); 252f9f848faSopenharmony_ci if (htrimer == NULL) { 253f9f848faSopenharmony_ci return LOS_NOK; 254f9f848faSopenharmony_ci } 255f9f848faSopenharmony_ci 256f9f848faSopenharmony_ci HrtimerNodeAdd(htrimer, curHandler); 257f9f848faSopenharmony_ci } else { 258f9f848faSopenharmony_ci if (curNode->pstNext != NULL) { 259f9f848faSopenharmony_ci if (curNode == g_hrtimerList) { 260f9f848faSopenharmony_ci g_hrtimerList = curNode->pstNext; 261f9f848faSopenharmony_ci g_hrtimerList->set_time_reload += HrtimerClockValueGet(); 262f9f848faSopenharmony_ci HrtimerClockStop(); 263f9f848faSopenharmony_ci HrtimerClockStart(g_hrtimerList->set_time_reload); 264f9f848faSopenharmony_ci } else { 265f9f848faSopenharmony_ci prevNode->pstNext = curNode->pstNext; 266f9f848faSopenharmony_ci curNode->pstNext->set_time_reload += curNode->set_time_reload; 267f9f848faSopenharmony_ci } 268f9f848faSopenharmony_ci } else { 269f9f848faSopenharmony_ci if (curNode == g_hrtimerList) { 270f9f848faSopenharmony_ci g_hrtimerList = NULL; 271f9f848faSopenharmony_ci HrtimerClockStop(); 272f9f848faSopenharmony_ci } else { 273f9f848faSopenharmony_ci prevNode->pstNext = NULL; 274f9f848faSopenharmony_ci } 275f9f848faSopenharmony_ci } 276f9f848faSopenharmony_ci curNode->pstNext = NULL; 277f9f848faSopenharmony_ci curNode->_softexpires = time; 278f9f848faSopenharmony_ci curNode->set_time_reload = (UINT32)((time.tv.sec * US_PER_SECOND + time.tv.usec) * HRTIMER_PERUS); 279f9f848faSopenharmony_ci curNode->HandlerHead->_softexpires = time; 280f9f848faSopenharmony_ci HrtimerNodeAdd(curNode, NULL); 281f9f848faSopenharmony_ci } 282f9f848faSopenharmony_ci 283f9f848faSopenharmony_ci return LOS_OK; 284f9f848faSopenharmony_ci} 285f9f848faSopenharmony_ci 286f9f848faSopenharmony_ciSTATIC VOID CancelHandlerNode(const struct hrtimer *timer, struct hrtimer_list_node *curNode) 287f9f848faSopenharmony_ci{ 288f9f848faSopenharmony_ci struct handler_list_node *curHandler = curNode->HandlerHead; 289f9f848faSopenharmony_ci struct handler_list_node *prevHandler = curHandler; 290f9f848faSopenharmony_ci 291f9f848faSopenharmony_ci while (curHandler != NULL) { 292f9f848faSopenharmony_ci if ((curHandler->pfnHandler == timer->function) && 293f9f848faSopenharmony_ci (curHandler->_softexpires.tv.sec == timer->_softexpires.tv.sec) && 294f9f848faSopenharmony_ci (curHandler->_softexpires.tv.usec == timer->_softexpires.tv.usec)) { 295f9f848faSopenharmony_ci if (curHandler == curNode->HandlerHead) { 296f9f848faSopenharmony_ci curNode->HandlerHead = curHandler->pstNext; 297f9f848faSopenharmony_ci } else { 298f9f848faSopenharmony_ci prevHandler->pstNext = curHandler->pstNext; 299f9f848faSopenharmony_ci } 300f9f848faSopenharmony_ci curHandler->pstNext = NULL; 301f9f848faSopenharmony_ci (VOID)LOS_MemFree(m_aucSysMem0, curHandler); 302f9f848faSopenharmony_ci break; 303f9f848faSopenharmony_ci } 304f9f848faSopenharmony_ci prevHandler = curHandler; 305f9f848faSopenharmony_ci curHandler = curHandler->pstNext; 306f9f848faSopenharmony_ci } 307f9f848faSopenharmony_ci} 308f9f848faSopenharmony_ci 309f9f848faSopenharmony_ciSTATIC UINT32 CheckTime(union ktime *time) 310f9f848faSopenharmony_ci{ 311f9f848faSopenharmony_ci if ((time->tv.sec == 0) && (time->tv.usec == 0)) { 312f9f848faSopenharmony_ci return LOS_NOK; 313f9f848faSopenharmony_ci } 314f9f848faSopenharmony_ci 315f9f848faSopenharmony_ci if (time->tv.usec >= US_PER_SECOND) { 316f9f848faSopenharmony_ci time->tv.sec += time->tv.usec / US_PER_SECOND; 317f9f848faSopenharmony_ci time->tv.usec = time->tv.usec % US_PER_SECOND; 318f9f848faSopenharmony_ci } 319f9f848faSopenharmony_ci 320f9f848faSopenharmony_ci return LOS_OK; 321f9f848faSopenharmony_ci} 322f9f848faSopenharmony_ci 323f9f848faSopenharmony_civoid linux_hrtimer_init(struct hrtimer *timer, clockid_t clockID, enum hrtimer_mode mode) 324f9f848faSopenharmony_ci{ 325f9f848faSopenharmony_ci (VOID)clockID; 326f9f848faSopenharmony_ci if ((timer == NULL) || (mode != HRTIMER_MODE_REL)) { 327f9f848faSopenharmony_ci PRINT_ERR("The timer is NULL OR The mode is not HRTIMER_MODE_REL!\n"); 328f9f848faSopenharmony_ci } 329f9f848faSopenharmony_ci return; 330f9f848faSopenharmony_ci} 331f9f848faSopenharmony_ci 332f9f848faSopenharmony_ciint linux_hrtimer_create(struct hrtimer *timer, union ktime time, Handler handler) 333f9f848faSopenharmony_ci{ 334f9f848faSopenharmony_ci UINT32 ret; 335f9f848faSopenharmony_ci 336f9f848faSopenharmony_ci if ((timer == NULL) || (handler == NULL)) { 337f9f848faSopenharmony_ci return -1; 338f9f848faSopenharmony_ci } 339f9f848faSopenharmony_ci 340f9f848faSopenharmony_ci ret = CheckTime(&time); 341f9f848faSopenharmony_ci if (ret != LOS_OK) { 342f9f848faSopenharmony_ci return -1; 343f9f848faSopenharmony_ci } 344f9f848faSopenharmony_ci 345f9f848faSopenharmony_ci timer->_softexpires.tv.sec = time.tv.sec; 346f9f848faSopenharmony_ci timer->_softexpires.tv.usec = time.tv.usec; 347f9f848faSopenharmony_ci timer->function = handler; 348f9f848faSopenharmony_ci 349f9f848faSopenharmony_ci return 0; 350f9f848faSopenharmony_ci} 351f9f848faSopenharmony_ci 352f9f848faSopenharmony_ciSTATIC struct handler_list_node *HandleNodeInit(union ktime time, struct hrtimer *timer) 353f9f848faSopenharmony_ci{ 354f9f848faSopenharmony_ci struct handler_list_node *handler = NULL; 355f9f848faSopenharmony_ci handler = (struct handler_list_node *)LOS_MemAlloc(m_aucSysMem0, sizeof(struct handler_list_node)); 356f9f848faSopenharmony_ci if (handler == NULL) { 357f9f848faSopenharmony_ci return NULL; 358f9f848faSopenharmony_ci } 359f9f848faSopenharmony_ci handler->_softexpires = time; 360f9f848faSopenharmony_ci handler->pfnHandler = timer->function; 361f9f848faSopenharmony_ci handler->pstNext = NULL; 362f9f848faSopenharmony_ci return handler; 363f9f848faSopenharmony_ci} 364f9f848faSopenharmony_ci 365f9f848faSopenharmony_ciint linux_hrtimer_start(struct hrtimer *timer, union ktime time, const enum hrtimer_mode mode) 366f9f848faSopenharmony_ci{ 367f9f848faSopenharmony_ci struct hrtimer_list_node *hrtimer = NULL; 368f9f848faSopenharmony_ci struct hrtimer_list_node *prevNode = NULL; 369f9f848faSopenharmony_ci struct hrtimer_list_node *curNode = NULL; 370f9f848faSopenharmony_ci struct handler_list_node *handler = NULL; 371f9f848faSopenharmony_ci struct handler_list_node *prevHandler = NULL; 372f9f848faSopenharmony_ci struct handler_list_node *curHandler = NULL; 373f9f848faSopenharmony_ci UINT32 intSave; 374f9f848faSopenharmony_ci 375f9f848faSopenharmony_ci if ((timer == NULL) || (mode != HRTIMER_MODE_REL)) { 376f9f848faSopenharmony_ci return -1; 377f9f848faSopenharmony_ci } 378f9f848faSopenharmony_ci 379f9f848faSopenharmony_ci if (CheckTime(&time) != LOS_OK) { 380f9f848faSopenharmony_ci return -1; 381f9f848faSopenharmony_ci } 382f9f848faSopenharmony_ci 383f9f848faSopenharmony_ci LOS_SpinLockSave(&g_hrtimerSpin, &intSave); 384f9f848faSopenharmony_ci GetHrtimerNodePosition(timer, &prevNode, &curNode); 385f9f848faSopenharmony_ci if (curNode == NULL) { 386f9f848faSopenharmony_ci LOS_SpinUnlockRestore(&g_hrtimerSpin, intSave); 387f9f848faSopenharmony_ci if (timer->function == NULL) { 388f9f848faSopenharmony_ci return -1; 389f9f848faSopenharmony_ci } 390f9f848faSopenharmony_ci hrtimer = HrtimerListNodeInit(time); 391f9f848faSopenharmony_ci if (hrtimer == NULL) { 392f9f848faSopenharmony_ci return -1; 393f9f848faSopenharmony_ci } 394f9f848faSopenharmony_ci handler = HandleNodeInit(time, timer); 395f9f848faSopenharmony_ci if (handler == NULL) { 396f9f848faSopenharmony_ci (VOID)LOS_MemFree(m_aucSysMem0, hrtimer); 397f9f848faSopenharmony_ci return -1; 398f9f848faSopenharmony_ci } 399f9f848faSopenharmony_ci 400f9f848faSopenharmony_ci LOS_SpinLockSave(&g_hrtimerSpin, &intSave); 401f9f848faSopenharmony_ci HrtimerNodeAdd(hrtimer, handler); 402f9f848faSopenharmony_ci LOS_SpinUnlockRestore(&g_hrtimerSpin, intSave); 403f9f848faSopenharmony_ci return 0; 404f9f848faSopenharmony_ci } else { 405f9f848faSopenharmony_ci GetHandlerNodePosition(timer, curNode, &prevHandler, &curHandler); 406f9f848faSopenharmony_ci if (ChangeNodePosition(prevNode, curNode, prevHandler, curHandler, time) == LOS_OK) { 407f9f848faSopenharmony_ci LOS_SpinUnlockRestore(&g_hrtimerSpin, intSave); 408f9f848faSopenharmony_ci return 1; 409f9f848faSopenharmony_ci } 410f9f848faSopenharmony_ci } 411f9f848faSopenharmony_ci 412f9f848faSopenharmony_ci LOS_SpinUnlockRestore(&g_hrtimerSpin, intSave); 413f9f848faSopenharmony_ci return -1; 414f9f848faSopenharmony_ci} 415f9f848faSopenharmony_ci 416f9f848faSopenharmony_ciint linux_hrtimer_cancel(struct hrtimer *timer) 417f9f848faSopenharmony_ci{ 418f9f848faSopenharmony_ci struct hrtimer_list_node *prevNode = NULL; 419f9f848faSopenharmony_ci struct hrtimer_list_node *curNode = NULL; 420f9f848faSopenharmony_ci UINT32 intSave; 421f9f848faSopenharmony_ci 422f9f848faSopenharmony_ci if (timer == NULL) { 423f9f848faSopenharmony_ci return -1; 424f9f848faSopenharmony_ci } 425f9f848faSopenharmony_ci 426f9f848faSopenharmony_ci LOS_SpinLockSave(&g_hrtimerSpin, &intSave); 427f9f848faSopenharmony_ci curNode = g_hrtimerList; 428f9f848faSopenharmony_ci if (curNode == NULL) { 429f9f848faSopenharmony_ci LOS_SpinUnlockRestore(&g_hrtimerSpin, intSave); 430f9f848faSopenharmony_ci return 0; 431f9f848faSopenharmony_ci } 432f9f848faSopenharmony_ci 433f9f848faSopenharmony_ci GetHrtimerNodePosition(timer, &prevNode, &curNode); 434f9f848faSopenharmony_ci 435f9f848faSopenharmony_ci if (curNode == NULL) { 436f9f848faSopenharmony_ci LOS_SpinUnlockRestore(&g_hrtimerSpin, intSave); 437f9f848faSopenharmony_ci return 0; 438f9f848faSopenharmony_ci } else if (curNode == g_hrtimerList) { 439f9f848faSopenharmony_ci CancelHandlerNode(timer, curNode); 440f9f848faSopenharmony_ci 441f9f848faSopenharmony_ci if (curNode->HandlerHead == NULL) { 442f9f848faSopenharmony_ci g_hrtimerList = curNode->pstNext; 443f9f848faSopenharmony_ci if (g_hrtimerList != NULL) { 444f9f848faSopenharmony_ci g_hrtimerList->set_time_reload += HrtimerClockValueGet(); 445f9f848faSopenharmony_ci HrtimerClockStop(); 446f9f848faSopenharmony_ci HrtimerClockStart(g_hrtimerList->set_time_reload); 447f9f848faSopenharmony_ci } else { 448f9f848faSopenharmony_ci HrtimerClockStop(); 449f9f848faSopenharmony_ci } 450f9f848faSopenharmony_ci curNode->pstNext = NULL; 451f9f848faSopenharmony_ci (VOID)LOS_MemFree(m_aucSysMem0, curNode); 452f9f848faSopenharmony_ci } 453f9f848faSopenharmony_ci } else { 454f9f848faSopenharmony_ci CancelHandlerNode(timer, curNode); 455f9f848faSopenharmony_ci 456f9f848faSopenharmony_ci if (curNode->HandlerHead == NULL) { 457f9f848faSopenharmony_ci if (curNode->pstNext == NULL) { 458f9f848faSopenharmony_ci prevNode->pstNext = NULL; 459f9f848faSopenharmony_ci } else { 460f9f848faSopenharmony_ci prevNode->pstNext = curNode->pstNext; 461f9f848faSopenharmony_ci prevNode->pstNext->set_time_reload += curNode->set_time_reload; 462f9f848faSopenharmony_ci } 463f9f848faSopenharmony_ci curNode->pstNext = NULL; 464f9f848faSopenharmony_ci (VOID)LOS_MemFree(m_aucSysMem0, curNode); 465f9f848faSopenharmony_ci } 466f9f848faSopenharmony_ci } 467f9f848faSopenharmony_ci LOS_SpinUnlockRestore(&g_hrtimerSpin, intSave); 468f9f848faSopenharmony_ci return 1; 469f9f848faSopenharmony_ci} 470f9f848faSopenharmony_ci 471f9f848faSopenharmony_ciu64 linux_hrtimer_forward(struct hrtimer *timer, union ktime interval) 472f9f848faSopenharmony_ci{ 473f9f848faSopenharmony_ci struct hrtimer_list_node *prevNode = NULL; 474f9f848faSopenharmony_ci struct hrtimer_list_node *curNode = NULL; 475f9f848faSopenharmony_ci struct handler_list_node *prevHandler = NULL; 476f9f848faSopenharmony_ci struct handler_list_node *curHandler = NULL; 477f9f848faSopenharmony_ci UINT32 intSave; 478f9f848faSopenharmony_ci UINT32 ret; 479f9f848faSopenharmony_ci 480f9f848faSopenharmony_ci if (timer == NULL) { 481f9f848faSopenharmony_ci return 0; 482f9f848faSopenharmony_ci } 483f9f848faSopenharmony_ci 484f9f848faSopenharmony_ci ret = CheckTime(&interval); 485f9f848faSopenharmony_ci if (ret != LOS_OK) { 486f9f848faSopenharmony_ci return 0; 487f9f848faSopenharmony_ci } 488f9f848faSopenharmony_ci 489f9f848faSopenharmony_ci LOS_SpinLockSave(&g_hrtimerSpin, &intSave); 490f9f848faSopenharmony_ci GetHrtimerNodePosition(timer, &prevNode, &curNode); 491f9f848faSopenharmony_ci if (curNode == NULL) { 492f9f848faSopenharmony_ci LOS_SpinUnlockRestore(&g_hrtimerSpin, intSave); 493f9f848faSopenharmony_ci return 0; 494f9f848faSopenharmony_ci } 495f9f848faSopenharmony_ci GetHandlerNodePosition(timer, curNode, &prevHandler, &curHandler); 496f9f848faSopenharmony_ci timer->_softexpires = interval; 497f9f848faSopenharmony_ci ret = ChangeNodePosition(prevNode, curNode, prevHandler, curHandler, interval); 498f9f848faSopenharmony_ci LOS_SpinUnlockRestore(&g_hrtimerSpin, intSave); 499f9f848faSopenharmony_ci if (ret != LOS_OK) { 500f9f848faSopenharmony_ci return 0; 501f9f848faSopenharmony_ci } else { 502f9f848faSopenharmony_ci return (u64)((interval.tv.sec * US_PER_SECOND + interval.tv.usec) * HRTIMER_PERUS); 503f9f848faSopenharmony_ci } 504f9f848faSopenharmony_ci} 505f9f848faSopenharmony_ci 506f9f848faSopenharmony_ciint linux_hrtimer_is_queued(struct hrtimer *timer) 507f9f848faSopenharmony_ci{ 508f9f848faSopenharmony_ci struct hrtimer_list_node *curNode = NULL; 509f9f848faSopenharmony_ci struct handler_list_node *handler = NULL; 510f9f848faSopenharmony_ci INT32 ret = LOS_NOK; 511f9f848faSopenharmony_ci UINT32 intSave; 512f9f848faSopenharmony_ci 513f9f848faSopenharmony_ci if (timer == NULL) { 514f9f848faSopenharmony_ci return -1; 515f9f848faSopenharmony_ci } 516f9f848faSopenharmony_ci 517f9f848faSopenharmony_ci LOS_SpinLockSave(&g_hrtimerSpin, &intSave); 518f9f848faSopenharmony_ci curNode = g_hrtimerList; 519f9f848faSopenharmony_ci while (curNode != NULL) { 520f9f848faSopenharmony_ci handler = curNode->HandlerHead; 521f9f848faSopenharmony_ci while (handler != NULL) { 522f9f848faSopenharmony_ci if (handler->pfnHandler == timer->function) { 523f9f848faSopenharmony_ci break; 524f9f848faSopenharmony_ci } 525f9f848faSopenharmony_ci handler = handler->pstNext; 526f9f848faSopenharmony_ci } 527f9f848faSopenharmony_ci 528f9f848faSopenharmony_ci if ((handler != NULL) && (handler->pfnHandler == timer->function) && 529f9f848faSopenharmony_ci (handler->_softexpires.tv.sec == timer->_softexpires.tv.sec) && 530f9f848faSopenharmony_ci (handler->_softexpires.tv.usec == timer->_softexpires.tv.usec)) { 531f9f848faSopenharmony_ci ret = LOS_OK; 532f9f848faSopenharmony_ci break; 533f9f848faSopenharmony_ci } 534f9f848faSopenharmony_ci curNode = curNode->pstNext; 535f9f848faSopenharmony_ci } 536f9f848faSopenharmony_ci LOS_SpinUnlockRestore(&g_hrtimerSpin, intSave); 537f9f848faSopenharmony_ci 538f9f848faSopenharmony_ci return ret; 539f9f848faSopenharmony_ci} 540f9f848faSopenharmony_ci 541f9f848faSopenharmony_ciUINT32 HrtimersInit(VOID) 542f9f848faSopenharmony_ci{ 543f9f848faSopenharmony_ci UINT32 ret; 544f9f848faSopenharmony_ci 545f9f848faSopenharmony_ci g_hrtimerList = NULL; 546f9f848faSopenharmony_ci /* Initialize the timer */ 547f9f848faSopenharmony_ci HrtimerClockInit(); 548f9f848faSopenharmony_ci /* Create interrupt of the timer */ 549f9f848faSopenharmony_ci ret = LOS_HwiCreate(NUM_HAL_INTERRUPT_HRTIMER, 0, 0, HrtimerListScan, 0); 550f9f848faSopenharmony_ci if (ret != LOS_OK) { 551f9f848faSopenharmony_ci return LOS_NOK; 552f9f848faSopenharmony_ci } 553f9f848faSopenharmony_ci HalIrqUnmask(NUM_HAL_INTERRUPT_HRTIMER); 554f9f848faSopenharmony_ci 555f9f848faSopenharmony_ci return LOS_OK; 556f9f848faSopenharmony_ci} 557f9f848faSopenharmony_ci 558f9f848faSopenharmony_ciLOS_MODULE_INIT(HrtimersInit, LOS_INIT_LEVEL_PLATFROM_EARLY); 559