-
-
Save Xenoamor/cacf18cb19e2b260fe291b3474e1605d to your computer and use it in GitHub Desktop.
C++ embedded exception thread safety test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "FreeRTOS.h" | |
#include "task.h" | |
#include "semphr.h" | |
static TaskHandle_t xHandleTask1 = nullptr; | |
static TaskHandle_t xHandleTask2 = nullptr; | |
static SemaphoreHandle_t cxa_throw_mutex = nullptr; | |
static void toggle_blue_led(); | |
static void toggle_green_led(); | |
// Wrap the _cxa_begin_catch and _cxa_end_catch calls with a mutex | |
// This requires the following linker options: | |
// -Wl,--wrap=__cxa_begin_catch | |
// -Wl,--wrap=__cxa_end_catch | |
extern "C" void *__real___cxa_begin_catch(void *); | |
extern "C" void *__wrap___cxa_begin_catch(void *ptr) | |
{ | |
xSemaphoreTakeRecursive(cxa_throw_mutex, portMAX_DELAY); | |
return __real___cxa_begin_catch(ptr); | |
} | |
extern "C" void __real___cxa_end_catch(); | |
extern "C" void __wrap___cxa_end_catch() | |
{ | |
__real___cxa_end_catch(); | |
xSemaphoreGiveRecursive(cxa_throw_mutex); | |
} | |
void Task1(void *pvParameters) | |
{ | |
for (;;) | |
{ | |
try | |
{ | |
throw 5; | |
} | |
catch (int e) | |
{ | |
toggle_blue_led(); | |
} | |
try | |
{ | |
throw 10; | |
} | |
catch (int e) | |
{ | |
toggle_blue_led(); | |
} | |
} | |
} | |
void Task2(void *pvParameters) | |
{ | |
for (;;) | |
{ | |
try | |
{ | |
throw 5; | |
} | |
catch (int e) | |
{ | |
toggle_green_led(); | |
} | |
try | |
{ | |
throw 10; | |
} | |
catch (int e) | |
{ | |
toggle_green_led(); | |
} | |
} | |
} | |
int main() | |
{ | |
xTaskCreate(Task1, "Task1", 512, nullptr, 3, xHandleTask1); | |
xTaskCreate(Task2, "Task2", 512, nullptr, 3, xHandleTask2); | |
cxa_throw_mutex = xSemaphoreCreateRecursiveMutex(); | |
vTaskStartScheduler(); | |
while (true) | |
{} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <errno.h> | |
#include <string.h> | |
#include "FreeRTOS.h" | |
// Binds newlib memory allocators to that of freeRTOS | |
// this makes them thread-safe | |
#if !defined(configUSE_NEWLIB_REENTRANT) || (configUSE_NEWLIB_REENTRANT != 1) | |
#warning "#define configUSE_NEWLIB_REENTRANT 1 // Required for thread-safety of newlib sprintf, dtoa, strtok, etc..." | |
#endif | |
void* sbrk(int incr) | |
{ | |
// Newlib standard heap usage banned | |
// Instead newlib should automatically use the overriden malloc etc... functions below | |
configASSERT(false); | |
errno = ENOMEM; | |
return (char*)-1; | |
} | |
void* _sbrk(int incr) | |
{ | |
return sbrk(incr); | |
} | |
void* _sbrk_r(struct _reent* r, int incr) | |
{ | |
return _sbrk(incr); | |
} | |
void free(void* ptr) | |
{ | |
return vPortFree(ptr); | |
} | |
void _free_r(struct _reent* r, void* ptr) | |
{ | |
return free(ptr); | |
} | |
void* malloc(size_t size) | |
{ | |
return pvPortMalloc(size); | |
} | |
void* _malloc_r(struct _reent* r, size_t size) | |
{ | |
return malloc(size); | |
} | |
void* realloc(void* ptr, size_t size) | |
{ | |
void* mem; | |
mem = malloc(size); | |
if (mem != NULL) { | |
memcpy(mem, ptr, size); | |
free(ptr); | |
} | |
return mem; | |
} | |
void* _realloc_r(struct _reent* r, void* ptr, size_t size) | |
{ | |
return realloc(ptr, size); | |
} | |
void* calloc(size_t nitems, size_t size) | |
{ | |
void* mem; | |
size_t bytes = nitems * size; | |
mem = malloc(bytes); | |
if (mem != NULL) | |
memset(mem, 0, bytes); | |
return mem; | |
} | |
void* _calloc_r(struct _reent* r, size_t nitems, size_t size) | |
{ | |
return calloc(nitems, size); | |
} | |
void* memalign(size_t alignment, size_t size) | |
{ | |
configASSERT(false); // Not implemented | |
return NULL; | |
} | |
void* _memalign_r(struct _reent* r, size_t alignment, size_t size) | |
{ | |
return memalign(alignment, size); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment