xref: /Kernel-v10.6.2/portable/ThirdParty/XCC/Xtensa/portclib.c (revision ef7b253b56c9788077f5ecd6c9deb4021923d646)
1 /*
2  * FreeRTOS Kernel V10.6.2
3  * Copyright (C) 2015-2019 Cadence Design Systems, Inc.
4  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
5  *
6  * SPDX-License-Identifier: MIT
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy of
9  * this software and associated documentation files (the "Software"), to deal in
10  * the Software without restriction, including without limitation the rights to
11  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12  * the Software, and to permit persons to whom the Software is furnished to do so,
13  * subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in all
16  * copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * https://www.FreeRTOS.org
26  * https://github.com/FreeRTOS
27  *
28  */
29 
30 #include "FreeRTOS.h"
31 
32 #if XT_USE_THREAD_SAFE_CLIB
33 
34 #if XSHAL_CLIB == XTHAL_CLIB_XCLIB
35 
36 #include <errno.h>
37 #include <sys/reent.h>
38 
39 #include "semphr.h"
40 
41 typedef SemaphoreHandle_t       _Rmtx;
42 
43 //-----------------------------------------------------------------------------
44 //  Override this and set to nonzero to enable locking.
45 //-----------------------------------------------------------------------------
46 int32_t _xclib_use_mt = 1;
47 
48 
49 //-----------------------------------------------------------------------------
50 //  Init lock.
51 //-----------------------------------------------------------------------------
52 void
_Mtxinit(_Rmtx * mtx)53 _Mtxinit(_Rmtx * mtx)
54 {
55     *mtx = xSemaphoreCreateRecursiveMutex();
56 }
57 
58 //-----------------------------------------------------------------------------
59 //  Destroy lock.
60 //-----------------------------------------------------------------------------
61 void
_Mtxdst(_Rmtx * mtx)62 _Mtxdst(_Rmtx * mtx)
63 {
64     if ((mtx != NULL) && (*mtx != NULL)) {
65         vSemaphoreDelete(*mtx);
66     }
67 }
68 
69 //-----------------------------------------------------------------------------
70 //  Lock.
71 //-----------------------------------------------------------------------------
72 void
_Mtxlock(_Rmtx * mtx)73 _Mtxlock(_Rmtx * mtx)
74 {
75     if ((mtx != NULL) && (*mtx != NULL)) {
76         xSemaphoreTakeRecursive(*mtx, portMAX_DELAY);
77     }
78 }
79 
80 //-----------------------------------------------------------------------------
81 //  Unlock.
82 //-----------------------------------------------------------------------------
83 void
_Mtxunlock(_Rmtx * mtx)84 _Mtxunlock(_Rmtx * mtx)
85 {
86     if ((mtx != NULL) && (*mtx != NULL)) {
87         xSemaphoreGiveRecursive(*mtx);
88     }
89 }
90 
91 //-----------------------------------------------------------------------------
92 //  Called by malloc() to allocate blocks of memory from the heap.
93 //-----------------------------------------------------------------------------
94 void *
_sbrk_r(struct _reent * reent,int32_t incr)95 _sbrk_r (struct _reent * reent, int32_t incr)
96 {
97     extern char _end;
98     extern char _heap_sentry;
99     static char * _heap_sentry_ptr = &_heap_sentry;
100     static char * heap_ptr;
101     char * base;
102 
103     if (!heap_ptr)
104         heap_ptr = (char *) &_end;
105 
106     base = heap_ptr;
107     if (heap_ptr + incr >= _heap_sentry_ptr) {
108         reent->_errno = ENOMEM;
109         return (char *) -1;
110     }
111 
112     heap_ptr += incr;
113     return base;
114 }
115 
116 //-----------------------------------------------------------------------------
117 //  Global initialization for C library.
118 //-----------------------------------------------------------------------------
119 void
vPortClibInit(void)120 vPortClibInit(void)
121 {
122 }
123 
124 //-----------------------------------------------------------------------------
125 //  Per-thread cleanup stub provided for linking, does nothing.
126 //-----------------------------------------------------------------------------
127 void
_reclaim_reent(void * ptr)128 _reclaim_reent(void * ptr)
129 {
130 }
131 
132 #endif /* XSHAL_CLIB == XTHAL_CLIB_XCLIB */
133 
134 #if XSHAL_CLIB == XTHAL_CLIB_NEWLIB
135 
136 #include <errno.h>
137 #include <malloc.h>
138 #include <stdio.h>
139 #include <stdlib.h>
140 #include <string.h>
141 
142 #include "semphr.h"
143 
144 static SemaphoreHandle_t xClibMutex;
145 static uint32_t  ulClibInitDone = 0;
146 
147 //-----------------------------------------------------------------------------
148 //  Get C library lock.
149 //-----------------------------------------------------------------------------
150 void
__malloc_lock(struct _reent * ptr)151 __malloc_lock(struct _reent * ptr)
152 {
153     if (!ulClibInitDone)
154         return;
155 
156     xSemaphoreTakeRecursive(xClibMutex, portMAX_DELAY);
157 }
158 
159 //-----------------------------------------------------------------------------
160 //  Release C library lock.
161 //-----------------------------------------------------------------------------
162 void
__malloc_unlock(struct _reent * ptr)163 __malloc_unlock(struct _reent * ptr)
164 {
165     if (!ulClibInitDone)
166         return;
167 
168     xSemaphoreGiveRecursive(xClibMutex);
169 }
170 
171 //-----------------------------------------------------------------------------
172 //  Lock for environment. Since we have only one global lock we can just call
173 //  the malloc() lock function.
174 //-----------------------------------------------------------------------------
175 void
__env_lock(struct _reent * ptr)176 __env_lock(struct _reent * ptr)
177 {
178     __malloc_lock(ptr);
179 }
180 
181 
182 //-----------------------------------------------------------------------------
183 //  Unlock environment.
184 //-----------------------------------------------------------------------------
185 void
__env_unlock(struct _reent * ptr)186 __env_unlock(struct _reent * ptr)
187 {
188     __malloc_unlock(ptr);
189 }
190 
191 //-----------------------------------------------------------------------------
192 //  Called by malloc() to allocate blocks of memory from the heap.
193 //-----------------------------------------------------------------------------
194 void *
_sbrk_r(struct _reent * reent,int32_t incr)195 _sbrk_r (struct _reent * reent, int32_t incr)
196 {
197     extern char _end;
198     extern char _heap_sentry;
199     static char * _heap_sentry_ptr = &_heap_sentry;
200     static char * heap_ptr;
201     char * base;
202 
203     if (!heap_ptr)
204         heap_ptr = (char *) &_end;
205 
206     base = heap_ptr;
207     if (heap_ptr + incr >= _heap_sentry_ptr) {
208         reent->_errno = ENOMEM;
209         return (char *) -1;
210     }
211 
212     heap_ptr += incr;
213     return base;
214 }
215 
216 //-----------------------------------------------------------------------------
217 //  Global initialization for C library.
218 //-----------------------------------------------------------------------------
219 void
vPortClibInit(void)220 vPortClibInit(void)
221 {
222     configASSERT(!ulClibInitDone);
223 
224     xClibMutex = xSemaphoreCreateRecursiveMutex();
225     ulClibInitDone  = 1;
226 }
227 
228 #endif /* XSHAL_CLIB == XTHAL_CLIB_NEWLIB */
229 
230 #endif /* XT_USE_THREAD_SAFE_CLIB */
231