Merge pull request #6973 from OpenNuvoton/nuvoton_armc6_thread_safe

Support thread-safety with ARMC6
pull/7296/head
Cruz Monrreal 2018-06-21 17:39:15 -05:00 committed by GitHub
commit aa25b1d0ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 3 deletions

View File

@ -423,6 +423,65 @@ void __rt_entry (void) {
mbed_start_main();
}
/* Move all code here from RTX code base (rtx_lib.c) and do some modifications:
*
* 1. _mutex_initialize/_mutex_free are re-implemented to meet Mbed.
* 2. All _mutex_* functions are declared with '__USED' to avoid excluded by linker.
*/
#if defined(RTX_NO_MULTITHREAD_CLIB)
#define LIBSPACE_SIZE 96
//lint -esym(714,__user_perthread_libspace,_mutex_*) "Referenced by C library"
//lint -esym(765,__user_perthread_libspace,_mutex_*) "Global scope"
//lint -esym(9003, os_libspace*) "variables 'os_libspace*' defined at module scope"
// Memory for libspace
static uint32_t os_libspace[OS_THREAD_LIBSPACE_NUM+1][LIBSPACE_SIZE/4] \
__attribute__((section(".bss.os.libspace")));
// Thread IDs for libspace
static osThreadId_t os_libspace_id[OS_THREAD_LIBSPACE_NUM] \
__attribute__((section(".bss.os.libspace")));
// Check if Kernel has been started
static uint32_t os_kernel_is_active (void) {
static uint8_t os_kernel_active = 0U;
if (os_kernel_active == 0U) {
if (osKernelGetState() > osKernelReady) {
os_kernel_active = 1U;
}
}
return (uint32_t)os_kernel_active;
}
// Provide libspace for current thread
void *__user_perthread_libspace (void) {
osThreadId_t id;
uint32_t n;
if (os_kernel_is_active() != 0U) {
id = osThreadGetId();
for (n = 0U; n < (uint32_t)OS_THREAD_LIBSPACE_NUM; n++) {
if (os_libspace_id[n] == NULL) {
os_libspace_id[n] = id;
}
if (os_libspace_id[n] == id) {
break;
}
}
if (n == (uint32_t)OS_THREAD_LIBSPACE_NUM) {
(void)osRtxErrorNotify(osRtxErrorClibSpace, id);
}
} else {
n = OS_THREAD_LIBSPACE_NUM;
}
//lint -e{9087} "cast between pointers to different object types"
return (void *)&os_libspace[n][0];
}
/* ARM toolchain requires dynamically created mutexes to enforce thread safety. There's
up to 8 static mutexes, protecting atexit, signalinit, stdin, stdout, stderr, stream_list,
fp_trap_init and the heap. Additionally for each call to fopen one extra mutex will be
@ -438,8 +497,13 @@ typedef void *mutex;
#define OS_MUTEX_STATIC_NUM 8
mutex _static_mutexes[OS_MUTEX_STATIC_NUM] = {NULL};
mbed_rtos_storage_mutex_t _static_mutexes_mem[OS_MUTEX_STATIC_NUM] = {NULL};
int _mutex_initialize(mutex *m)
//lint -save "Function prototypes defined in C library"
//lint -e970 "Use of 'int' outside of a typedef"
//lint -e818 "Pointer 'm' could be declared as pointing to const"
/* Initialize mutex */
__USED int _mutex_initialize(mutex *m)
{
osMutexAttr_t attr;
memset(&attr, 0, sizeof(attr));
@ -485,7 +549,22 @@ int _mutex_initialize(mutex *m)
return 1;
}
void _mutex_free(mutex *m) {
/* Acquire mutex */
__USED void _mutex_acquire(mutex *m) {
if (os_kernel_is_active() != 0U) {
(void)osMutexAcquire(*m, osWaitForever);
}
}
/* Release mutex */
__USED void _mutex_release(mutex *m) {
if (os_kernel_is_active() != 0U) {
(void)osMutexRelease(*m);
}
}
/* Free mutex */
__USED void _mutex_free(mutex *m) {
mutex *slot = NULL;
core_util_critical_section_enter();
for (int i = 0; i < OS_MUTEX_STATIC_NUM; i++) {
@ -507,6 +586,7 @@ void _mutex_free(mutex *m) {
}
#endif /* RTX_NO_MULTITHREAD_CLIB */
#endif /* ARMC */
#elif defined (__GNUC__) /******************** GCC ********************/

View File

@ -70,4 +70,8 @@
#define OS_IDLE_THREAD_TZ_MOD_ID 1
#define OS_TIMER_THREAD_TZ_MOD_ID 1
// Don't adopt default multi-thread support for ARM/ARMC6 toolchains from RTX code base.
// Provide Mbed-specific instead.
#define RTX_NO_MULTITHREAD_CLIB
#endif /* MBED_RTX_CONF_H */