2 * FreeRTOS SMP Kernel V202110.00
3 * Copyright (C) 2020 Synopsys, Inc. or its affiliates. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 * this software and associated documentation files (the "Software"), to deal in
7 * the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * https://www.FreeRTOS.org
23 * https://github.com/FreeRTOS
39 #include "arc/arc_exception.h"
40 #include "embARC_toolchain.h"
41 #include "embARC_debug.h"
43 #ifdef ENABLE_FREERTOS_TLS_DEBUG
44 #define TLS_DEBUG( fmt, ... ) EMBARC_PRINTF( fmt, ## __VA_ARGS__ )
46 #define TLS_DEBUG( fmt, ... )
50 * Runtime routines to execute constructors and
51 * destructors for task local storage.
53 extern void __mw_run_tls_dtor();
54 extern void __mw_run_tls_ctor();
56 extern uint32_t exc_nest_count;
59 * Linker generated symbols to mark .tls section addresses
60 * first byte .. last byte
62 extern char _ftls[], _etls[];
66 void executable_requires_tls_section( void )
80 #pragma off_inline(executable_requires_tls_section);
81 #pragma alias(executable_requires_tls_section, "executable_requires_.tls_section");
83 static void * init_task_tls( void )
85 uint32_t len = ( uint32_t ) ( _etls - _ftls );
88 #if FREERTOS_HEAP_SEL == 3
89 #warning "FreeRTOS TLS support is not compatible with heap 3 solution(FREERTOS_HEAP_SEL=3)!"
90 #warning "You can change FREERTOS_HEAP_SEL in freertos.mk to select other heap solution."
92 tls = pvPortMalloc( len );
97 TLS_DEBUG( "Malloc task tls:%dbytes\r\n", len );
98 memcpy( tls, _ftls, len );
99 __mw_run_tls_ctor(); /* Run constructors */
105 static void free_task_tls( void * pxTCB )
107 TaskHandle_t task2free = ( TaskHandle_t ) pxTCB;
109 if( task2free != NULL )
111 void * tls = pvTaskGetThreadLocalStoragePointer( task2free, 0 );
115 TLS_DEBUG( "Free task tls\r\n" );
118 vTaskSetThreadLocalStoragePointer( task2free, 0, NULL );
123 void task_end_hook( void * pxTCB )
125 free_task_tls( pxTCB );
128 static void * get_isr_tls( void )
131 static int first = 1;
133 if( _Rarely( first ) )
136 __mw_run_tls_ctor(); /* Run constructors */
139 return ( void * ) _ftls;
141 #pragma off_inline(get_isr_tls)
143 static void * get_task_tls( void )
145 TaskHandle_t cur_task;
147 cur_task = xTaskGetCurrentTaskHandle();
149 if( cur_task == NULL )
151 return get_isr_tls();
154 void * tls = pvTaskGetThreadLocalStoragePointer( cur_task, 0 );
158 tls = init_task_tls();
162 vTaskSetThreadLocalStoragePointer( cur_task, 0, tls );
172 #pragma off_inline(get_task_tls)
174 #if _ARC /* for ARC XCALLs need to preserve flags */
175 extern void * _Preserve_flags _mwget_tls( void );
179 * Back end gens calls to find local data for this task
181 void * _mwget_tls( void )
183 if( _ftls == ( char * ) 0 )
185 executable_requires_tls_section();
188 if( exc_nest_count > 0 ) /* In ISR */
190 return get_isr_tls();
194 return get_task_tls();
199 /* simple interface of thread safe */
200 typedef xSemaphoreHandle _lock_t;
201 #if configUSE_RECURSIVE_MUTEXES != 1
202 #error "configUSE_RECURSIVE_MUTEXES in FreeRTOSConfig.h need to 1"
205 void _mwmutex_create( _lock_t * mutex_ptr )
207 *mutex_ptr = xSemaphoreCreateRecursiveMutex();
210 void _mwmutex_delete( _lock_t * mutex_ptr )
212 if( ( *mutex_ptr ) != NULL )
214 vSemaphoreDelete( *mutex_ptr );
218 void _mwmutex_lock( _lock_t mutex )
220 if( ( mutex ) != NULL )
222 while( xSemaphoreTakeRecursive( mutex, portMAX_DELAY ) != pdTRUE )
228 void _mwmutex_unlock( _lock_t mutex )
230 if( ( mutex ) != NULL )
232 xSemaphoreGiveRecursive( mutex );
236 #else /* if defined( __MW__ ) */