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