13d8536b4Sopenharmony_ci/* 23d8536b4Sopenharmony_ci * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved. 33d8536b4Sopenharmony_ci * 43d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 53d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met: 63d8536b4Sopenharmony_ci * 73d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 83d8536b4Sopenharmony_ci * conditions and the following disclaimer. 93d8536b4Sopenharmony_ci * 103d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 113d8536b4Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 123d8536b4Sopenharmony_ci * provided with the distribution. 133d8536b4Sopenharmony_ci * 143d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 153d8536b4Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 163d8536b4Sopenharmony_ci * permission. 173d8536b4Sopenharmony_ci * 183d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 193d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 203d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 213d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 223d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 233d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 243d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 253d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 263d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 273d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 283d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 293d8536b4Sopenharmony_ci */ 303d8536b4Sopenharmony_ci 313d8536b4Sopenharmony_ci#include "los_signal.h" 323d8536b4Sopenharmony_ci#include "securec.h" 333d8536b4Sopenharmony_ci#include "los_config.h" 343d8536b4Sopenharmony_ci#include "los_interrupt.h" 353d8536b4Sopenharmony_ci#include "los_task.h" 363d8536b4Sopenharmony_ci#include "los_sched.h" 373d8536b4Sopenharmony_ci#include "los_debug.h" 383d8536b4Sopenharmony_ci#include "los_memory.h" 393d8536b4Sopenharmony_ci#include "los_context.h" 403d8536b4Sopenharmony_ci#include "los_arch_context.h" 413d8536b4Sopenharmony_ci 423d8536b4Sopenharmony_ciUINTPTR OsSignalTaskContextRestore(VOID) 433d8536b4Sopenharmony_ci{ 443d8536b4Sopenharmony_ci#if (LOSCFG_KERNEL_SIGNAL == 1) 453d8536b4Sopenharmony_ci LosTaskCB *task = OsCurrTaskGet(); 463d8536b4Sopenharmony_ci OsSigCB *sigCB = (OsSigCB *)task->sig; 473d8536b4Sopenharmony_ci UINTPTR sp; 483d8536b4Sopenharmony_ci 493d8536b4Sopenharmony_ci if ((sigCB == NULL) || (sigCB->sigRestoreSP == NULL)) { 503d8536b4Sopenharmony_ci return 0; 513d8536b4Sopenharmony_ci } 523d8536b4Sopenharmony_ci 533d8536b4Sopenharmony_ci sp = (UINTPTR)sigCB->sigRestoreSP; 543d8536b4Sopenharmony_ci sigCB->sigRestoreSP = NULL; 553d8536b4Sopenharmony_ci 563d8536b4Sopenharmony_ci return sp; 573d8536b4Sopenharmony_ci#else 583d8536b4Sopenharmony_ci return 0; 593d8536b4Sopenharmony_ci#endif 603d8536b4Sopenharmony_ci} 613d8536b4Sopenharmony_ci 623d8536b4Sopenharmony_ci#if (LOSCFG_KERNEL_SIGNAL == 1) 633d8536b4Sopenharmony_ciSTATIC LOS_DL_LIST g_waitSignalList; 643d8536b4Sopenharmony_ci 653d8536b4Sopenharmony_ciSTATIC VOID SignalDefaultHandler(INT32 signo) 663d8536b4Sopenharmony_ci{ 673d8536b4Sopenharmony_ci PRINTK("signal default handler, signo = %d\n", signo); 683d8536b4Sopenharmony_ci} 693d8536b4Sopenharmony_ci 703d8536b4Sopenharmony_ciSTATIC UINT32 AddSigInfoToList(OsSigCB *sigCB, siginfo_t *info) 713d8536b4Sopenharmony_ci{ 723d8536b4Sopenharmony_ci OsSigInfoNode *tmpInfo = NULL; 733d8536b4Sopenharmony_ci BOOL findFlag = FALSE; 743d8536b4Sopenharmony_ci 753d8536b4Sopenharmony_ci LOS_DL_LIST_FOR_EACH_ENTRY(tmpInfo, &sigCB->sigInfoList, OsSigInfoNode, node) { 763d8536b4Sopenharmony_ci if (tmpInfo->info.si_signo == info->si_signo) { 773d8536b4Sopenharmony_ci findFlag = TRUE; 783d8536b4Sopenharmony_ci break; 793d8536b4Sopenharmony_ci } 803d8536b4Sopenharmony_ci } 813d8536b4Sopenharmony_ci 823d8536b4Sopenharmony_ci if (findFlag == FALSE) { 833d8536b4Sopenharmony_ci tmpInfo = (OsSigInfoNode *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(OsSigInfoNode)); 843d8536b4Sopenharmony_ci if (tmpInfo == NULL) { 853d8536b4Sopenharmony_ci return LOS_NOK; 863d8536b4Sopenharmony_ci } 873d8536b4Sopenharmony_ci LOS_ListAdd(&sigCB->sigInfoList, &tmpInfo->node); 883d8536b4Sopenharmony_ci } 893d8536b4Sopenharmony_ci (VOID)memcpy_s(&tmpInfo->info, sizeof(siginfo_t), info, sizeof(siginfo_t)); 903d8536b4Sopenharmony_ci return LOS_OK; 913d8536b4Sopenharmony_ci} 923d8536b4Sopenharmony_ci 933d8536b4Sopenharmony_ciSTATIC VOID DeleteSigInfoFromList(OsSigCB *sigCB, INT32 sigNo) 943d8536b4Sopenharmony_ci{ 953d8536b4Sopenharmony_ci OsSigInfoNode *tmpInfo = NULL; 963d8536b4Sopenharmony_ci BOOL findFlag = FALSE; 973d8536b4Sopenharmony_ci 983d8536b4Sopenharmony_ci LOS_DL_LIST_FOR_EACH_ENTRY(tmpInfo, &sigCB->sigInfoList, OsSigInfoNode, node) { 993d8536b4Sopenharmony_ci if (tmpInfo->info.si_signo == sigNo) { 1003d8536b4Sopenharmony_ci LOS_ListDelete(&tmpInfo->node); 1013d8536b4Sopenharmony_ci findFlag = TRUE; 1023d8536b4Sopenharmony_ci break; 1033d8536b4Sopenharmony_ci } 1043d8536b4Sopenharmony_ci } 1053d8536b4Sopenharmony_ci 1063d8536b4Sopenharmony_ci if (findFlag == TRUE) { 1073d8536b4Sopenharmony_ci (VOID)memcpy_s(&sigCB->sigInfo, sizeof(siginfo_t), &tmpInfo->info, sizeof(siginfo_t)); 1083d8536b4Sopenharmony_ci (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, tmpInfo); 1093d8536b4Sopenharmony_ci } 1103d8536b4Sopenharmony_ci} 1113d8536b4Sopenharmony_ci 1123d8536b4Sopenharmony_ciSTATIC VOID SignalHandle(LosTaskCB *task, BOOL cleanStatus) 1133d8536b4Sopenharmony_ci{ 1143d8536b4Sopenharmony_ci UINT32 intSave; 1153d8536b4Sopenharmony_ci OsSigCB *sigCB = NULL; 1163d8536b4Sopenharmony_ci 1173d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 1183d8536b4Sopenharmony_ci sigCB = task->sig; 1193d8536b4Sopenharmony_ci if (sigCB == NULL) { 1203d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1213d8536b4Sopenharmony_ci return; 1223d8536b4Sopenharmony_ci } 1233d8536b4Sopenharmony_ci 1243d8536b4Sopenharmony_ci while (sigCB->sigPendFlag & sigCB->sigSetFlag) { 1253d8536b4Sopenharmony_ci UINT32 sigFlag = sigCB->sigPendFlag & sigCB->sigSetFlag; 1263d8536b4Sopenharmony_ci INT32 sigNo = LOS_SIGNAL_SUPPORT_MAX - CLZ(sigFlag) + 1; 1273d8536b4Sopenharmony_ci DeleteSigInfoFromList(sigCB, sigNo); 1283d8536b4Sopenharmony_ci 1293d8536b4Sopenharmony_ci SIG_HANDLER handler = sigCB->sigHandlers[sigNo - 1]; 1303d8536b4Sopenharmony_ci sigCB->sigPendFlag &= ~LOS_SIGNAL_MASK(sigNo); 1313d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1323d8536b4Sopenharmony_ci 1333d8536b4Sopenharmony_ci if (handler != NULL) { 1343d8536b4Sopenharmony_ci handler(sigNo); 1353d8536b4Sopenharmony_ci } 1363d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 1373d8536b4Sopenharmony_ci 1383d8536b4Sopenharmony_ci if (cleanStatus == TRUE) { 1393d8536b4Sopenharmony_ci task->taskStatus &= ~OS_TASK_FLAG_SIGNAL; 1403d8536b4Sopenharmony_ci } 1413d8536b4Sopenharmony_ci } 1423d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1433d8536b4Sopenharmony_ci} 1443d8536b4Sopenharmony_ci 1453d8536b4Sopenharmony_ciSTATIC VOID SignalEntry(INT32 sigNo) 1463d8536b4Sopenharmony_ci{ 1473d8536b4Sopenharmony_ci (void)sigNo; 1483d8536b4Sopenharmony_ci LosTaskCB *task = OsCurrTaskGet(); 1493d8536b4Sopenharmony_ci OsSigCB *sigCB = (OsSigCB *)task->sig; 1503d8536b4Sopenharmony_ci 1513d8536b4Sopenharmony_ci SignalHandle(task, FALSE); 1523d8536b4Sopenharmony_ci 1533d8536b4Sopenharmony_ci task->stackPointer = sigCB->sigSaveSP; 1543d8536b4Sopenharmony_ci sigCB->sigSaveSP = NULL; 1553d8536b4Sopenharmony_ci sigCB->sigRestoreSP = task->stackPointer; 1563d8536b4Sopenharmony_ci task->taskStatus &= ~OS_TASK_FLAG_SIGNAL; 1573d8536b4Sopenharmony_ci 1583d8536b4Sopenharmony_ci LOS_Schedule(); 1593d8536b4Sopenharmony_ci} 1603d8536b4Sopenharmony_ci 1613d8536b4Sopenharmony_ciSTATIC VOID SignalSend(LosTaskCB *task, INT32 sigNo) 1623d8536b4Sopenharmony_ci{ 1633d8536b4Sopenharmony_ci UINT32 intSave; 1643d8536b4Sopenharmony_ci OsSigCB *sigCB = NULL; 1653d8536b4Sopenharmony_ci sigset_t mask = LOS_SIGNAL_MASK(sigNo); 1663d8536b4Sopenharmony_ci 1673d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 1683d8536b4Sopenharmony_ci sigCB = task->sig; 1693d8536b4Sopenharmony_ci if (sigCB == NULL) { 1703d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1713d8536b4Sopenharmony_ci return; 1723d8536b4Sopenharmony_ci } 1733d8536b4Sopenharmony_ci 1743d8536b4Sopenharmony_ci if (!(sigCB->sigPendFlag & mask)) { 1753d8536b4Sopenharmony_ci sigCB->sigPendFlag |= mask; 1763d8536b4Sopenharmony_ci } 1773d8536b4Sopenharmony_ci 1783d8536b4Sopenharmony_ci if (task == OsCurrTaskGet()) { 1793d8536b4Sopenharmony_ci task->taskStatus |= OS_TASK_FLAG_SIGNAL; 1803d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1813d8536b4Sopenharmony_ci 1823d8536b4Sopenharmony_ci if (!OS_INT_ACTIVE) { 1833d8536b4Sopenharmony_ci SignalHandle(task, TRUE); 1843d8536b4Sopenharmony_ci } 1853d8536b4Sopenharmony_ci } else { 1863d8536b4Sopenharmony_ci if (sigCB->sigStatus & OS_SIGNAL_STATUS_WAIT) { 1873d8536b4Sopenharmony_ci if (sigCB->sigWaitFlag & LOS_SIGNAL_MASK(sigNo)) { 1883d8536b4Sopenharmony_ci DeleteSigInfoFromList(sigCB, sigNo); 1893d8536b4Sopenharmony_ci OsSchedTaskWake(task); 1903d8536b4Sopenharmony_ci task->taskStatus |= OS_TASK_FLAG_SIGNAL; 1913d8536b4Sopenharmony_ci } 1923d8536b4Sopenharmony_ci } else if (!(task->taskStatus & OS_TASK_FLAG_SIGNAL)) { 1933d8536b4Sopenharmony_ci task->taskStatus |= OS_TASK_FLAG_SIGNAL; 1943d8536b4Sopenharmony_ci sigCB->sigSaveSP = task->stackPointer; 1953d8536b4Sopenharmony_ci sigCB->sigRestoreSP = NULL; 1963d8536b4Sopenharmony_ci task->stackPointer = ArchSignalContextInit(task->stackPointer, (VOID *)task->topOfStack, 1973d8536b4Sopenharmony_ci (UINTPTR)SignalEntry, sigNo); 1983d8536b4Sopenharmony_ci } 1993d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2003d8536b4Sopenharmony_ci LOS_Schedule(); 2013d8536b4Sopenharmony_ci } 2023d8536b4Sopenharmony_ci} 2033d8536b4Sopenharmony_ci 2043d8536b4Sopenharmony_ciSTATIC OsSigCB *SignalCBInit(LosTaskCB *task) 2053d8536b4Sopenharmony_ci{ 2063d8536b4Sopenharmony_ci OsSigCB *sigCB = NULL; 2073d8536b4Sopenharmony_ci UINT32 i; 2083d8536b4Sopenharmony_ci 2093d8536b4Sopenharmony_ci if (task->sig == NULL) { 2103d8536b4Sopenharmony_ci sigCB = (OsSigCB *)LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(OsSigCB)); 2113d8536b4Sopenharmony_ci if (sigCB == NULL) { 2123d8536b4Sopenharmony_ci return NULL; 2133d8536b4Sopenharmony_ci } 2143d8536b4Sopenharmony_ci (VOID)memset_s(sigCB, sizeof(OsSigCB), 0, sizeof(OsSigCB)); 2153d8536b4Sopenharmony_ci LOS_ListInit(&sigCB->sigInfoList); 2163d8536b4Sopenharmony_ci 2173d8536b4Sopenharmony_ci for (i = 0; i <= LOS_SIGNAL_SUPPORT_MAX; i++) { 2183d8536b4Sopenharmony_ci sigCB->sigHandlers[i] = SignalDefaultHandler; 2193d8536b4Sopenharmony_ci } 2203d8536b4Sopenharmony_ci 2213d8536b4Sopenharmony_ci task->sig = (VOID *)sigCB; 2223d8536b4Sopenharmony_ci } else { 2233d8536b4Sopenharmony_ci sigCB = (OsSigCB *)task->sig; 2243d8536b4Sopenharmony_ci } 2253d8536b4Sopenharmony_ci 2263d8536b4Sopenharmony_ci return sigCB; 2273d8536b4Sopenharmony_ci} 2283d8536b4Sopenharmony_ci 2293d8536b4Sopenharmony_ciSIG_HANDLER LOS_SignalSet(INT32 sigNo, SIG_HANDLER handler) 2303d8536b4Sopenharmony_ci{ 2313d8536b4Sopenharmony_ci UINT32 intSave; 2323d8536b4Sopenharmony_ci SIG_HANDLER old = NULL; 2333d8536b4Sopenharmony_ci LosTaskCB *task = OsCurrTaskGet(); 2343d8536b4Sopenharmony_ci OsSigCB *sigCB = NULL; 2353d8536b4Sopenharmony_ci 2363d8536b4Sopenharmony_ci if (task == NULL) { 2373d8536b4Sopenharmony_ci return SIG_ERR; 2383d8536b4Sopenharmony_ci } 2393d8536b4Sopenharmony_ci 2403d8536b4Sopenharmony_ci if (!OS_SIGNAL_VALID(sigNo)) { 2413d8536b4Sopenharmony_ci return SIG_ERR; 2423d8536b4Sopenharmony_ci } 2433d8536b4Sopenharmony_ci 2443d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 2453d8536b4Sopenharmony_ci sigCB = SignalCBInit(task); 2463d8536b4Sopenharmony_ci if (sigCB == NULL) { 2473d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2483d8536b4Sopenharmony_ci return SIG_ERR; 2493d8536b4Sopenharmony_ci } 2503d8536b4Sopenharmony_ci 2513d8536b4Sopenharmony_ci old = sigCB->sigHandlers[sigNo - 1]; /* signal number from 1, but index from 0 */ 2523d8536b4Sopenharmony_ci if (handler == SIG_IGN) { 2533d8536b4Sopenharmony_ci sigCB->sigHandlers[sigNo - 1] = NULL; 2543d8536b4Sopenharmony_ci sigCB->sigSetFlag &= ~LOS_SIGNAL_MASK(sigNo); 2553d8536b4Sopenharmony_ci } else if (handler == SIG_DFL) { 2563d8536b4Sopenharmony_ci sigCB->sigHandlers[sigNo - 1] = SignalDefaultHandler; 2573d8536b4Sopenharmony_ci sigCB->sigSetFlag |= LOS_SIGNAL_MASK(sigNo); 2583d8536b4Sopenharmony_ci } else { 2593d8536b4Sopenharmony_ci sigCB->sigHandlers[sigNo - 1] = handler; 2603d8536b4Sopenharmony_ci sigCB->sigSetFlag |= LOS_SIGNAL_MASK(sigNo); 2613d8536b4Sopenharmony_ci } 2623d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2633d8536b4Sopenharmony_ci 2643d8536b4Sopenharmony_ci return old; 2653d8536b4Sopenharmony_ci} 2663d8536b4Sopenharmony_ci 2673d8536b4Sopenharmony_ciUINT32 LOS_SignalMask(INT32 how, const sigset_t *set, sigset_t *oldSet) 2683d8536b4Sopenharmony_ci{ 2693d8536b4Sopenharmony_ci UINT32 intSave; 2703d8536b4Sopenharmony_ci LosTaskCB *task = OsCurrTaskGet(); 2713d8536b4Sopenharmony_ci OsSigCB *sigCB = NULL; 2723d8536b4Sopenharmony_ci 2733d8536b4Sopenharmony_ci if (task == NULL) { 2743d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_CAN_NOT_CALL; 2753d8536b4Sopenharmony_ci } 2763d8536b4Sopenharmony_ci 2773d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 2783d8536b4Sopenharmony_ci sigCB = SignalCBInit(task); 2793d8536b4Sopenharmony_ci if (sigCB == NULL) { 2803d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2813d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_NO_MEMORY; 2823d8536b4Sopenharmony_ci } 2833d8536b4Sopenharmony_ci 2843d8536b4Sopenharmony_ci if (oldSet != NULL) { 2853d8536b4Sopenharmony_ci *oldSet = sigCB->sigSetFlag; 2863d8536b4Sopenharmony_ci } 2873d8536b4Sopenharmony_ci 2883d8536b4Sopenharmony_ci if (set == NULL) { 2893d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2903d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_INVALID; 2913d8536b4Sopenharmony_ci } 2923d8536b4Sopenharmony_ci 2933d8536b4Sopenharmony_ci switch (how) { 2943d8536b4Sopenharmony_ci case SIG_BLOCK: 2953d8536b4Sopenharmony_ci sigCB->sigSetFlag &= ~*set; 2963d8536b4Sopenharmony_ci break; 2973d8536b4Sopenharmony_ci case SIG_SETMASK: 2983d8536b4Sopenharmony_ci sigCB->sigSetFlag = *set; 2993d8536b4Sopenharmony_ci break; 3003d8536b4Sopenharmony_ci case SIG_UNBLOCK: 3013d8536b4Sopenharmony_ci sigCB->sigSetFlag |= *set; 3023d8536b4Sopenharmony_ci break; 3033d8536b4Sopenharmony_ci default: 3043d8536b4Sopenharmony_ci PRINT_ERR("The error parameter how = %d\n", how); 3053d8536b4Sopenharmony_ci break; 3063d8536b4Sopenharmony_ci } 3073d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 3083d8536b4Sopenharmony_ci 3093d8536b4Sopenharmony_ci return LOS_OK; 3103d8536b4Sopenharmony_ci} 3113d8536b4Sopenharmony_ci 3123d8536b4Sopenharmony_ciSTATIC INLINE UINT32 SignalTimedWait(LosTaskCB *task, const sigset_t *set, UINT32 timeout, UINT32 *intSave) 3133d8536b4Sopenharmony_ci{ 3143d8536b4Sopenharmony_ci OsSigCB *sigCB = (OsSigCB *)task->sig; 3153d8536b4Sopenharmony_ci INT32 sigNo; 3163d8536b4Sopenharmony_ci 3173d8536b4Sopenharmony_ci if (timeout == 0) { 3183d8536b4Sopenharmony_ci LOS_IntRestore(*intSave); 3193d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_INVALID; 3203d8536b4Sopenharmony_ci } 3213d8536b4Sopenharmony_ci 3223d8536b4Sopenharmony_ci if (OS_INT_ACTIVE) { 3233d8536b4Sopenharmony_ci LOS_IntRestore(*intSave); 3243d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_PEND_INTERR; 3253d8536b4Sopenharmony_ci } 3263d8536b4Sopenharmony_ci 3273d8536b4Sopenharmony_ci sigCB->sigWaitFlag |= *set; 3283d8536b4Sopenharmony_ci sigCB->sigStatus |= OS_SIGNAL_STATUS_WAIT; 3293d8536b4Sopenharmony_ci 3303d8536b4Sopenharmony_ci OsSchedTaskWait(&g_waitSignalList, timeout); 3313d8536b4Sopenharmony_ci LOS_IntRestore(*intSave); 3323d8536b4Sopenharmony_ci LOS_Schedule(); 3333d8536b4Sopenharmony_ci 3343d8536b4Sopenharmony_ci *intSave = LOS_IntLock(); 3353d8536b4Sopenharmony_ci task->taskStatus &= ~OS_TASK_FLAG_SIGNAL; 3363d8536b4Sopenharmony_ci sigCB->sigStatus &= ~OS_SIGNAL_STATUS_WAIT; 3373d8536b4Sopenharmony_ci sigCB->sigWaitFlag = 0; 3383d8536b4Sopenharmony_ci if (task->taskStatus & OS_TASK_STATUS_TIMEOUT) { 3393d8536b4Sopenharmony_ci task->taskStatus &= ~OS_TASK_STATUS_TIMEOUT; 3403d8536b4Sopenharmony_ci LOS_IntRestore(*intSave); 3413d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_TIMEOUT; 3423d8536b4Sopenharmony_ci } 3433d8536b4Sopenharmony_ci sigNo = sigCB->sigInfo.si_signo; 3443d8536b4Sopenharmony_ci sigCB->sigPendFlag &= ~LOS_SIGNAL_MASK(sigNo); 3453d8536b4Sopenharmony_ci return sigNo; 3463d8536b4Sopenharmony_ci} 3473d8536b4Sopenharmony_ci 3483d8536b4Sopenharmony_ciUINT32 LOS_SignalWait(const sigset_t *set, siginfo_t *info, UINT32 timeout) 3493d8536b4Sopenharmony_ci{ 3503d8536b4Sopenharmony_ci UINT32 intSave; 3513d8536b4Sopenharmony_ci LosTaskCB *task = OsCurrTaskGet(); 3523d8536b4Sopenharmony_ci OsSigCB *sigCB = NULL; 3533d8536b4Sopenharmony_ci sigset_t sigFlag; 3543d8536b4Sopenharmony_ci INT32 sigNo; 3553d8536b4Sopenharmony_ci 3563d8536b4Sopenharmony_ci if ((set == NULL) || (*set == 0)) { 3573d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_INVALID; 3583d8536b4Sopenharmony_ci } 3593d8536b4Sopenharmony_ci 3603d8536b4Sopenharmony_ci if (task == NULL) { 3613d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_CAN_NOT_CALL; 3623d8536b4Sopenharmony_ci } 3633d8536b4Sopenharmony_ci 3643d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 3653d8536b4Sopenharmony_ci sigCB = SignalCBInit(task); 3663d8536b4Sopenharmony_ci if (sigCB == NULL) { 3673d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 3683d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_NO_MEMORY; 3693d8536b4Sopenharmony_ci } 3703d8536b4Sopenharmony_ci 3713d8536b4Sopenharmony_ci sigFlag = sigCB->sigPendFlag & *set; 3723d8536b4Sopenharmony_ci if (sigFlag) { 3733d8536b4Sopenharmony_ci sigCB->sigPendFlag ^= sigFlag; 3743d8536b4Sopenharmony_ci sigNo = LOS_SIGNAL_SUPPORT_MAX - CLZ(sigFlag) + 1; 3753d8536b4Sopenharmony_ci DeleteSigInfoFromList(sigCB, sigNo); 3763d8536b4Sopenharmony_ci } else { 3773d8536b4Sopenharmony_ci sigNo = SignalTimedWait(task, set, timeout, &intSave); 3783d8536b4Sopenharmony_ci if (sigNo > LOS_SIGNAL_SUPPORT_MAX) { 3793d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 3803d8536b4Sopenharmony_ci return sigNo; 3813d8536b4Sopenharmony_ci } 3823d8536b4Sopenharmony_ci } 3833d8536b4Sopenharmony_ci 3843d8536b4Sopenharmony_ci if (info != NULL) { 3853d8536b4Sopenharmony_ci (VOID)memcpy_s(info, sizeof(siginfo_t), &sigCB->sigInfo, sizeof(siginfo_t)); 3863d8536b4Sopenharmony_ci } 3873d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 3883d8536b4Sopenharmony_ci 3893d8536b4Sopenharmony_ci return sigNo; 3903d8536b4Sopenharmony_ci} 3913d8536b4Sopenharmony_ci 3923d8536b4Sopenharmony_ciUINT32 LOS_SignalSend(UINT32 taskID, INT32 sigNo) 3933d8536b4Sopenharmony_ci{ 3943d8536b4Sopenharmony_ci siginfo_t info; 3953d8536b4Sopenharmony_ci UINT32 intSave; 3963d8536b4Sopenharmony_ci OsSigCB *sigCB = NULL; 3973d8536b4Sopenharmony_ci LosTaskCB *task = NULL; 3983d8536b4Sopenharmony_ci 3993d8536b4Sopenharmony_ci if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) { 4003d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_INVALID; 4013d8536b4Sopenharmony_ci } 4023d8536b4Sopenharmony_ci 4033d8536b4Sopenharmony_ci if (!OS_SIGNAL_VALID(sigNo)) { 4043d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_INVALID; 4053d8536b4Sopenharmony_ci } 4063d8536b4Sopenharmony_ci 4073d8536b4Sopenharmony_ci info.si_signo = sigNo; 4083d8536b4Sopenharmony_ci info.si_code = SI_USER; 4093d8536b4Sopenharmony_ci info.si_value.sival_ptr = NULL; 4103d8536b4Sopenharmony_ci 4113d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 4123d8536b4Sopenharmony_ci task = OS_TCB_FROM_TID(taskID); 4133d8536b4Sopenharmony_ci sigCB = SignalCBInit(task); 4143d8536b4Sopenharmony_ci if (sigCB == NULL) { 4153d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 4163d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_NO_MEMORY; 4173d8536b4Sopenharmony_ci } 4183d8536b4Sopenharmony_ci 4193d8536b4Sopenharmony_ci if (!(sigCB->sigSetFlag & LOS_SIGNAL_MASK(sigNo))) { /* the signal has not been set */ 4203d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 4213d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_NO_SET; 4223d8536b4Sopenharmony_ci } 4233d8536b4Sopenharmony_ci 4243d8536b4Sopenharmony_ci UINT32 ret = AddSigInfoToList(sigCB, &info); 4253d8536b4Sopenharmony_ci if (ret != LOS_OK) { 4263d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 4273d8536b4Sopenharmony_ci return LOS_ERRNO_SIGNAL_NO_MEMORY; 4283d8536b4Sopenharmony_ci } 4293d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 4303d8536b4Sopenharmony_ci 4313d8536b4Sopenharmony_ci /* send signal to this thread */ 4323d8536b4Sopenharmony_ci SignalSend(task, sigNo); 4333d8536b4Sopenharmony_ci 4343d8536b4Sopenharmony_ci return LOS_OK; 4353d8536b4Sopenharmony_ci} 4363d8536b4Sopenharmony_ci 4373d8536b4Sopenharmony_ciUINT32 OsSignalInit(VOID) 4383d8536b4Sopenharmony_ci{ 4393d8536b4Sopenharmony_ci LOS_ListInit(&g_waitSignalList); 4403d8536b4Sopenharmony_ci return LOS_OK; 4413d8536b4Sopenharmony_ci} 4423d8536b4Sopenharmony_ci#endif