1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "los_iar_tls.h"
33 #include <stdio.h>
34 #include "los_task.h"
35 #include "los_mux.h"
36 #include "los_memory.h"
37
38 /* IAR version is less than 8. */
39 #if (__VER__ < 8000000)
__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY * symbp)40 void __DLIB_TLS_MEMORY *__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY *symbp)
41 {
42 if (!LOS_TaskIsRuning()) {
43 CHAR _DLIB_TLS_MEMORY *tlsAreaPtr = (char _DLIB_TLS_MEMORY *)__segment_begin("__DLIB_PERTHREAD");
44 tlsAreaPtr += __IAR_DLIB_PERTHREAD_SYMBOL_OFFSET(symbp);
45 return (void __DLIB_TLS_MEMORY *)tlsAreaPtr;
46 } else {
47 UINT32 taskID = LOS_CurTaskIDGet();
48 LosTaskCB *task = OS_TCB_FROM_TID(taskID);
49 if (task->iarTlsArea == NULL) {
50 task->iarTlsArea = __iar_dlib_perthread_allocate();
51 }
52 return (void __DLIB_TLS_MEMORY *)task->iarTlsArea;
53 }
54 }
55
56 #else /* IAR version 8 or above. */
57 #pragma section = "__iar_tls$$DATA"
__aeabi_read_tp(void)58 void *__aeabi_read_tp(void)
59 {
60 if (!LOS_TaskIsRunning()) {
61 return __section_begin("__iar_tls$$DATA");
62 } else {
63 UINT32 taskID = LOS_CurTaskIDGet();
64 LosTaskCB *task = OS_TCB_FROM_TID(taskID);
65 if (task->iarTlsArea == NULL) {
66 task->iarTlsArea = IarPerThreadTlsAreaAllocate();
67 }
68 return task->iarTlsArea;
69 }
70 }
71
IarPerThreadTlsAreaAllocate(void)72 void *IarPerThreadTlsAreaAllocate(void)
73 {
74 UINT32 tlsAreaSize = __iar_tls_size();
75 VOID *tlsAreaPtr = LOS_MemAlloc(m_aucSysMem0, tlsAreaSize);
76 if (tlsAreaPtr == NULL) {
77 return NULL;
78 }
79
80 __iar_tls_init(tlsAreaPtr);
81 return tlsAreaPtr;
82 }
83
IarPerThreadTlsAreaDeallocate(void * tlsArea)84 void IarPerThreadTlsAreaDeallocate(void *tlsArea)
85 {
86 __call_thread_dtors();
87 LOS_MemFree(m_aucSysMem0, tlsArea);
88 }
89 #endif
90
91 #ifndef _MAX_LOCK
92 #define _MAX_LOCK 4
93 #endif
94
95 #ifndef _MAX_FLOCK
96 #define _MAX_FLOCK FOPEN_MAX
97 #endif
98
99 struct IarMutexInfo {
100 UINT32 muxID;
101 BOOL usedFlag;
102 };
103
104 STATIC struct IarMutexInfo g_iarSysMutex[_MAX_LOCK] = {0};
105 STATIC struct IarMutexInfo g_iarFileMutex[_MAX_FLOCK] = {0};
106
IarMtxCreate(struct IarMutexInfo * mutexArray,UINT32 size)107 STATIC __iar_Rmtx IarMtxCreate(struct IarMutexInfo *mutexArray, UINT32 size)
108 {
109 UINT32 i;
110
111 for (i = 0; i < size; i++) {
112 if (mutexArray[i].usedFlag == FALSE) {
113 UINT32 ret = LOS_MuxCreate(&mutexArray[i].muxID);
114 if (ret == LOS_OK) {
115 mutexArray[i].usedFlag = TRUE;
116 return (__iar_Rmtx)&mutexArray[i];
117 } else {
118 break;
119 }
120 }
121 }
122
123 return NULL;
124 }
125
__iar_system_Mtxinit(__iar_Rmtx * m)126 void __iar_system_Mtxinit(__iar_Rmtx *m)
127 {
128 if (m == NULL) {
129 return;
130 }
131
132 *m = IarMtxCreate(g_iarSysMutex, _MAX_LOCK);
133 }
134
__iar_system_Mtxdst(__iar_Rmtx * m)135 void __iar_system_Mtxdst(__iar_Rmtx *m)
136 {
137 if (m == NULL) {
138 return;
139 }
140 struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
141
142 (void)LOS_MuxDelete(muxInfo->muxID);
143 muxInfo->usedFlag = FALSE;
144 *m = (__iar_Rmtx)NULL;
145 }
146
__iar_system_Mtxlock(__iar_Rmtx * m)147 void __iar_system_Mtxlock(__iar_Rmtx *m)
148 {
149 if (m == NULL) {
150 return;
151 }
152 struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
153
154 if (LOS_TaskIsRunning()) {
155 (void)LOS_MuxPend(muxInfo->muxID, LOS_WAIT_FOREVER);
156 }
157 }
158
__iar_system_Mtxunlock(__iar_Rmtx * m)159 void __iar_system_Mtxunlock(__iar_Rmtx *m)
160 {
161 if (m == NULL) {
162 return;
163 }
164 struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
165
166 if (LOS_TaskIsRunning()) {
167 (void)LOS_MuxPost(muxInfo->muxID);
168 }
169 }
170
__iar_file_Mtxinit(__iar_Rmtx * m)171 void __iar_file_Mtxinit(__iar_Rmtx *m)
172 {
173 if (m == NULL) {
174 return;
175 }
176
177 *m = IarMtxCreate(g_iarFileMutex, _MAX_FLOCK);
178 }
179
__iar_file_Mtxdst(__iar_Rmtx * m)180 void __iar_file_Mtxdst(__iar_Rmtx *m)
181 {
182 if (m == NULL) {
183 return;
184 }
185 struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
186
187 (void)LOS_MuxDelete(muxInfo->muxID);
188 muxInfo->usedFlag = FALSE;
189 *m = (__iar_Rmtx)NULL;
190 }
191
__iar_file_Mtxlock(__iar_Rmtx * m)192 void __iar_file_Mtxlock(__iar_Rmtx *m)
193 {
194 if (m == NULL) {
195 return;
196 }
197 struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
198
199 if (LOS_TaskIsRunning()) {
200 (void)LOS_MuxPend(muxInfo->muxID, LOS_WAIT_FOREVER);
201 }
202 }
203
__iar_file_Mtxunlock(__iar_Rmtx * m)204 void __iar_file_Mtxunlock(__iar_Rmtx *m)
205 {
206 if (m == NULL) {
207 return;
208 }
209 struct IarMutexInfo *muxInfo = (struct IarMutexInfo *)*m;
210
211 if (LOS_TaskIsRunning()) {
212 (void)LOS_MuxPost(muxInfo->muxID);
213 }
214 }
215