feature: 支持IAR C++ thread_local特性

在需要IAR的thread_local特性时,在targets_config.h中包含los_iar_tls.h,覆盖los_config.h的默认定义,使能该特性。

close #I4PTVZ

Signed-off-by: JerryH <huangjieliang@huawei.com>
Change-Id: I92d3f960555f95cb3618dd5e3915824105eb13a4
This commit is contained in:
JerryH 2022-01-10 20:03:08 +08:00
parent 4a120d7533
commit b98aa4eacd
5 changed files with 300 additions and 0 deletions

View File

@ -0,0 +1,214 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_iar_tls.h"
#include <stdio.h>
#include "los_task.h"
#include "los_mux.h"
#include "los_memory.h"
/* IAR version is less than 8. */
#if (__VER__ < 8000000)
void __DLIB_TLS_MEMORY *__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY *symbp)
{
if (!LOS_TaskIsRuning()) {
CHAR _DLIB_TLS_MEMORY *tlsAreaPtr = (char _DLIB_TLS_MEMORY *)__segment_begin("__DLIB_PERTHREAD");
tlsAreaPtr += __IAR_DLIB_PERTHREAD_SYMBOL_OFFSET(symbp);
return (void __DLIB_TLS_MEMORY *)tlsAreaPtr;
} else {
UINT32 taskID = LOS_CurTaskIDGet();
LosTaskCB *task = OS_TCB_FROM_TID(taskID);
if (task->iarTlsArea == NULL) {
task->iarTlsArea = __iar_dlib_perthread_allocate();
}
return (void __DLIB_TLS_MEMORY *)task->iarTlsArea;
}
}
#else /* IAR version 8 or above. */
#pragma section="__iar_tls$$DATA"
void *__aeabi_read_tp(void)
{
if (!LOS_TaskIsRunning()) {
return __section_begin("__iar_tls$$DATA");
} else {
UINT32 taskID = LOS_CurTaskIDGet();
LosTaskCB *task = OS_TCB_FROM_TID(taskID);
if (task->iarTlsArea == NULL) {
task->iarTlsArea = IarPerThreadTlsAreaAllocate();
}
return task->iarTlsArea;
}
}
void *IarPerThreadTlsAreaAllocate(void)
{
UINT32 tlsAreaSize = __iar_tls_size();
VOID *tlsAreaPtr = LOS_MemAlloc(m_aucSysMem0, tlsAreaSize);
if (tlsAreaPtr == NULL) {
return NULL;
}
__iar_tls_init(tlsAreaPtr);
return tlsAreaPtr;
}
void IarPerThreadTlsAreaDeallocate(void *tlsArea)
{
__call_thread_dtors();
LOS_MemFree(m_aucSysMem0, tlsArea);
}
#endif
#ifndef _MAX_LOCK
#define _MAX_LOCK 4
#endif
#ifndef _MAX_FLOCK
#define _MAX_FLOCK FOPEN_MAX
#endif
struct IarMutexInfo {
UINT32 muxID;
BOOL usedFlag;
};
STATIC struct IarMutexInfo g_iarSysMutex[_MAX_LOCK] = {0};
STATIC struct IarMutexInfo g_iarFileMutex[_MAX_FLOCK] = {0};
STATIC __iar_Rmtx IarMtxCreate(struct IarMutexInfo *mutexArray, UINT32 size)
{
UINT32 i;
for (i = 0; i < size; i++) {
if (mutexArray[i].usedFlag == FALSE) {
UINT32 ret = LOS_MuxCreate(&mutexArray[i].muxID);
if (ret == LOS_OK) {
mutexArray[i].usedFlag = TRUE;
return (__iar_Rmtx)&mutexArray[i];
} else {
break;
}
}
}
return NULL;
}
void __iar_system_Mtxinit(__iar_Rmtx *m)
{
if (m == NULL) {
return;
}
*m = IarMtxCreate(g_iarSysMutex, _MAX_LOCK);
}
void __iar_system_Mtxdst(__iar_Rmtx *m)
{
if (m == NULL) {
return;
}
struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
(void)LOS_MuxDelete(muxInfo->muxID);
muxInfo->usedFlag = FALSE;
*m = (__iar_Rmtx)NULL;
}
void __iar_system_Mtxlock(__iar_Rmtx *m)
{
if (m == NULL) {
return;
}
struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
if (LOS_TaskIsRunning()) {
(void)LOS_MuxPend(muxInfo->muxID, LOS_WAIT_FOREVER);
}
}
void __iar_system_Mtxunlock(__iar_Rmtx *m)
{
if (m == NULL) {
return;
}
struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
if (LOS_TaskIsRunning()) {
(void)LOS_MuxPost(muxInfo->muxID);
}
}
void __iar_file_Mtxinit(__iar_Rmtx *m)
{
if (m == NULL) {
return;
}
*m = IarMtxCreate(g_iarFileMutex, _MAX_FLOCK);
}
void __iar_file_Mtxdst(__iar_Rmtx *m)
{
if (m == NULL) {
return;
}
struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
(void)LOS_MuxDelete(muxInfo->muxID);
muxInfo->usedFlag = FALSE;
*m = (__iar_Rmtx)NULL;
}
void __iar_file_Mtxlock(__iar_Rmtx *m)
{
if (m == NULL) {
return;
}
struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
if (LOS_TaskIsRunning()) {
(void)LOS_MuxPend(muxInfo->muxID, LOS_WAIT_FOREVER);
}
}
void __iar_file_Mtxunlock(__iar_Rmtx *m)
{
if (m == NULL) {
return;
}
struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
if (LOS_TaskIsRunning()) {
(void)LOS_MuxPost(muxInfo->muxID);
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_compiler.h"
/* Using task extended field to realize IAR TLS function in target_config.h include this header file. */
#define LOSCFG_TASK_STRUCT_EXTENSION VOID *iarTlsArea;
#if (__VER__ < 8000000)
#include <yvals.h>
#define LOSCFG_TASK_CREATE_EXTENSION_HOOK(taskCB)
#define LOSCFG_TASK_DELETE_EXTENSION_HOOK(taskCB) do { \
if (taskCB->iarTlsArea != NULL) { \
__iar_dlib_perthread_deallocate(taskCB->iarTlsArea); \
taskCB->iarTlsArea = NULL; \
} \
} while (0);
#else
#include <Dlib_threads.h>
void *IarPerThreadTlsAreaAllocate(void);
void IarPerThreadTlsAreaDeallocate(void *tlsArea);
#define LOSCFG_TASK_CREATE_EXTENSION_HOOK(taskCB)
#define LOSCFG_TASK_DELETE_EXTENSION_HOOK(taskCB) do { \
if (taskCB->iarTlsArea != NULL) { \
IarPerThreadTlsAreaDeallocate(taskCB->iarTlsArea); \
taskCB->iarTlsArea = NULL; \
} \
} while (0);
#endif
/* In the main initialization phase, the macro should be called. */
#define IAR_INIT_LOCKS() __iar_Initlocks()

View File

@ -635,6 +635,20 @@ extern UINT8 *m_aucSysMem0;
#define LOSCFG_ARCH_HWI_VECTOR_ALIGN 0x100
#endif
/**
* @ingroup los_config
* Task extension field additional functions, such as IAR TLS.
*/
#ifndef LOSCFG_TASK_STRUCT_EXTENSION
#define LOSCFG_TASK_STRUCT_EXTENSION
#endif
#ifndef LOSCFG_TASK_CREATE_EXTENSION_HOOK
#define LOSCFG_TASK_CREATE_EXTENSION_HOOK(taskCB)
#endif
#ifndef LOSCFG_TASK_DELETE_EXTENSION_HOOK
#define LOSCFG_TASK_DELETE_EXTENSION_HOOK(taskCB)
#endif
#ifdef __cplusplus
#if __cplusplus
}

View File

@ -1480,6 +1480,7 @@ typedef struct {
UINT32 eventMode; /**< Event mode */
VOID *msg; /**< Memory allocated to queues */
INT32 errorNo;
LOSCFG_TASK_STRUCT_EXTENSION /**< Task extension field */
} LosTaskCB;
typedef struct {

View File

@ -749,6 +749,9 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S
if (retVal != LOS_OK) {
return retVal;
}
LOSCFG_TASK_CREATE_EXTENSION_HOOK(taskCB);
#if (LOSCFG_BASE_CORE_CPUP == 1)
intSave = LOS_IntLock();
g_cpup[taskCB->taskID].cpupID = taskCB->taskID;
@ -1084,6 +1087,9 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID)
// Ignore the return code when matching CSEC rule 6.6(4).
(VOID)memset_s((VOID *)&g_cpup[taskCB->taskID], sizeof(OsCpupCB), 0, sizeof(OsCpupCB));
#endif
LOSCFG_TASK_DELETE_EXTENSION_HOOK(taskCB);
if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
if (!(taskCB->taskStatus & OS_TASK_STATUS_EXIT)) {
taskCB->taskStatus = OS_TASK_STATUS_UNUSED;