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 "los_iar_tls.h"
333d8536b4Sopenharmony_ci#include <stdio.h>
343d8536b4Sopenharmony_ci#include "los_task.h"
353d8536b4Sopenharmony_ci#include "los_mux.h"
363d8536b4Sopenharmony_ci#include "los_memory.h"
373d8536b4Sopenharmony_ci
383d8536b4Sopenharmony_ci/* IAR version is less than 8. */
393d8536b4Sopenharmony_ci#if (__VER__ < 8000000)
403d8536b4Sopenharmony_civoid __DLIB_TLS_MEMORY *__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY *symbp)
413d8536b4Sopenharmony_ci{
423d8536b4Sopenharmony_ci    if (!LOS_TaskIsRuning()) {
433d8536b4Sopenharmony_ci        CHAR _DLIB_TLS_MEMORY *tlsAreaPtr = (char _DLIB_TLS_MEMORY *)__segment_begin("__DLIB_PERTHREAD");
443d8536b4Sopenharmony_ci        tlsAreaPtr += __IAR_DLIB_PERTHREAD_SYMBOL_OFFSET(symbp);
453d8536b4Sopenharmony_ci        return (void __DLIB_TLS_MEMORY *)tlsAreaPtr;
463d8536b4Sopenharmony_ci    } else {
473d8536b4Sopenharmony_ci        UINT32 taskID = LOS_CurTaskIDGet();
483d8536b4Sopenharmony_ci        LosTaskCB *task = OS_TCB_FROM_TID(taskID);
493d8536b4Sopenharmony_ci        if (task->iarTlsArea == NULL) {
503d8536b4Sopenharmony_ci            task->iarTlsArea = __iar_dlib_perthread_allocate();
513d8536b4Sopenharmony_ci        }
523d8536b4Sopenharmony_ci        return (void __DLIB_TLS_MEMORY *)task->iarTlsArea;
533d8536b4Sopenharmony_ci    }
543d8536b4Sopenharmony_ci}
553d8536b4Sopenharmony_ci
563d8536b4Sopenharmony_ci#else /* IAR version 8 or above. */
573d8536b4Sopenharmony_ci#pragma section = "__iar_tls$$DATA"
583d8536b4Sopenharmony_civoid *__aeabi_read_tp(void)
593d8536b4Sopenharmony_ci{
603d8536b4Sopenharmony_ci    if (!LOS_TaskIsRunning()) {
613d8536b4Sopenharmony_ci        return __section_begin("__iar_tls$$DATA");
623d8536b4Sopenharmony_ci    } else {
633d8536b4Sopenharmony_ci        UINT32 taskID = LOS_CurTaskIDGet();
643d8536b4Sopenharmony_ci        LosTaskCB *task = OS_TCB_FROM_TID(taskID);
653d8536b4Sopenharmony_ci        if (task->iarTlsArea == NULL) {
663d8536b4Sopenharmony_ci            task->iarTlsArea = IarPerThreadTlsAreaAllocate();
673d8536b4Sopenharmony_ci        }
683d8536b4Sopenharmony_ci        return task->iarTlsArea;
693d8536b4Sopenharmony_ci    }
703d8536b4Sopenharmony_ci}
713d8536b4Sopenharmony_ci
723d8536b4Sopenharmony_civoid *IarPerThreadTlsAreaAllocate(void)
733d8536b4Sopenharmony_ci{
743d8536b4Sopenharmony_ci    UINT32 tlsAreaSize = __iar_tls_size();
753d8536b4Sopenharmony_ci    VOID *tlsAreaPtr = LOS_MemAlloc(m_aucSysMem0, tlsAreaSize);
763d8536b4Sopenharmony_ci    if (tlsAreaPtr == NULL) {
773d8536b4Sopenharmony_ci        return NULL;
783d8536b4Sopenharmony_ci    }
793d8536b4Sopenharmony_ci
803d8536b4Sopenharmony_ci    __iar_tls_init(tlsAreaPtr);
813d8536b4Sopenharmony_ci    return tlsAreaPtr;
823d8536b4Sopenharmony_ci}
833d8536b4Sopenharmony_ci
843d8536b4Sopenharmony_civoid IarPerThreadTlsAreaDeallocate(void *tlsArea)
853d8536b4Sopenharmony_ci{
863d8536b4Sopenharmony_ci    __call_thread_dtors();
873d8536b4Sopenharmony_ci    LOS_MemFree(m_aucSysMem0, tlsArea);
883d8536b4Sopenharmony_ci}
893d8536b4Sopenharmony_ci#endif
903d8536b4Sopenharmony_ci
913d8536b4Sopenharmony_ci#ifndef _MAX_LOCK
923d8536b4Sopenharmony_ci#define _MAX_LOCK       4
933d8536b4Sopenharmony_ci#endif
943d8536b4Sopenharmony_ci
953d8536b4Sopenharmony_ci#ifndef _MAX_FLOCK
963d8536b4Sopenharmony_ci#define _MAX_FLOCK      FOPEN_MAX
973d8536b4Sopenharmony_ci#endif
983d8536b4Sopenharmony_ci
993d8536b4Sopenharmony_cistruct IarMutexInfo {
1003d8536b4Sopenharmony_ci    UINT32 muxID;
1013d8536b4Sopenharmony_ci    BOOL usedFlag;
1023d8536b4Sopenharmony_ci};
1033d8536b4Sopenharmony_ci
1043d8536b4Sopenharmony_ciSTATIC struct IarMutexInfo g_iarSysMutex[_MAX_LOCK] = {0};
1053d8536b4Sopenharmony_ciSTATIC struct IarMutexInfo g_iarFileMutex[_MAX_FLOCK] = {0};
1063d8536b4Sopenharmony_ci
1073d8536b4Sopenharmony_ciSTATIC __iar_Rmtx IarMtxCreate(struct IarMutexInfo *mutexArray, UINT32 size)
1083d8536b4Sopenharmony_ci{
1093d8536b4Sopenharmony_ci    UINT32 i;
1103d8536b4Sopenharmony_ci
1113d8536b4Sopenharmony_ci    for (i = 0; i < size; i++) {
1123d8536b4Sopenharmony_ci        if (mutexArray[i].usedFlag == FALSE) {
1133d8536b4Sopenharmony_ci            UINT32 ret = LOS_MuxCreate(&mutexArray[i].muxID);
1143d8536b4Sopenharmony_ci            if (ret == LOS_OK) {
1153d8536b4Sopenharmony_ci                mutexArray[i].usedFlag = TRUE;
1163d8536b4Sopenharmony_ci                return (__iar_Rmtx)&mutexArray[i];
1173d8536b4Sopenharmony_ci            } else {
1183d8536b4Sopenharmony_ci                break;
1193d8536b4Sopenharmony_ci            }
1203d8536b4Sopenharmony_ci        }
1213d8536b4Sopenharmony_ci    }
1223d8536b4Sopenharmony_ci
1233d8536b4Sopenharmony_ci    return NULL;
1243d8536b4Sopenharmony_ci}
1253d8536b4Sopenharmony_ci
1263d8536b4Sopenharmony_civoid __iar_system_Mtxinit(__iar_Rmtx *m)
1273d8536b4Sopenharmony_ci{
1283d8536b4Sopenharmony_ci    if (m == NULL) {
1293d8536b4Sopenharmony_ci        return;
1303d8536b4Sopenharmony_ci    }
1313d8536b4Sopenharmony_ci
1323d8536b4Sopenharmony_ci    *m = IarMtxCreate(g_iarSysMutex, _MAX_LOCK);
1333d8536b4Sopenharmony_ci}
1343d8536b4Sopenharmony_ci
1353d8536b4Sopenharmony_civoid __iar_system_Mtxdst(__iar_Rmtx *m)
1363d8536b4Sopenharmony_ci{
1373d8536b4Sopenharmony_ci    if (m == NULL) {
1383d8536b4Sopenharmony_ci        return;
1393d8536b4Sopenharmony_ci    }
1403d8536b4Sopenharmony_ci    struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
1413d8536b4Sopenharmony_ci
1423d8536b4Sopenharmony_ci    (void)LOS_MuxDelete(muxInfo->muxID);
1433d8536b4Sopenharmony_ci    muxInfo->usedFlag = FALSE;
1443d8536b4Sopenharmony_ci    *m = (__iar_Rmtx)NULL;
1453d8536b4Sopenharmony_ci}
1463d8536b4Sopenharmony_ci
1473d8536b4Sopenharmony_civoid __iar_system_Mtxlock(__iar_Rmtx *m)
1483d8536b4Sopenharmony_ci{
1493d8536b4Sopenharmony_ci    if (m == NULL) {
1503d8536b4Sopenharmony_ci        return;
1513d8536b4Sopenharmony_ci    }
1523d8536b4Sopenharmony_ci    struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
1533d8536b4Sopenharmony_ci
1543d8536b4Sopenharmony_ci    if (LOS_TaskIsRunning()) {
1553d8536b4Sopenharmony_ci        (void)LOS_MuxPend(muxInfo->muxID, LOS_WAIT_FOREVER);
1563d8536b4Sopenharmony_ci    }
1573d8536b4Sopenharmony_ci}
1583d8536b4Sopenharmony_ci
1593d8536b4Sopenharmony_civoid __iar_system_Mtxunlock(__iar_Rmtx *m)
1603d8536b4Sopenharmony_ci{
1613d8536b4Sopenharmony_ci    if (m == NULL) {
1623d8536b4Sopenharmony_ci        return;
1633d8536b4Sopenharmony_ci    }
1643d8536b4Sopenharmony_ci    struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
1653d8536b4Sopenharmony_ci
1663d8536b4Sopenharmony_ci    if (LOS_TaskIsRunning()) {
1673d8536b4Sopenharmony_ci        (void)LOS_MuxPost(muxInfo->muxID);
1683d8536b4Sopenharmony_ci    }
1693d8536b4Sopenharmony_ci}
1703d8536b4Sopenharmony_ci
1713d8536b4Sopenharmony_civoid __iar_file_Mtxinit(__iar_Rmtx *m)
1723d8536b4Sopenharmony_ci{
1733d8536b4Sopenharmony_ci    if (m == NULL) {
1743d8536b4Sopenharmony_ci        return;
1753d8536b4Sopenharmony_ci    }
1763d8536b4Sopenharmony_ci
1773d8536b4Sopenharmony_ci    *m = IarMtxCreate(g_iarFileMutex, _MAX_FLOCK);
1783d8536b4Sopenharmony_ci}
1793d8536b4Sopenharmony_ci
1803d8536b4Sopenharmony_civoid __iar_file_Mtxdst(__iar_Rmtx *m)
1813d8536b4Sopenharmony_ci{
1823d8536b4Sopenharmony_ci    if (m == NULL) {
1833d8536b4Sopenharmony_ci        return;
1843d8536b4Sopenharmony_ci    }
1853d8536b4Sopenharmony_ci    struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
1863d8536b4Sopenharmony_ci
1873d8536b4Sopenharmony_ci    (void)LOS_MuxDelete(muxInfo->muxID);
1883d8536b4Sopenharmony_ci    muxInfo->usedFlag = FALSE;
1893d8536b4Sopenharmony_ci    *m = (__iar_Rmtx)NULL;
1903d8536b4Sopenharmony_ci}
1913d8536b4Sopenharmony_ci
1923d8536b4Sopenharmony_civoid __iar_file_Mtxlock(__iar_Rmtx *m)
1933d8536b4Sopenharmony_ci{
1943d8536b4Sopenharmony_ci    if (m == NULL) {
1953d8536b4Sopenharmony_ci        return;
1963d8536b4Sopenharmony_ci    }
1973d8536b4Sopenharmony_ci    struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
1983d8536b4Sopenharmony_ci
1993d8536b4Sopenharmony_ci    if (LOS_TaskIsRunning()) {
2003d8536b4Sopenharmony_ci        (void)LOS_MuxPend(muxInfo->muxID, LOS_WAIT_FOREVER);
2013d8536b4Sopenharmony_ci    }
2023d8536b4Sopenharmony_ci}
2033d8536b4Sopenharmony_ci
2043d8536b4Sopenharmony_civoid __iar_file_Mtxunlock(__iar_Rmtx *m)
2053d8536b4Sopenharmony_ci{
2063d8536b4Sopenharmony_ci    if (m == NULL) {
2073d8536b4Sopenharmony_ci        return;
2083d8536b4Sopenharmony_ci    }
2093d8536b4Sopenharmony_ci    struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
2103d8536b4Sopenharmony_ci
2113d8536b4Sopenharmony_ci    if (LOS_TaskIsRunning()) {
2123d8536b4Sopenharmony_ci        (void)LOS_MuxPost(muxInfo->muxID);
2133d8536b4Sopenharmony_ci    }
2143d8536b4Sopenharmony_ci}
215