1 /* 2 * FreeRTOS Kernel V11.0.1 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 /*----------------------------------------------------------------------------- */ _Mtxinit(_Rmtx * mtx)52 void _Mtxinit( _Rmtx * mtx ) 53 { 54 *mtx = xSemaphoreCreateRecursiveMutex(); 55 } 56 57 /*----------------------------------------------------------------------------- */ 58 /* Destroy lock. */ 59 /*----------------------------------------------------------------------------- */ _Mtxdst(_Rmtx * mtx)60 void _Mtxdst( _Rmtx * mtx ) 61 { 62 if( ( mtx != NULL ) && ( *mtx != NULL ) ) 63 { 64 vSemaphoreDelete( *mtx ); 65 } 66 } 67 68 /*----------------------------------------------------------------------------- */ 69 /* Lock. */ 70 /*----------------------------------------------------------------------------- */ _Mtxlock(_Rmtx * mtx)71 void _Mtxlock( _Rmtx * mtx ) 72 { 73 if( ( mtx != NULL ) && ( *mtx != NULL ) ) 74 { 75 xSemaphoreTakeRecursive( *mtx, portMAX_DELAY ); 76 } 77 } 78 79 /*----------------------------------------------------------------------------- */ 80 /* Unlock. */ 81 /*----------------------------------------------------------------------------- */ _Mtxunlock(_Rmtx * mtx)82 void _Mtxunlock( _Rmtx * mtx ) 83 { 84 if( ( mtx != NULL ) && ( *mtx != NULL ) ) 85 { 86 xSemaphoreGiveRecursive( *mtx ); 87 } 88 } 89 90 /*----------------------------------------------------------------------------- */ 91 /* Called by malloc() to allocate blocks of memory from the heap. */ 92 /*----------------------------------------------------------------------------- */ _sbrk_r(struct _reent * reent,int32_t incr)93 void * _sbrk_r( struct _reent * reent, 94 int32_t incr ) 95 { 96 extern char _end; 97 extern char _heap_sentry; 98 static char * _heap_sentry_ptr = &_heap_sentry; 99 static char * heap_ptr; 100 char * base; 101 102 if( !heap_ptr ) 103 { 104 heap_ptr = ( char * ) &_end; 105 } 106 107 base = heap_ptr; 108 109 if( heap_ptr + incr >= _heap_sentry_ptr ) 110 { 111 reent->_errno = ENOMEM; 112 return ( char * ) -1; 113 } 114 115 heap_ptr += incr; 116 return base; 117 } 118 119 /*----------------------------------------------------------------------------- */ 120 /* Global initialization for C library. */ 121 /*----------------------------------------------------------------------------- */ vPortClibInit(void)122 void vPortClibInit( void ) 123 { 124 } 125 126 /*----------------------------------------------------------------------------- */ 127 /* Per-thread cleanup stub provided for linking, does nothing. */ 128 /*----------------------------------------------------------------------------- */ _reclaim_reent(void * ptr)129 void _reclaim_reent( void * ptr ) 130 { 131 } 132 133 #endif /* XSHAL_CLIB == XTHAL_CLIB_XCLIB */ 134 135 #if XSHAL_CLIB == XTHAL_CLIB_NEWLIB 136 137 #include <errno.h> 138 #include <malloc.h> 139 #include <stdio.h> 140 #include <stdlib.h> 141 #include <string.h> 142 143 #include "semphr.h" 144 145 static SemaphoreHandle_t xClibMutex; 146 static uint32_t ulClibInitDone = 0; 147 148 /*----------------------------------------------------------------------------- */ 149 /* Get C library lock. */ 150 /*----------------------------------------------------------------------------- */ __malloc_lock(struct _reent * ptr)151 void __malloc_lock( struct _reent * ptr ) 152 { 153 if( !ulClibInitDone ) 154 { 155 return; 156 } 157 158 xSemaphoreTakeRecursive( xClibMutex, portMAX_DELAY ); 159 } 160 161 /*----------------------------------------------------------------------------- */ 162 /* Release C library lock. */ 163 /*----------------------------------------------------------------------------- */ __malloc_unlock(struct _reent * ptr)164 void __malloc_unlock( struct _reent * ptr ) 165 { 166 if( !ulClibInitDone ) 167 { 168 return; 169 } 170 171 xSemaphoreGiveRecursive( xClibMutex ); 172 } 173 174 /*----------------------------------------------------------------------------- */ 175 /* Lock for environment. Since we have only one global lock we can just call */ 176 /* the malloc() lock function. */ 177 /*----------------------------------------------------------------------------- */ __env_lock(struct _reent * ptr)178 void __env_lock( struct _reent * ptr ) 179 { 180 __malloc_lock( ptr ); 181 } 182 183 184 /*----------------------------------------------------------------------------- */ 185 /* Unlock environment. */ 186 /*----------------------------------------------------------------------------- */ __env_unlock(struct _reent * ptr)187 void __env_unlock( struct _reent * ptr ) 188 { 189 __malloc_unlock( ptr ); 190 } 191 192 /*----------------------------------------------------------------------------- */ 193 /* Called by malloc() to allocate blocks of memory from the heap. */ 194 /*----------------------------------------------------------------------------- */ _sbrk_r(struct _reent * reent,int32_t incr)195 void * _sbrk_r( struct _reent * reent, 196 int32_t incr ) 197 { 198 extern char _end; 199 extern char _heap_sentry; 200 static char * _heap_sentry_ptr = &_heap_sentry; 201 static char * heap_ptr; 202 char * base; 203 204 if( !heap_ptr ) 205 { 206 heap_ptr = ( char * ) &_end; 207 } 208 209 base = heap_ptr; 210 211 if( heap_ptr + incr >= _heap_sentry_ptr ) 212 { 213 reent->_errno = ENOMEM; 214 return ( char * ) -1; 215 } 216 217 heap_ptr += incr; 218 return base; 219 } 220 221 /*----------------------------------------------------------------------------- */ 222 /* Global initialization for C library. */ 223 /*----------------------------------------------------------------------------- */ vPortClibInit(void)224 void vPortClibInit( void ) 225 { 226 configASSERT( !ulClibInitDone ); 227 228 xClibMutex = xSemaphoreCreateRecursiveMutex(); 229 ulClibInitDone = 1; 230 } 231 232 #endif /* XSHAL_CLIB == XTHAL_CLIB_NEWLIB */ 233 234 #endif /* XT_USE_THREAD_SAFE_CLIB */ 235