Merge pull request #5526 from geky/fix-armcc-fopen-mutex-malloc

Fixed mutex assert in armcc fopen and related memory leak
pull/5574/head^2
Jimmy Brisson 2017-11-27 10:37:14 -06:00 committed by GitHub
commit 33c972666c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 6 deletions

View File

@ -168,6 +168,7 @@
#include "cmsis_os2.h"
#include "mbed_toolchain.h"
#include "mbed_error.h"
#include "mbed_critical.h"
#if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ >= 8000000)
#include <DLib_Threads.h>
#endif
@ -423,6 +424,7 @@ void __rt_entry (void) {
}
typedef void *mutex;
mutex _static_mutexes[OS_MUTEX_NUM] = {NULL};
/* 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,
@ -441,9 +443,23 @@ int _mutex_initialize(mutex *m)
attr.name = "ARM toolchain mutex";
attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
*m = osMutexNew(&attr);
if (*m != NULL) {
return 1;
mutex *slot = NULL;
core_util_critical_section_enter();
for (int i = 0; i < OS_MUTEX_NUM; i++) {
if (_static_mutexes[i] == NULL) {
_static_mutexes[i] = (mutex)-1; // dummy value to reserve slot
slot = &_static_mutexes[i];
break;
}
}
core_util_critical_section_exit();
if (slot != NULL) {
*m = osMutexNew(&attr);
*slot = *m;
if (*m != NULL) {
return 1;
}
}
/* Mutex pool exhausted, try using HEAP */
@ -463,6 +479,28 @@ int _mutex_initialize(mutex *m)
return 1;
}
void _mutex_free(mutex *m) {
mutex *slot = NULL;
core_util_critical_section_enter();
for (int i = 0; i < OS_MUTEX_NUM; i++) {
if (_static_mutexes[i] == *m) {
slot = &_static_mutexes[i];
break;
}
}
core_util_critical_section_exit();
osMutexDelete(*m);
// if no slot reserved for mutex, must have been dynamically allocated
if (!slot) {
free(m);
} else {
*slot = NULL;
}
}
#endif /* ARMC */
#elif defined (__GNUC__) /******************** GCC ********************/

View File

@ -609,27 +609,33 @@ __WEAK int _mutex_initialize(mutex *m) {
}
// Acquire mutex
#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050
__USED
#endif
void _mutex_acquire(mutex *m);
void _mutex_acquire(mutex *m) {
__WEAK void _mutex_acquire(mutex *m) {
if (os_kernel_is_active()) {
osMutexAcquire(*m, osWaitForever);
}
}
// Release mutex
#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050
__USED
#endif
void _mutex_release(mutex *m);
void _mutex_release(mutex *m) {
__WEAK void _mutex_release(mutex *m) {
if (os_kernel_is_active()) {
osMutexRelease(*m);
}
}
// Free mutex
#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050
__USED
#endif
void _mutex_free(mutex *m);
void _mutex_free(mutex *m) {
__WEAK void _mutex_free(mutex *m) {
osMutexDelete(*m);
}