13d8536b4Sopenharmony_ci/* 23d8536b4Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 33d8536b4Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 43d8536b4Sopenharmony_ci * 53d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 63d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met: 73d8536b4Sopenharmony_ci * 83d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 93d8536b4Sopenharmony_ci * conditions and the following disclaimer. 103d8536b4Sopenharmony_ci * 113d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 123d8536b4Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 133d8536b4Sopenharmony_ci * provided with the distribution. 143d8536b4Sopenharmony_ci * 153d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 163d8536b4Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 173d8536b4Sopenharmony_ci * permission. 183d8536b4Sopenharmony_ci * 193d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 203d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 213d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 223d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 233d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 243d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 253d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 263d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 273d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 283d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 293d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303d8536b4Sopenharmony_ci */ 313d8536b4Sopenharmony_ci 323d8536b4Sopenharmony_ci#include <pthread.h> 333d8536b4Sopenharmony_ci#include <time.h> 343d8536b4Sopenharmony_ci#include <securec.h> 353d8536b4Sopenharmony_ci#include "los_compiler.h" 363d8536b4Sopenharmony_ci#include "los_mux.h" 373d8536b4Sopenharmony_ci#include "errno.h" 383d8536b4Sopenharmony_ci#include "los_debug.h" 393d8536b4Sopenharmony_ci#include "los_hook.h" 403d8536b4Sopenharmony_ci#include "los_sched.h" 413d8536b4Sopenharmony_ci#if (LOSCFG_MUTEX_CREATE_TRACE == 1) 423d8536b4Sopenharmony_ci#include "los_arch.h" 433d8536b4Sopenharmony_ci#endif 443d8536b4Sopenharmony_ci 453d8536b4Sopenharmony_ci#define MUTEXATTR_TYPE_MASK 0x0FU 463d8536b4Sopenharmony_ci#define OS_SYS_NS_PER_MSECOND 1000000 473d8536b4Sopenharmony_ci#define OS_SYS_NS_PER_SECOND 1000000000 483d8536b4Sopenharmony_ci 493d8536b4Sopenharmony_cistatic inline int MapError(UINT32 err) 503d8536b4Sopenharmony_ci{ 513d8536b4Sopenharmony_ci switch (err) { 523d8536b4Sopenharmony_ci case LOS_OK: 533d8536b4Sopenharmony_ci return 0; 543d8536b4Sopenharmony_ci case LOS_ERRNO_MUX_IN_INTERR: 553d8536b4Sopenharmony_ci return EPERM; 563d8536b4Sopenharmony_ci case LOS_ERRNO_MUX_PEND_IN_LOCK: 573d8536b4Sopenharmony_ci return EDEADLK; 583d8536b4Sopenharmony_ci case LOS_ERRNO_MUX_PENDED: 593d8536b4Sopenharmony_ci case LOS_ERRNO_MUX_UNAVAILABLE: 603d8536b4Sopenharmony_ci return EBUSY; 613d8536b4Sopenharmony_ci case LOS_ERRNO_MUX_TIMEOUT: 623d8536b4Sopenharmony_ci return ETIMEDOUT; 633d8536b4Sopenharmony_ci case LOS_ERRNO_MUX_ALL_BUSY: 643d8536b4Sopenharmony_ci return EAGAIN; 653d8536b4Sopenharmony_ci case LOS_ERRNO_MUX_INVALID: 663d8536b4Sopenharmony_ci default: 673d8536b4Sopenharmony_ci return EINVAL; 683d8536b4Sopenharmony_ci } 693d8536b4Sopenharmony_ci} 703d8536b4Sopenharmony_ci 713d8536b4Sopenharmony_ciint pthread_mutexattr_init(pthread_mutexattr_t *mutexAttr) 723d8536b4Sopenharmony_ci{ 733d8536b4Sopenharmony_ci if (mutexAttr == NULL) { 743d8536b4Sopenharmony_ci return EINVAL; 753d8536b4Sopenharmony_ci } 763d8536b4Sopenharmony_ci 773d8536b4Sopenharmony_ci mutexAttr->type = PTHREAD_MUTEX_DEFAULT; 783d8536b4Sopenharmony_ci 793d8536b4Sopenharmony_ci return 0; 803d8536b4Sopenharmony_ci} 813d8536b4Sopenharmony_ci 823d8536b4Sopenharmony_ciint pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *outType) 833d8536b4Sopenharmony_ci{ 843d8536b4Sopenharmony_ci INT32 type; 853d8536b4Sopenharmony_ci 863d8536b4Sopenharmony_ci if ((attr == NULL) || (outType == NULL)) { 873d8536b4Sopenharmony_ci return EINVAL; 883d8536b4Sopenharmony_ci } 893d8536b4Sopenharmony_ci 903d8536b4Sopenharmony_ci type = (INT32)(attr->type & MUTEXATTR_TYPE_MASK); 913d8536b4Sopenharmony_ci if ((type != PTHREAD_MUTEX_NORMAL) && 923d8536b4Sopenharmony_ci (type != PTHREAD_MUTEX_RECURSIVE) && 933d8536b4Sopenharmony_ci (type != PTHREAD_MUTEX_ERRORCHECK)) { 943d8536b4Sopenharmony_ci return EINVAL; 953d8536b4Sopenharmony_ci } 963d8536b4Sopenharmony_ci 973d8536b4Sopenharmony_ci *outType = type; 983d8536b4Sopenharmony_ci 993d8536b4Sopenharmony_ci return 0; 1003d8536b4Sopenharmony_ci} 1013d8536b4Sopenharmony_ci 1023d8536b4Sopenharmony_ciint pthread_mutexattr_settype(pthread_mutexattr_t *mutexAttr, int type) 1033d8536b4Sopenharmony_ci{ 1043d8536b4Sopenharmony_ci if (mutexAttr == NULL) { 1053d8536b4Sopenharmony_ci return EINVAL; 1063d8536b4Sopenharmony_ci } 1073d8536b4Sopenharmony_ci 1083d8536b4Sopenharmony_ci if (((unsigned)type != PTHREAD_MUTEX_NORMAL) && 1093d8536b4Sopenharmony_ci ((unsigned)type != PTHREAD_MUTEX_RECURSIVE) && 1103d8536b4Sopenharmony_ci ((unsigned)type != PTHREAD_MUTEX_ERRORCHECK)) { 1113d8536b4Sopenharmony_ci return EINVAL; 1123d8536b4Sopenharmony_ci } 1133d8536b4Sopenharmony_ci mutexAttr->type = (UINT8)((mutexAttr->type & ~MUTEXATTR_TYPE_MASK) | (UINT32)type); 1143d8536b4Sopenharmony_ci 1153d8536b4Sopenharmony_ci return 0; 1163d8536b4Sopenharmony_ci} 1173d8536b4Sopenharmony_ci 1183d8536b4Sopenharmony_ciint pthread_mutexattr_destroy(pthread_mutexattr_t *mutexAttr) 1193d8536b4Sopenharmony_ci{ 1203d8536b4Sopenharmony_ci if (mutexAttr == NULL) { 1213d8536b4Sopenharmony_ci return EINVAL; 1223d8536b4Sopenharmony_ci } 1233d8536b4Sopenharmony_ci 1243d8536b4Sopenharmony_ci (VOID)memset_s(mutexAttr, sizeof(pthread_mutexattr_t), 0, sizeof(pthread_mutexattr_t)); 1253d8536b4Sopenharmony_ci 1263d8536b4Sopenharmony_ci return 0; 1273d8536b4Sopenharmony_ci} 1283d8536b4Sopenharmony_ci 1293d8536b4Sopenharmony_ci/* Initialize mutex. If mutexAttr is NULL, use default attributes. */ 1303d8536b4Sopenharmony_ciint pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexAttr) 1313d8536b4Sopenharmony_ci{ 1323d8536b4Sopenharmony_ci pthread_mutexattr_t useAttr; 1333d8536b4Sopenharmony_ci UINT32 muxHandle; 1343d8536b4Sopenharmony_ci UINT32 ret; 1353d8536b4Sopenharmony_ci 1363d8536b4Sopenharmony_ci#if (LOSCFG_MUTEX_CREATE_TRACE == 1) 1373d8536b4Sopenharmony_ci UINTPTR regLR = ArchLRGet(); 1383d8536b4Sopenharmony_ci#endif 1393d8536b4Sopenharmony_ci 1403d8536b4Sopenharmony_ci if (mutex == NULL) { 1413d8536b4Sopenharmony_ci return EINVAL; 1423d8536b4Sopenharmony_ci } 1433d8536b4Sopenharmony_ci 1443d8536b4Sopenharmony_ci if (mutexAttr == NULL) { 1453d8536b4Sopenharmony_ci (VOID)pthread_mutexattr_init(&useAttr); 1463d8536b4Sopenharmony_ci } else { 1473d8536b4Sopenharmony_ci useAttr = *mutexAttr; 1483d8536b4Sopenharmony_ci } 1493d8536b4Sopenharmony_ci 1503d8536b4Sopenharmony_ci ret = LOS_MuxCreate(&muxHandle); 1513d8536b4Sopenharmony_ci if (ret != LOS_OK) { 1523d8536b4Sopenharmony_ci return MapError(ret); 1533d8536b4Sopenharmony_ci } 1543d8536b4Sopenharmony_ci 1553d8536b4Sopenharmony_ci mutex->stAttr = useAttr; 1563d8536b4Sopenharmony_ci mutex->magic = _MUX_MAGIC; 1573d8536b4Sopenharmony_ci mutex->handle = muxHandle; 1583d8536b4Sopenharmony_ci#if (LOSCFG_MUTEX_CREATE_TRACE == 1) 1593d8536b4Sopenharmony_ci OsSetMutexCreateInfo(GET_MUX(mutex->handle), regLR); 1603d8536b4Sopenharmony_ci#endif 1613d8536b4Sopenharmony_ci 1623d8536b4Sopenharmony_ci return 0; 1633d8536b4Sopenharmony_ci} 1643d8536b4Sopenharmony_ci 1653d8536b4Sopenharmony_ciint pthread_mutex_destroy(pthread_mutex_t *mutex) 1663d8536b4Sopenharmony_ci{ 1673d8536b4Sopenharmony_ci UINT32 ret; 1683d8536b4Sopenharmony_ci if ((mutex == NULL) || (mutex->magic != _MUX_MAGIC)) { 1693d8536b4Sopenharmony_ci return EINVAL; 1703d8536b4Sopenharmony_ci } 1713d8536b4Sopenharmony_ci ret = LOS_MuxDelete(mutex->handle); 1723d8536b4Sopenharmony_ci if (ret != LOS_OK) { 1733d8536b4Sopenharmony_ci return MapError(ret); 1743d8536b4Sopenharmony_ci } 1753d8536b4Sopenharmony_ci mutex->handle = _MUX_INVALID_HANDLE; 1763d8536b4Sopenharmony_ci mutex->magic = 0; 1773d8536b4Sopenharmony_ci 1783d8536b4Sopenharmony_ci return 0; 1793d8536b4Sopenharmony_ci} 1803d8536b4Sopenharmony_ci 1813d8536b4Sopenharmony_ciSTATIC UINT32 CheckMutexAttr(const pthread_mutexattr_t *attr) 1823d8536b4Sopenharmony_ci{ 1833d8536b4Sopenharmony_ci if ((attr->type != PTHREAD_MUTEX_NORMAL) && 1843d8536b4Sopenharmony_ci (attr->type != PTHREAD_MUTEX_RECURSIVE) && 1853d8536b4Sopenharmony_ci (attr->type != PTHREAD_MUTEX_ERRORCHECK)) { 1863d8536b4Sopenharmony_ci return LOS_NOK; 1873d8536b4Sopenharmony_ci } 1883d8536b4Sopenharmony_ci 1893d8536b4Sopenharmony_ci return LOS_OK; 1903d8536b4Sopenharmony_ci} 1913d8536b4Sopenharmony_ci 1923d8536b4Sopenharmony_ciSTATIC UINT32 MuxPreCheck(const pthread_mutex_t *mutex, const LosTaskCB *runTask) 1933d8536b4Sopenharmony_ci{ 1943d8536b4Sopenharmony_ci if ((mutex == NULL) || (mutex->magic != _MUX_MAGIC) || 1953d8536b4Sopenharmony_ci ((mutex->handle != _MUX_INVALID_HANDLE) && (mutex->handle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT))) { 1963d8536b4Sopenharmony_ci return EINVAL; 1973d8536b4Sopenharmony_ci } 1983d8536b4Sopenharmony_ci 1993d8536b4Sopenharmony_ci if (OS_INT_ACTIVE) { 2003d8536b4Sopenharmony_ci return EPERM; 2013d8536b4Sopenharmony_ci } 2023d8536b4Sopenharmony_ci /* DO NOT recommend to use blocking API in system tasks */ 2033d8536b4Sopenharmony_ci if ((runTask != NULL) && (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK)) { 2043d8536b4Sopenharmony_ci PRINT_DEBUG("Warning: DO NOT recommend to use %s in system tasks.\n", __FUNCTION__); 2053d8536b4Sopenharmony_ci } 2063d8536b4Sopenharmony_ci 2073d8536b4Sopenharmony_ci if (CheckMutexAttr(&mutex->stAttr) != LOS_OK) { 2083d8536b4Sopenharmony_ci return EINVAL; 2093d8536b4Sopenharmony_ci } 2103d8536b4Sopenharmony_ci 2113d8536b4Sopenharmony_ci return 0; 2123d8536b4Sopenharmony_ci} 2133d8536b4Sopenharmony_ci 2143d8536b4Sopenharmony_ciSTATIC UINT32 MuxPendForPosix(pthread_mutex_t *mutex, UINT32 timeout) 2153d8536b4Sopenharmony_ci{ 2163d8536b4Sopenharmony_ci UINT32 intSave; 2173d8536b4Sopenharmony_ci LosMuxCB *muxPended = NULL; 2183d8536b4Sopenharmony_ci UINT32 retErr; 2193d8536b4Sopenharmony_ci LosTaskCB *runningTask = NULL; 2203d8536b4Sopenharmony_ci UINT32 muxHandle = mutex->handle; 2213d8536b4Sopenharmony_ci 2223d8536b4Sopenharmony_ci muxPended = GET_MUX(muxHandle); 2233d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 2243d8536b4Sopenharmony_ci 2253d8536b4Sopenharmony_ci if (muxPended->muxStat == OS_MUX_UNUSED) { 2263d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2273d8536b4Sopenharmony_ci OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); 2283d8536b4Sopenharmony_ci } 2293d8536b4Sopenharmony_ci 2303d8536b4Sopenharmony_ci runningTask = (LosTaskCB *)g_losTask.runTask; 2313d8536b4Sopenharmony_ci if (muxPended->muxCount == 0) { 2323d8536b4Sopenharmony_ci muxPended->muxCount++; 2333d8536b4Sopenharmony_ci muxPended->owner = runningTask; 2343d8536b4Sopenharmony_ci muxPended->priority = runningTask->priority; 2353d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2363d8536b4Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_MUX_PEND, muxPended, timeout); 2373d8536b4Sopenharmony_ci return LOS_OK; 2383d8536b4Sopenharmony_ci } 2393d8536b4Sopenharmony_ci 2403d8536b4Sopenharmony_ci if ((muxPended->owner == runningTask) && (mutex->stAttr.type == PTHREAD_MUTEX_RECURSIVE)) { 2413d8536b4Sopenharmony_ci muxPended->muxCount++; 2423d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2433d8536b4Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_MUX_PEND, muxPended, timeout); 2443d8536b4Sopenharmony_ci return LOS_OK; 2453d8536b4Sopenharmony_ci } 2463d8536b4Sopenharmony_ci 2473d8536b4Sopenharmony_ci if (!timeout) { 2483d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2493d8536b4Sopenharmony_ci OS_RETURN_ERROR(LOS_ERRNO_MUX_UNAVAILABLE); 2503d8536b4Sopenharmony_ci } 2513d8536b4Sopenharmony_ci 2523d8536b4Sopenharmony_ci runningTask->taskMux = (VOID *)muxPended; 2533d8536b4Sopenharmony_ci 2543d8536b4Sopenharmony_ci if (muxPended->owner->priority > runningTask->priority) { 2553d8536b4Sopenharmony_ci (VOID)OsSchedModifyTaskSchedParam(muxPended->owner, runningTask->priority); 2563d8536b4Sopenharmony_ci } 2573d8536b4Sopenharmony_ci 2583d8536b4Sopenharmony_ci OsSchedTaskWait(&muxPended->muxList, timeout); 2593d8536b4Sopenharmony_ci 2603d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2613d8536b4Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_MUX_PEND, muxPended, timeout); 2623d8536b4Sopenharmony_ci LOS_Schedule(); 2633d8536b4Sopenharmony_ci 2643d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 2653d8536b4Sopenharmony_ci if (runningTask->taskStatus & OS_TASK_STATUS_TIMEOUT) { 2663d8536b4Sopenharmony_ci runningTask->taskStatus &= (~OS_TASK_STATUS_TIMEOUT); 2673d8536b4Sopenharmony_ci retErr = LOS_ERRNO_MUX_TIMEOUT; 2683d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2693d8536b4Sopenharmony_ci OS_RETURN_ERROR(retErr); 2703d8536b4Sopenharmony_ci } 2713d8536b4Sopenharmony_ci 2723d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2733d8536b4Sopenharmony_ci return LOS_OK; 2743d8536b4Sopenharmony_ci} 2753d8536b4Sopenharmony_ci 2763d8536b4Sopenharmony_ciSTATIC UINT32 MuxPostForPosix(pthread_mutex_t *mutex) 2773d8536b4Sopenharmony_ci{ 2783d8536b4Sopenharmony_ci UINT32 intSave; 2793d8536b4Sopenharmony_ci LosMuxCB *muxPosted = NULL; 2803d8536b4Sopenharmony_ci LosTaskCB *resumedTask = NULL; 2813d8536b4Sopenharmony_ci LosTaskCB *runningTask = NULL; 2823d8536b4Sopenharmony_ci UINT32 muxHandle = mutex->handle; 2833d8536b4Sopenharmony_ci 2843d8536b4Sopenharmony_ci muxPosted = GET_MUX(muxHandle); 2853d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 2863d8536b4Sopenharmony_ci 2873d8536b4Sopenharmony_ci if (muxPosted->muxStat == OS_MUX_UNUSED) { 2883d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2893d8536b4Sopenharmony_ci OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); 2903d8536b4Sopenharmony_ci } 2913d8536b4Sopenharmony_ci 2923d8536b4Sopenharmony_ci runningTask = (LosTaskCB *)g_losTask.runTask; 2933d8536b4Sopenharmony_ci if ((muxPosted->muxCount == 0) || (muxPosted->owner != runningTask)) { 2943d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 2953d8536b4Sopenharmony_ci OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID); 2963d8536b4Sopenharmony_ci } 2973d8536b4Sopenharmony_ci 2983d8536b4Sopenharmony_ci if ((--(muxPosted->muxCount) != 0) && (mutex->stAttr.type == PTHREAD_MUTEX_RECURSIVE)) { 2993d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 3003d8536b4Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_MUX_POST, muxPosted); 3013d8536b4Sopenharmony_ci return LOS_OK; 3023d8536b4Sopenharmony_ci } 3033d8536b4Sopenharmony_ci 3043d8536b4Sopenharmony_ci if ((muxPosted->owner->priority) != muxPosted->priority) { 3053d8536b4Sopenharmony_ci (VOID)OsSchedModifyTaskSchedParam(muxPosted->owner, muxPosted->priority); 3063d8536b4Sopenharmony_ci } 3073d8536b4Sopenharmony_ci 3083d8536b4Sopenharmony_ci if (!LOS_ListEmpty(&muxPosted->muxList)) { 3093d8536b4Sopenharmony_ci resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(muxPosted->muxList))); 3103d8536b4Sopenharmony_ci 3113d8536b4Sopenharmony_ci muxPosted->muxCount = 1; 3123d8536b4Sopenharmony_ci muxPosted->owner = resumedTask; 3133d8536b4Sopenharmony_ci muxPosted->priority = resumedTask->priority; 3143d8536b4Sopenharmony_ci resumedTask->taskMux = NULL; 3153d8536b4Sopenharmony_ci 3163d8536b4Sopenharmony_ci OsSchedTaskWake(resumedTask); 3173d8536b4Sopenharmony_ci 3183d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 3193d8536b4Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_MUX_POST, muxPosted); 3203d8536b4Sopenharmony_ci LOS_Schedule(); 3213d8536b4Sopenharmony_ci } else { 3223d8536b4Sopenharmony_ci muxPosted->owner = NULL; 3233d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 3243d8536b4Sopenharmony_ci } 3253d8536b4Sopenharmony_ci 3263d8536b4Sopenharmony_ci return LOS_OK; 3273d8536b4Sopenharmony_ci} 3283d8536b4Sopenharmony_ci 3293d8536b4Sopenharmony_ciint pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *absTimeout) 3303d8536b4Sopenharmony_ci{ 3313d8536b4Sopenharmony_ci UINT32 ret; 3323d8536b4Sopenharmony_ci UINT32 timeout; 3333d8536b4Sopenharmony_ci UINT64 timeoutNs; 3343d8536b4Sopenharmony_ci struct timespec curTime = {0}; 3353d8536b4Sopenharmony_ci LosMuxCB *muxPended = NULL; 3363d8536b4Sopenharmony_ci 3373d8536b4Sopenharmony_ci#if (LOSCFG_MUTEX_CREATE_TRACE == 1) 3383d8536b4Sopenharmony_ci UINTPTR regLR = ArchLRGet(); 3393d8536b4Sopenharmony_ci#endif 3403d8536b4Sopenharmony_ci 3413d8536b4Sopenharmony_ci ret = MuxPreCheck(mutex, OS_TCB_FROM_TID(LOS_CurTaskIDGet())); 3423d8536b4Sopenharmony_ci if (ret != 0) { 3433d8536b4Sopenharmony_ci return (INT32)ret; 3443d8536b4Sopenharmony_ci } 3453d8536b4Sopenharmony_ci 3463d8536b4Sopenharmony_ci if ((absTimeout == NULL) || (absTimeout->tv_nsec < 0) || (absTimeout->tv_nsec >= OS_SYS_NS_PER_SECOND)) { 3473d8536b4Sopenharmony_ci return EINVAL; 3483d8536b4Sopenharmony_ci } 3493d8536b4Sopenharmony_ci if (mutex->handle == _MUX_INVALID_HANDLE) { 3503d8536b4Sopenharmony_ci ret = LOS_MuxCreate(&mutex->handle); 3513d8536b4Sopenharmony_ci if (ret != LOS_OK) { 3523d8536b4Sopenharmony_ci return MapError(ret); 3533d8536b4Sopenharmony_ci } 3543d8536b4Sopenharmony_ci#if (LOSCFG_MUTEX_CREATE_TRACE == 1) 3553d8536b4Sopenharmony_ci OsSetMutexCreateInfo(GET_MUX(mutex->handle), regLR); 3563d8536b4Sopenharmony_ci#endif 3573d8536b4Sopenharmony_ci } else { 3583d8536b4Sopenharmony_ci muxPended = GET_MUX(mutex->handle); 3593d8536b4Sopenharmony_ci if ((mutex->stAttr.type == PTHREAD_MUTEX_ERRORCHECK) && 3603d8536b4Sopenharmony_ci (muxPended->muxCount != 0) && 3613d8536b4Sopenharmony_ci (muxPended->owner == OS_TCB_FROM_TID(LOS_CurTaskIDGet()))) { 3623d8536b4Sopenharmony_ci return EDEADLK; 3633d8536b4Sopenharmony_ci } 3643d8536b4Sopenharmony_ci } 3653d8536b4Sopenharmony_ci ret = clock_gettime(CLOCK_REALTIME, &curTime); 3663d8536b4Sopenharmony_ci if (ret != LOS_OK) { 3673d8536b4Sopenharmony_ci return EINVAL; 3683d8536b4Sopenharmony_ci } 3693d8536b4Sopenharmony_ci timeoutNs = (absTimeout->tv_sec - curTime.tv_sec) * OS_SYS_NS_PER_SECOND + (absTimeout->tv_nsec - curTime.tv_nsec); 3703d8536b4Sopenharmony_ci if (timeoutNs <= 0) { 3713d8536b4Sopenharmony_ci return ETIMEDOUT; 3723d8536b4Sopenharmony_ci } 3733d8536b4Sopenharmony_ci timeout = (timeoutNs + (OS_SYS_NS_PER_MSECOND - 1)) / OS_SYS_NS_PER_MSECOND; 3743d8536b4Sopenharmony_ci ret = MuxPendForPosix(mutex, timeout); 3753d8536b4Sopenharmony_ci 3763d8536b4Sopenharmony_ci return MapError(ret); 3773d8536b4Sopenharmony_ci} 3783d8536b4Sopenharmony_ci 3793d8536b4Sopenharmony_ci/* Lock mutex, waiting for it if necessary. */ 3803d8536b4Sopenharmony_ciint pthread_mutex_lock(pthread_mutex_t *mutex) 3813d8536b4Sopenharmony_ci{ 3823d8536b4Sopenharmony_ci UINT32 ret; 3833d8536b4Sopenharmony_ci LosMuxCB *muxPended = NULL; 3843d8536b4Sopenharmony_ci 3853d8536b4Sopenharmony_ci#if (LOSCFG_MUTEX_CREATE_TRACE == 1) 3863d8536b4Sopenharmony_ci UINTPTR regLR = ArchLRGet(); 3873d8536b4Sopenharmony_ci#endif 3883d8536b4Sopenharmony_ci 3893d8536b4Sopenharmony_ci LosTaskCB *runTask = OS_TCB_FROM_TID(LOS_CurTaskIDGet()); 3903d8536b4Sopenharmony_ci 3913d8536b4Sopenharmony_ci ret = MuxPreCheck(mutex, runTask); 3923d8536b4Sopenharmony_ci if (ret != 0) { 3933d8536b4Sopenharmony_ci return (INT32)ret; 3943d8536b4Sopenharmony_ci } 3953d8536b4Sopenharmony_ci 3963d8536b4Sopenharmony_ci if (mutex->handle == _MUX_INVALID_HANDLE) { 3973d8536b4Sopenharmony_ci ret = LOS_MuxCreate(&mutex->handle); 3983d8536b4Sopenharmony_ci if (ret != LOS_OK) { 3993d8536b4Sopenharmony_ci return MapError(ret); 4003d8536b4Sopenharmony_ci } 4013d8536b4Sopenharmony_ci#if (LOSCFG_MUTEX_CREATE_TRACE == 1) 4023d8536b4Sopenharmony_ci OsSetMutexCreateInfo(GET_MUX(mutex->handle), regLR); 4033d8536b4Sopenharmony_ci#endif 4043d8536b4Sopenharmony_ci } else { 4053d8536b4Sopenharmony_ci muxPended = GET_MUX(mutex->handle); 4063d8536b4Sopenharmony_ci if ((mutex->stAttr.type == PTHREAD_MUTEX_ERRORCHECK) && 4073d8536b4Sopenharmony_ci (muxPended->muxCount != 0) && 4083d8536b4Sopenharmony_ci (muxPended->owner == runTask)) { 4093d8536b4Sopenharmony_ci return EDEADLK; 4103d8536b4Sopenharmony_ci } 4113d8536b4Sopenharmony_ci } 4123d8536b4Sopenharmony_ci ret = MuxPendForPosix(mutex, LOS_WAIT_FOREVER); 4133d8536b4Sopenharmony_ci 4143d8536b4Sopenharmony_ci return MapError(ret); 4153d8536b4Sopenharmony_ci} 4163d8536b4Sopenharmony_ci 4173d8536b4Sopenharmony_ciint pthread_mutex_trylock(pthread_mutex_t *mutex) 4183d8536b4Sopenharmony_ci{ 4193d8536b4Sopenharmony_ci UINT32 ret; 4203d8536b4Sopenharmony_ci LosMuxCB *muxPended = NULL; 4213d8536b4Sopenharmony_ci 4223d8536b4Sopenharmony_ci#if (LOSCFG_MUTEX_CREATE_TRACE == 1) 4233d8536b4Sopenharmony_ci UINTPTR regLR = ArchLRGet(); 4243d8536b4Sopenharmony_ci#endif 4253d8536b4Sopenharmony_ci 4263d8536b4Sopenharmony_ci ret = MuxPreCheck(mutex, OS_TCB_FROM_TID(LOS_CurTaskIDGet())); 4273d8536b4Sopenharmony_ci if (ret != 0) { 4283d8536b4Sopenharmony_ci return (INT32)ret; 4293d8536b4Sopenharmony_ci } 4303d8536b4Sopenharmony_ci 4313d8536b4Sopenharmony_ci if (mutex->handle == _MUX_INVALID_HANDLE) { 4323d8536b4Sopenharmony_ci ret = LOS_MuxCreate(&mutex->handle); 4333d8536b4Sopenharmony_ci if (ret != LOS_OK) { 4343d8536b4Sopenharmony_ci return MapError(ret); 4353d8536b4Sopenharmony_ci } 4363d8536b4Sopenharmony_ci#if (LOSCFG_MUTEX_CREATE_TRACE == 1) 4373d8536b4Sopenharmony_ci OsSetMutexCreateInfo(GET_MUX(mutex->handle), regLR); 4383d8536b4Sopenharmony_ci#endif 4393d8536b4Sopenharmony_ci } else { 4403d8536b4Sopenharmony_ci muxPended = GET_MUX(mutex->handle); 4413d8536b4Sopenharmony_ci if ((mutex->stAttr.type != PTHREAD_MUTEX_RECURSIVE) && (muxPended->muxCount != 0)) { 4423d8536b4Sopenharmony_ci return EBUSY; 4433d8536b4Sopenharmony_ci } 4443d8536b4Sopenharmony_ci } 4453d8536b4Sopenharmony_ci ret = MuxPendForPosix(mutex, 0); 4463d8536b4Sopenharmony_ci 4473d8536b4Sopenharmony_ci return MapError(ret); 4483d8536b4Sopenharmony_ci} 4493d8536b4Sopenharmony_ci 4503d8536b4Sopenharmony_ciint pthread_mutex_unlock(pthread_mutex_t *mutex) 4513d8536b4Sopenharmony_ci{ 4523d8536b4Sopenharmony_ci UINT32 ret; 4533d8536b4Sopenharmony_ci ret = MuxPreCheck(mutex, OS_TCB_FROM_TID(LOS_CurTaskIDGet())); 4543d8536b4Sopenharmony_ci if (ret != 0) { 4553d8536b4Sopenharmony_ci return (INT32)ret; 4563d8536b4Sopenharmony_ci } 4573d8536b4Sopenharmony_ci 4583d8536b4Sopenharmony_ci if (mutex->handle == _MUX_INVALID_HANDLE) { 4593d8536b4Sopenharmony_ci return EINVAL; 4603d8536b4Sopenharmony_ci } 4613d8536b4Sopenharmony_ci 4623d8536b4Sopenharmony_ci ret = MuxPostForPosix(mutex); 4633d8536b4Sopenharmony_ci 4643d8536b4Sopenharmony_ci return MapError(ret); 4653d8536b4Sopenharmony_ci} 4663d8536b4Sopenharmony_ci 467