10d163575Sopenharmony_ci/* 20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 30d163575Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. 40d163575Sopenharmony_ci * 50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 60d163575Sopenharmony_ci * are permitted provided that the following conditions are met: 70d163575Sopenharmony_ci * 80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 90d163575Sopenharmony_ci * conditions and the following disclaimer. 100d163575Sopenharmony_ci * 110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 120d163575Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 130d163575Sopenharmony_ci * provided with the distribution. 140d163575Sopenharmony_ci * 150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 160d163575Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 170d163575Sopenharmony_ci * permission. 180d163575Sopenharmony_ci * 190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 300d163575Sopenharmony_ci */ 310d163575Sopenharmony_ci 320d163575Sopenharmony_ci#include "los_mux_pri.h" 330d163575Sopenharmony_ci#include "los_bitmap.h" 340d163575Sopenharmony_ci#include "los_spinlock.h" 350d163575Sopenharmony_ci#include "los_mp.h" 360d163575Sopenharmony_ci#include "los_task_pri.h" 370d163575Sopenharmony_ci#include "los_exc.h" 380d163575Sopenharmony_ci#include "los_sched_pri.h" 390d163575Sopenharmony_ci 400d163575Sopenharmony_ci 410d163575Sopenharmony_ci#ifdef LOSCFG_BASE_IPC_MUX 420d163575Sopenharmony_ci#define MUTEXATTR_TYPE_MASK 0x0FU 430d163575Sopenharmony_ci 440d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxAttrInit(LosMuxAttr *attr) 450d163575Sopenharmony_ci{ 460d163575Sopenharmony_ci if (attr == NULL) { 470d163575Sopenharmony_ci return LOS_EINVAL; 480d163575Sopenharmony_ci } 490d163575Sopenharmony_ci 500d163575Sopenharmony_ci attr->protocol = LOS_MUX_PRIO_INHERIT; 510d163575Sopenharmony_ci attr->prioceiling = OS_TASK_PRIORITY_LOWEST; 520d163575Sopenharmony_ci attr->type = LOS_MUX_DEFAULT; 530d163575Sopenharmony_ci return LOS_OK; 540d163575Sopenharmony_ci} 550d163575Sopenharmony_ci 560d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxAttrDestroy(LosMuxAttr *attr) 570d163575Sopenharmony_ci{ 580d163575Sopenharmony_ci if (attr == NULL) { 590d163575Sopenharmony_ci return LOS_EINVAL; 600d163575Sopenharmony_ci } 610d163575Sopenharmony_ci 620d163575Sopenharmony_ci return LOS_OK; 630d163575Sopenharmony_ci} 640d163575Sopenharmony_ci 650d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetType(const LosMuxAttr *attr, INT32 *outType) 660d163575Sopenharmony_ci{ 670d163575Sopenharmony_ci INT32 type; 680d163575Sopenharmony_ci 690d163575Sopenharmony_ci if ((attr == NULL) || (outType == NULL)) { 700d163575Sopenharmony_ci return LOS_EINVAL; 710d163575Sopenharmony_ci } 720d163575Sopenharmony_ci 730d163575Sopenharmony_ci type = (INT32)(attr->type & MUTEXATTR_TYPE_MASK); 740d163575Sopenharmony_ci if ((type < LOS_MUX_NORMAL) || (type > LOS_MUX_ERRORCHECK)) { 750d163575Sopenharmony_ci return LOS_EINVAL; 760d163575Sopenharmony_ci } 770d163575Sopenharmony_ci 780d163575Sopenharmony_ci *outType = type; 790d163575Sopenharmony_ci 800d163575Sopenharmony_ci return LOS_OK; 810d163575Sopenharmony_ci} 820d163575Sopenharmony_ci 830d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetType(LosMuxAttr *attr, INT32 type) 840d163575Sopenharmony_ci{ 850d163575Sopenharmony_ci if ((attr == NULL) || (type < LOS_MUX_NORMAL) || (type > LOS_MUX_ERRORCHECK)) { 860d163575Sopenharmony_ci return LOS_EINVAL; 870d163575Sopenharmony_ci } 880d163575Sopenharmony_ci 890d163575Sopenharmony_ci attr->type = (UINT8)((attr->type & ~MUTEXATTR_TYPE_MASK) | (UINT32)type); 900d163575Sopenharmony_ci return LOS_OK; 910d163575Sopenharmony_ci} 920d163575Sopenharmony_ci 930d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetProtocol(const LosMuxAttr *attr, INT32 *protocol) 940d163575Sopenharmony_ci{ 950d163575Sopenharmony_ci if ((attr != NULL) && (protocol != NULL)) { 960d163575Sopenharmony_ci *protocol = attr->protocol; 970d163575Sopenharmony_ci } else { 980d163575Sopenharmony_ci return LOS_EINVAL; 990d163575Sopenharmony_ci } 1000d163575Sopenharmony_ci 1010d163575Sopenharmony_ci return LOS_OK; 1020d163575Sopenharmony_ci} 1030d163575Sopenharmony_ci 1040d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetProtocol(LosMuxAttr *attr, INT32 protocol) 1050d163575Sopenharmony_ci{ 1060d163575Sopenharmony_ci if (attr == NULL) { 1070d163575Sopenharmony_ci return LOS_EINVAL; 1080d163575Sopenharmony_ci } 1090d163575Sopenharmony_ci 1100d163575Sopenharmony_ci switch (protocol) { 1110d163575Sopenharmony_ci case LOS_MUX_PRIO_NONE: 1120d163575Sopenharmony_ci case LOS_MUX_PRIO_INHERIT: 1130d163575Sopenharmony_ci case LOS_MUX_PRIO_PROTECT: 1140d163575Sopenharmony_ci attr->protocol = (UINT8)protocol; 1150d163575Sopenharmony_ci return LOS_OK; 1160d163575Sopenharmony_ci default: 1170d163575Sopenharmony_ci return LOS_EINVAL; 1180d163575Sopenharmony_ci } 1190d163575Sopenharmony_ci} 1200d163575Sopenharmony_ci 1210d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetPrioceiling(const LosMuxAttr *attr, INT32 *prioceiling) 1220d163575Sopenharmony_ci{ 1230d163575Sopenharmony_ci if (attr == NULL) { 1240d163575Sopenharmony_ci return LOS_EINVAL; 1250d163575Sopenharmony_ci } 1260d163575Sopenharmony_ci 1270d163575Sopenharmony_ci if (prioceiling != NULL) { 1280d163575Sopenharmony_ci *prioceiling = attr->prioceiling; 1290d163575Sopenharmony_ci } 1300d163575Sopenharmony_ci 1310d163575Sopenharmony_ci return LOS_OK; 1320d163575Sopenharmony_ci} 1330d163575Sopenharmony_ci 1340d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetPrioceiling(LosMuxAttr *attr, INT32 prioceiling) 1350d163575Sopenharmony_ci{ 1360d163575Sopenharmony_ci if ((attr == NULL) || 1370d163575Sopenharmony_ci (prioceiling < OS_TASK_PRIORITY_HIGHEST) || 1380d163575Sopenharmony_ci (prioceiling > OS_TASK_PRIORITY_LOWEST)) { 1390d163575Sopenharmony_ci return LOS_EINVAL; 1400d163575Sopenharmony_ci } 1410d163575Sopenharmony_ci 1420d163575Sopenharmony_ci attr->prioceiling = (UINT8)prioceiling; 1430d163575Sopenharmony_ci 1440d163575Sopenharmony_ci return LOS_OK; 1450d163575Sopenharmony_ci} 1460d163575Sopenharmony_ci 1470d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxSetPrioceiling(LosMux *mutex, INT32 prioceiling, INT32 *oldPrioceiling) 1480d163575Sopenharmony_ci{ 1490d163575Sopenharmony_ci INT32 ret; 1500d163575Sopenharmony_ci INT32 retLock; 1510d163575Sopenharmony_ci if ((mutex == NULL) || 1520d163575Sopenharmony_ci (prioceiling < OS_TASK_PRIORITY_HIGHEST) || 1530d163575Sopenharmony_ci (prioceiling > OS_TASK_PRIORITY_LOWEST)) { 1540d163575Sopenharmony_ci return LOS_EINVAL; 1550d163575Sopenharmony_ci } 1560d163575Sopenharmony_ci 1570d163575Sopenharmony_ci retLock = LOS_MuxLock(mutex, LOS_WAIT_FOREVER); 1580d163575Sopenharmony_ci if (retLock != LOS_OK) { 1590d163575Sopenharmony_ci return retLock; 1600d163575Sopenharmony_ci } 1610d163575Sopenharmony_ci 1620d163575Sopenharmony_ci if (oldPrioceiling != NULL) { 1630d163575Sopenharmony_ci *oldPrioceiling = mutex->attr.prioceiling; 1640d163575Sopenharmony_ci } 1650d163575Sopenharmony_ci 1660d163575Sopenharmony_ci ret = LOS_MuxAttrSetPrioceiling(&mutex->attr, prioceiling); 1670d163575Sopenharmony_ci 1680d163575Sopenharmony_ci retLock = LOS_MuxUnlock(mutex); 1690d163575Sopenharmony_ci if ((ret == LOS_OK) && (retLock != LOS_OK)) { 1700d163575Sopenharmony_ci return retLock; 1710d163575Sopenharmony_ci } 1720d163575Sopenharmony_ci 1730d163575Sopenharmony_ci return ret; 1740d163575Sopenharmony_ci} 1750d163575Sopenharmony_ci 1760d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxGetPrioceiling(const LosMux *mutex, INT32 *prioceiling) 1770d163575Sopenharmony_ci{ 1780d163575Sopenharmony_ci if ((mutex != NULL) && (prioceiling != NULL) && (mutex->magic == OS_MUX_MAGIC)) { 1790d163575Sopenharmony_ci *prioceiling = mutex->attr.prioceiling; 1800d163575Sopenharmony_ci return LOS_OK; 1810d163575Sopenharmony_ci } 1820d163575Sopenharmony_ci 1830d163575Sopenharmony_ci return LOS_EINVAL; 1840d163575Sopenharmony_ci} 1850d163575Sopenharmony_ci 1860d163575Sopenharmony_ciLITE_OS_SEC_TEXT BOOL LOS_MuxIsValid(const LosMux *mutex) 1870d163575Sopenharmony_ci{ 1880d163575Sopenharmony_ci if ((mutex != NULL) && (mutex->magic == OS_MUX_MAGIC)) { 1890d163575Sopenharmony_ci return TRUE; 1900d163575Sopenharmony_ci } 1910d163575Sopenharmony_ci 1920d163575Sopenharmony_ci return FALSE; 1930d163575Sopenharmony_ci} 1940d163575Sopenharmony_ci 1950d163575Sopenharmony_ciSTATIC UINT32 OsCheckMutexAttr(const LosMuxAttr *attr) 1960d163575Sopenharmony_ci{ 1970d163575Sopenharmony_ci if (((INT8)(attr->type) < LOS_MUX_NORMAL) || (attr->type > LOS_MUX_ERRORCHECK)) { 1980d163575Sopenharmony_ci return LOS_NOK; 1990d163575Sopenharmony_ci } 2000d163575Sopenharmony_ci if (((INT8)(attr->prioceiling) < OS_TASK_PRIORITY_HIGHEST) || (attr->prioceiling > OS_TASK_PRIORITY_LOWEST)) { 2010d163575Sopenharmony_ci return LOS_NOK; 2020d163575Sopenharmony_ci } 2030d163575Sopenharmony_ci if (((INT8)(attr->protocol) < LOS_MUX_PRIO_NONE) || (attr->protocol > LOS_MUX_PRIO_PROTECT)) { 2040d163575Sopenharmony_ci return LOS_NOK; 2050d163575Sopenharmony_ci } 2060d163575Sopenharmony_ci return LOS_OK; 2070d163575Sopenharmony_ci} 2080d163575Sopenharmony_ci 2090d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr) 2100d163575Sopenharmony_ci{ 2110d163575Sopenharmony_ci UINT32 intSave; 2120d163575Sopenharmony_ci 2130d163575Sopenharmony_ci if (mutex == NULL) { 2140d163575Sopenharmony_ci return LOS_EINVAL; 2150d163575Sopenharmony_ci } 2160d163575Sopenharmony_ci 2170d163575Sopenharmony_ci if (attr == NULL) { 2180d163575Sopenharmony_ci (VOID)LOS_MuxAttrInit(&mutex->attr); 2190d163575Sopenharmony_ci } else { 2200d163575Sopenharmony_ci (VOID)memcpy_s(&mutex->attr, sizeof(LosMuxAttr), attr, sizeof(LosMuxAttr)); 2210d163575Sopenharmony_ci } 2220d163575Sopenharmony_ci 2230d163575Sopenharmony_ci if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { 2240d163575Sopenharmony_ci return LOS_EINVAL; 2250d163575Sopenharmony_ci } 2260d163575Sopenharmony_ci 2270d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 2280d163575Sopenharmony_ci mutex->muxCount = 0; 2290d163575Sopenharmony_ci mutex->owner = NULL; 2300d163575Sopenharmony_ci LOS_ListInit(&mutex->muxList); 2310d163575Sopenharmony_ci mutex->magic = OS_MUX_MAGIC; 2320d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 2330d163575Sopenharmony_ci return LOS_OK; 2340d163575Sopenharmony_ci} 2350d163575Sopenharmony_ci 2360d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex) 2370d163575Sopenharmony_ci{ 2380d163575Sopenharmony_ci UINT32 intSave; 2390d163575Sopenharmony_ci 2400d163575Sopenharmony_ci if (mutex == NULL) { 2410d163575Sopenharmony_ci return LOS_EINVAL; 2420d163575Sopenharmony_ci } 2430d163575Sopenharmony_ci 2440d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 2450d163575Sopenharmony_ci if (mutex->magic != OS_MUX_MAGIC) { 2460d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 2470d163575Sopenharmony_ci return LOS_EBADF; 2480d163575Sopenharmony_ci } 2490d163575Sopenharmony_ci 2500d163575Sopenharmony_ci if (mutex->muxCount != 0) { 2510d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 2520d163575Sopenharmony_ci return LOS_EBUSY; 2530d163575Sopenharmony_ci } 2540d163575Sopenharmony_ci 2550d163575Sopenharmony_ci (VOID)memset_s(mutex, sizeof(LosMux), 0, sizeof(LosMux)); 2560d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 2570d163575Sopenharmony_ci return LOS_OK; 2580d163575Sopenharmony_ci} 2590d163575Sopenharmony_ci 2600d163575Sopenharmony_ciSTATIC VOID OsMuxBitmapSet(const LosMux *mutex, const LosTaskCB *runTask) 2610d163575Sopenharmony_ci{ 2620d163575Sopenharmony_ci if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) { 2630d163575Sopenharmony_ci return; 2640d163575Sopenharmony_ci } 2650d163575Sopenharmony_ci 2660d163575Sopenharmony_ci SchedParam param = { 0 }; 2670d163575Sopenharmony_ci LosTaskCB *owner = (LosTaskCB *)mutex->owner; 2680d163575Sopenharmony_ci INT32 ret = OsSchedParamCompare(owner, runTask); 2690d163575Sopenharmony_ci if (ret > 0) { 2700d163575Sopenharmony_ci runTask->ops->schedParamGet(runTask, ¶m); 2710d163575Sopenharmony_ci owner->ops->priorityInheritance(owner, ¶m); 2720d163575Sopenharmony_ci } 2730d163575Sopenharmony_ci} 2740d163575Sopenharmony_ci 2750d163575Sopenharmony_ciVOID OsMuxBitmapRestore(const LosMux *mutex, const LOS_DL_LIST *list, const LosTaskCB *runTask) 2760d163575Sopenharmony_ci{ 2770d163575Sopenharmony_ci if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) { 2780d163575Sopenharmony_ci return; 2790d163575Sopenharmony_ci } 2800d163575Sopenharmony_ci 2810d163575Sopenharmony_ci SchedParam param = { 0 }; 2820d163575Sopenharmony_ci LosTaskCB *owner = (LosTaskCB *)mutex->owner; 2830d163575Sopenharmony_ci runTask->ops->schedParamGet(runTask, ¶m); 2840d163575Sopenharmony_ci owner->ops->priorityRestore(owner, list, ¶m); 2850d163575Sopenharmony_ci} 2860d163575Sopenharmony_ci 2870d163575Sopenharmony_ciSTATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout) 2880d163575Sopenharmony_ci{ 2890d163575Sopenharmony_ci UINT32 ret; 2900d163575Sopenharmony_ci 2910d163575Sopenharmony_ci if ((mutex->muxList.pstPrev == NULL) || (mutex->muxList.pstNext == NULL)) { 2920d163575Sopenharmony_ci /* This is for mutex macro initialization. */ 2930d163575Sopenharmony_ci mutex->muxCount = 0; 2940d163575Sopenharmony_ci mutex->owner = NULL; 2950d163575Sopenharmony_ci LOS_ListInit(&mutex->muxList); 2960d163575Sopenharmony_ci } 2970d163575Sopenharmony_ci 2980d163575Sopenharmony_ci if (mutex->muxCount == 0) { 2990d163575Sopenharmony_ci mutex->muxCount++; 3000d163575Sopenharmony_ci mutex->owner = (VOID *)runTask; 3010d163575Sopenharmony_ci LOS_ListTailInsert(&runTask->lockList, &mutex->holdList); 3020d163575Sopenharmony_ci if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) { 3030d163575Sopenharmony_ci SchedParam param = { 0 }; 3040d163575Sopenharmony_ci runTask->ops->schedParamGet(runTask, ¶m); 3050d163575Sopenharmony_ci param.priority = mutex->attr.prioceiling; 3060d163575Sopenharmony_ci runTask->ops->priorityInheritance(runTask, ¶m); 3070d163575Sopenharmony_ci } 3080d163575Sopenharmony_ci return LOS_OK; 3090d163575Sopenharmony_ci } 3100d163575Sopenharmony_ci 3110d163575Sopenharmony_ci if (((LosTaskCB *)mutex->owner == runTask) && (mutex->attr.type == LOS_MUX_RECURSIVE)) { 3120d163575Sopenharmony_ci mutex->muxCount++; 3130d163575Sopenharmony_ci return LOS_OK; 3140d163575Sopenharmony_ci } 3150d163575Sopenharmony_ci 3160d163575Sopenharmony_ci if (!timeout) { 3170d163575Sopenharmony_ci return LOS_EINVAL; 3180d163575Sopenharmony_ci } 3190d163575Sopenharmony_ci 3200d163575Sopenharmony_ci if (!OsPreemptableInSched()) { 3210d163575Sopenharmony_ci return LOS_EDEADLK; 3220d163575Sopenharmony_ci } 3230d163575Sopenharmony_ci 3240d163575Sopenharmony_ci OsMuxBitmapSet(mutex, runTask); 3250d163575Sopenharmony_ci 3260d163575Sopenharmony_ci runTask->taskMux = (VOID *)mutex; 3270d163575Sopenharmony_ci LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &mutex->muxList); 3280d163575Sopenharmony_ci if (node == NULL) { 3290d163575Sopenharmony_ci ret = LOS_NOK; 3300d163575Sopenharmony_ci return ret; 3310d163575Sopenharmony_ci } 3320d163575Sopenharmony_ci 3330d163575Sopenharmony_ci OsTaskWaitSetPendMask(OS_TASK_WAIT_MUTEX, (UINTPTR)mutex, timeout); 3340d163575Sopenharmony_ci ret = runTask->ops->wait(runTask, node, timeout); 3350d163575Sopenharmony_ci if (ret == LOS_ERRNO_TSK_TIMEOUT) { 3360d163575Sopenharmony_ci OsMuxBitmapRestore(mutex, NULL, runTask); 3370d163575Sopenharmony_ci runTask->taskMux = NULL; 3380d163575Sopenharmony_ci ret = LOS_ETIMEDOUT; 3390d163575Sopenharmony_ci } 3400d163575Sopenharmony_ci 3410d163575Sopenharmony_ci return ret; 3420d163575Sopenharmony_ci} 3430d163575Sopenharmony_ci 3440d163575Sopenharmony_ciUINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout) 3450d163575Sopenharmony_ci{ 3460d163575Sopenharmony_ci LosTaskCB *runTask = OsCurrTaskGet(); 3470d163575Sopenharmony_ci 3480d163575Sopenharmony_ci if (mutex->magic != OS_MUX_MAGIC) { 3490d163575Sopenharmony_ci return LOS_EBADF; 3500d163575Sopenharmony_ci } 3510d163575Sopenharmony_ci 3520d163575Sopenharmony_ci if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { 3530d163575Sopenharmony_ci return LOS_EINVAL; 3540d163575Sopenharmony_ci } 3550d163575Sopenharmony_ci 3560d163575Sopenharmony_ci if ((mutex->attr.type == LOS_MUX_ERRORCHECK) && (mutex->owner == (VOID *)runTask)) { 3570d163575Sopenharmony_ci return LOS_EDEADLK; 3580d163575Sopenharmony_ci } 3590d163575Sopenharmony_ci 3600d163575Sopenharmony_ci return OsMuxPendOp(runTask, mutex, timeout); 3610d163575Sopenharmony_ci} 3620d163575Sopenharmony_ci 3630d163575Sopenharmony_ciUINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout) 3640d163575Sopenharmony_ci{ 3650d163575Sopenharmony_ci LosTaskCB *runTask = OsCurrTaskGet(); 3660d163575Sopenharmony_ci 3670d163575Sopenharmony_ci if (mutex->magic != OS_MUX_MAGIC) { 3680d163575Sopenharmony_ci return LOS_EBADF; 3690d163575Sopenharmony_ci } 3700d163575Sopenharmony_ci 3710d163575Sopenharmony_ci if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { 3720d163575Sopenharmony_ci return LOS_EINVAL; 3730d163575Sopenharmony_ci } 3740d163575Sopenharmony_ci 3750d163575Sopenharmony_ci if ((mutex->owner != NULL) && 3760d163575Sopenharmony_ci (((LosTaskCB *)mutex->owner != runTask) || (mutex->attr.type != LOS_MUX_RECURSIVE))) { 3770d163575Sopenharmony_ci return LOS_EBUSY; 3780d163575Sopenharmony_ci } 3790d163575Sopenharmony_ci 3800d163575Sopenharmony_ci return OsMuxPendOp(runTask, mutex, timeout); 3810d163575Sopenharmony_ci} 3820d163575Sopenharmony_ci 3830d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout) 3840d163575Sopenharmony_ci{ 3850d163575Sopenharmony_ci LosTaskCB *runTask = NULL; 3860d163575Sopenharmony_ci UINT32 intSave; 3870d163575Sopenharmony_ci UINT32 ret; 3880d163575Sopenharmony_ci 3890d163575Sopenharmony_ci if (mutex == NULL) { 3900d163575Sopenharmony_ci return LOS_EINVAL; 3910d163575Sopenharmony_ci } 3920d163575Sopenharmony_ci 3930d163575Sopenharmony_ci if (OS_INT_ACTIVE) { 3940d163575Sopenharmony_ci return LOS_EINTR; 3950d163575Sopenharmony_ci } 3960d163575Sopenharmony_ci 3970d163575Sopenharmony_ci runTask = (LosTaskCB *)OsCurrTaskGet(); 3980d163575Sopenharmony_ci /* DO NOT Call blocking API in system tasks */ 3990d163575Sopenharmony_ci if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { 4000d163575Sopenharmony_ci PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__); 4010d163575Sopenharmony_ci OsBackTrace(); 4020d163575Sopenharmony_ci } 4030d163575Sopenharmony_ci 4040d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 4050d163575Sopenharmony_ci ret = OsMuxLockUnsafe(mutex, timeout); 4060d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 4070d163575Sopenharmony_ci return ret; 4080d163575Sopenharmony_ci} 4090d163575Sopenharmony_ci 4100d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxTrylock(LosMux *mutex) 4110d163575Sopenharmony_ci{ 4120d163575Sopenharmony_ci LosTaskCB *runTask = NULL; 4130d163575Sopenharmony_ci UINT32 intSave; 4140d163575Sopenharmony_ci UINT32 ret; 4150d163575Sopenharmony_ci 4160d163575Sopenharmony_ci if (mutex == NULL) { 4170d163575Sopenharmony_ci return LOS_EINVAL; 4180d163575Sopenharmony_ci } 4190d163575Sopenharmony_ci 4200d163575Sopenharmony_ci if (OS_INT_ACTIVE) { 4210d163575Sopenharmony_ci return LOS_EINTR; 4220d163575Sopenharmony_ci } 4230d163575Sopenharmony_ci 4240d163575Sopenharmony_ci runTask = (LosTaskCB *)OsCurrTaskGet(); 4250d163575Sopenharmony_ci /* DO NOT Call blocking API in system tasks */ 4260d163575Sopenharmony_ci if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { 4270d163575Sopenharmony_ci PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__); 4280d163575Sopenharmony_ci OsBackTrace(); 4290d163575Sopenharmony_ci } 4300d163575Sopenharmony_ci 4310d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 4320d163575Sopenharmony_ci ret = OsMuxTrylockUnsafe(mutex, 0); 4330d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 4340d163575Sopenharmony_ci return ret; 4350d163575Sopenharmony_ci} 4360d163575Sopenharmony_ci 4370d163575Sopenharmony_ciSTATIC UINT32 OsMuxPostOp(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched) 4380d163575Sopenharmony_ci{ 4390d163575Sopenharmony_ci if (LOS_ListEmpty(&mutex->muxList)) { 4400d163575Sopenharmony_ci LOS_ListDelete(&mutex->holdList); 4410d163575Sopenharmony_ci mutex->owner = NULL; 4420d163575Sopenharmony_ci return LOS_OK; 4430d163575Sopenharmony_ci } 4440d163575Sopenharmony_ci 4450d163575Sopenharmony_ci LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(mutex->muxList))); 4460d163575Sopenharmony_ci OsMuxBitmapRestore(mutex, &mutex->muxList, resumedTask); 4470d163575Sopenharmony_ci 4480d163575Sopenharmony_ci mutex->muxCount = 1; 4490d163575Sopenharmony_ci mutex->owner = (VOID *)resumedTask; 4500d163575Sopenharmony_ci LOS_ListDelete(&mutex->holdList); 4510d163575Sopenharmony_ci LOS_ListTailInsert(&resumedTask->lockList, &mutex->holdList); 4520d163575Sopenharmony_ci OsTaskWakeClearPendMask(resumedTask); 4530d163575Sopenharmony_ci resumedTask->ops->wake(resumedTask); 4540d163575Sopenharmony_ci resumedTask->taskMux = NULL; 4550d163575Sopenharmony_ci if (needSched != NULL) { 4560d163575Sopenharmony_ci *needSched = TRUE; 4570d163575Sopenharmony_ci } 4580d163575Sopenharmony_ci 4590d163575Sopenharmony_ci return LOS_OK; 4600d163575Sopenharmony_ci} 4610d163575Sopenharmony_ci 4620d163575Sopenharmony_ciUINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched) 4630d163575Sopenharmony_ci{ 4640d163575Sopenharmony_ci if (mutex->magic != OS_MUX_MAGIC) { 4650d163575Sopenharmony_ci return LOS_EBADF; 4660d163575Sopenharmony_ci } 4670d163575Sopenharmony_ci 4680d163575Sopenharmony_ci if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) { 4690d163575Sopenharmony_ci return LOS_EINVAL; 4700d163575Sopenharmony_ci } 4710d163575Sopenharmony_ci 4720d163575Sopenharmony_ci if ((LosTaskCB *)mutex->owner != taskCB) { 4730d163575Sopenharmony_ci return LOS_EPERM; 4740d163575Sopenharmony_ci } 4750d163575Sopenharmony_ci 4760d163575Sopenharmony_ci if (mutex->muxCount == 0) { 4770d163575Sopenharmony_ci return LOS_EPERM; 4780d163575Sopenharmony_ci } 4790d163575Sopenharmony_ci 4800d163575Sopenharmony_ci if ((--mutex->muxCount != 0) && (mutex->attr.type == LOS_MUX_RECURSIVE)) { 4810d163575Sopenharmony_ci return LOS_OK; 4820d163575Sopenharmony_ci } 4830d163575Sopenharmony_ci 4840d163575Sopenharmony_ci if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) { 4850d163575Sopenharmony_ci SchedParam param = { 0 }; 4860d163575Sopenharmony_ci taskCB->ops->schedParamGet(taskCB, ¶m); 4870d163575Sopenharmony_ci taskCB->ops->priorityRestore(taskCB, NULL, ¶m); 4880d163575Sopenharmony_ci } 4890d163575Sopenharmony_ci 4900d163575Sopenharmony_ci /* Whether a task block the mutex lock. */ 4910d163575Sopenharmony_ci return OsMuxPostOp(taskCB, mutex, needSched); 4920d163575Sopenharmony_ci} 4930d163575Sopenharmony_ci 4940d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex) 4950d163575Sopenharmony_ci{ 4960d163575Sopenharmony_ci LosTaskCB *runTask = NULL; 4970d163575Sopenharmony_ci BOOL needSched = FALSE; 4980d163575Sopenharmony_ci UINT32 intSave; 4990d163575Sopenharmony_ci UINT32 ret; 5000d163575Sopenharmony_ci 5010d163575Sopenharmony_ci if (mutex == NULL) { 5020d163575Sopenharmony_ci return LOS_EINVAL; 5030d163575Sopenharmony_ci } 5040d163575Sopenharmony_ci 5050d163575Sopenharmony_ci if (OS_INT_ACTIVE) { 5060d163575Sopenharmony_ci return LOS_EINTR; 5070d163575Sopenharmony_ci } 5080d163575Sopenharmony_ci 5090d163575Sopenharmony_ci runTask = (LosTaskCB *)OsCurrTaskGet(); 5100d163575Sopenharmony_ci /* DO NOT Call blocking API in system tasks */ 5110d163575Sopenharmony_ci if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) { 5120d163575Sopenharmony_ci PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__); 5130d163575Sopenharmony_ci OsBackTrace(); 5140d163575Sopenharmony_ci } 5150d163575Sopenharmony_ci 5160d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 5170d163575Sopenharmony_ci ret = OsMuxUnlockUnsafe(runTask, mutex, &needSched); 5180d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 5190d163575Sopenharmony_ci if (needSched == TRUE) { 5200d163575Sopenharmony_ci LOS_MpSchedule(OS_MP_CPU_ALL); 5210d163575Sopenharmony_ci LOS_Schedule(); 5220d163575Sopenharmony_ci } 5230d163575Sopenharmony_ci return ret; 5240d163575Sopenharmony_ci} 5250d163575Sopenharmony_ci 5260d163575Sopenharmony_ci#endif /* LOSCFG_BASE_IPC_MUX */ 5270d163575Sopenharmony_ci 528