Implement mutex for local target, fix concurrency test (#104)

* Implement mutex support for target_lo

* Kill application if test hangs

* Use mutex in furi_take and furi_give

* Give furi application enough time to finish

* remove app obj after build

* enable counting semaphores

Co-authored-by: aanper <mail@s3f.ru>
This commit is contained in:
Vadim Kaushan 2020-09-07 17:35:18 +03:00 committed by GitHub
parent 0307b12fd5
commit 884fccc591
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 58 additions and 18 deletions

View File

@ -235,7 +235,7 @@ bool test_furi_concurrent_access(FuriRecordSubscriber* log) {
furi_give(holding_record); furi_give(holding_record);
} }
delay(20); delay(50);
if(second_app->handler != NULL) { if(second_app->handler != NULL) {
fuprintf(log, "second app still alive\n"); fuprintf(log, "second app still alive\n");

View File

@ -192,15 +192,18 @@ static void furi_notify(FuriRecordSubscriber* handler, const void* value, size_t
void* furi_take(FuriRecordSubscriber* handler) { void* furi_take(FuriRecordSubscriber* handler) {
if(handler == NULL || handler->record == NULL) return NULL; if(handler == NULL || handler->record == NULL) return NULL;
// take mutex
if (xSemaphoreTake(handler->record->mutex, portMAX_DELAY) == pdTRUE) {
return handler->record->value; return handler->record->value;
} else {
return NULL;
}
} }
void furi_give(FuriRecordSubscriber* handler) { void furi_give(FuriRecordSubscriber* handler) {
if(handler == NULL || handler->record == NULL) return; if(handler == NULL || handler->record == NULL) return;
// release mutex xSemaphoreGive(handler->record->mutex);
} }
void furi_commit(FuriRecordSubscriber* handler) { void furi_commit(FuriRecordSubscriber* handler) {

View File

@ -67,6 +67,7 @@
#define configUSE_MUTEXES 1 #define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8 #define configQUEUE_REGISTRY_SIZE 8
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configUSE_COUNTING_SEMAPHORES 1
/* Co-routine definitions. */ /* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0 #define configUSE_CO_ROUTINES 0

View File

@ -261,18 +261,16 @@ rust_lib:
$(RUST_LIB_CMD) $(RUST_LIB_CMD)
example_blink: example_blink:
rm $(BUILD_DIR)/app.o
EXAMPLE_BLINK=1 make EXAMPLE_BLINK=1 make
rm $(BUILD_DIR)/app.o rm $(BUILD_DIR)/app.o
example_uart_write: example_uart_write:
rm $(BUILD_DIR)/app.o
EXAMPLE_UART_WRITE=1 make EXAMPLE_UART_WRITE=1 make
rm $(BUILD_DIR)/app.o rm $(BUILD_DIR)/app.o
example_ipc: example_ipc:
rm $(BUILD_DIR)/app.o
EXAMPLE_IPC=1 make EXAMPLE_IPC=1 make
rm $(BUILD_DIR)/app.o
test: test:
TEST=1 make TEST=1 make

View File

@ -1,5 +1,6 @@
git checkout -- target_f1/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h git checkout -- target_f1/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h
git checkout -- target_f1/Makefile git checkout -- target_f1/Makefile
git checkout -- target_f1/Inc/FreeRTOSConfig.h
git checkout -- target_f1/Src/stm32l4xx_it.c git checkout -- target_f1/Src/stm32l4xx_it.c
git checkout -- target_f1/Src/usbd_conf.c git checkout -- target_f1/Src/usbd_conf.c
git checkout -- target_f1/Src/usbd_desc.c git checkout -- target_f1/Src/usbd_desc.c

View File

@ -14,10 +14,12 @@ typedef pthread_t* TaskHandle_t;
typedef enum { typedef enum {
SemaphoreTypeCounting SemaphoreTypeMutex,
SemaphoreTypeCounting,
} SemaphoreType; } SemaphoreType;
typedef struct { typedef struct {
SemaphoreType type; SemaphoreType type;
pthread_mutex_t mutex;
uint8_t take_counter; uint8_t take_counter;
uint8_t give_counter; uint8_t give_counter;
} StaticSemaphore_t; } StaticSemaphore_t;

View File

@ -162,7 +162,7 @@ example_ipc:
test: test:
rm -f $(BUILD_DIR)/app.o rm -f $(BUILD_DIR)/app.o
TEST=1 make TEST=1 make
$(BUILD_DIR)/$(TARGET) timeout --signal=9 5 $(BUILD_DIR)/$(TARGET)
.PHONY: all rust_lib example_blink example_uart_write test .PHONY: all rust_lib example_blink example_uart_write test

View File

@ -82,11 +82,6 @@ bool task_equal(TaskHandle_t a, TaskHandle_t b) {
return pthread_equal(*a, *b) != 0; return pthread_equal(*a, *b) != 0;
} }
SemaphoreHandle_t xSemaphoreCreateMutexStatic(StaticSemaphore_t* pxMutexBuffer) {
// TODO add posix mutex init
return NULL;
}
BaseType_t xQueueSend( BaseType_t xQueueSend(
QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait
) { ) {
@ -127,13 +122,45 @@ SemaphoreHandle_t xSemaphoreCreateCountingStatic(
UBaseType_t uxInitialCount, UBaseType_t uxInitialCount,
StaticSemaphore_t* pxSemaphoreBuffer StaticSemaphore_t* pxSemaphoreBuffer
) { ) {
pxSemaphoreBuffer->type = SemaphoreTypeCounting;
pxSemaphoreBuffer->take_counter = 0; pxSemaphoreBuffer->take_counter = 0;
pxSemaphoreBuffer->give_counter = 0; pxSemaphoreBuffer->give_counter = 0;
return pxSemaphoreBuffer; return pxSemaphoreBuffer;
} }
BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait) { SemaphoreHandle_t xSemaphoreCreateMutexStatic(StaticSemaphore_t* pxMutexBuffer) {
if(xSemaphore == NULL) return false; pxMutexBuffer->type = SemaphoreTypeMutex;
pthread_mutex_init(&pxMutexBuffer->mutex, NULL);
pxMutexBuffer->take_counter = 0;
pxMutexBuffer->give_counter = 0;
return pxMutexBuffer;
}
BaseType_t xSemaphoreTake(volatile SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait) {
if(xSemaphore == NULL) return pdFALSE;
if (xSemaphore->type == SemaphoreTypeMutex) {
if (xTicksToWait == portMAX_DELAY) {
if (pthread_mutex_lock(&xSemaphore->mutex) == 0) {
return pdTRUE;
} else {
return pdFALSE;
}
} else {
TickType_t ticks = xTicksToWait;
while (ticks >= 0) {
if (pthread_mutex_trylock(&xSemaphore->mutex) == 0) {
return pdTRUE;
}
if (ticks > 0) {
osDelay(1);
}
ticks--;
}
return pdFALSE;
}
}
// TODO: need to add inter-process sync or use POSIX primitives // TODO: need to add inter-process sync or use POSIX primitives
xSemaphore->take_counter++; xSemaphore->take_counter++;
@ -154,7 +181,15 @@ BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait)
} }
BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore) { BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore) {
if(xSemaphore == NULL) return false; if(xSemaphore == NULL) return pdFALSE;
if (xSemaphore->type == SemaphoreTypeMutex) {
if (pthread_mutex_unlock(&xSemaphore->mutex) == 0) {
return pdTRUE;
} else {
return pdFALSE;
}
}
// TODO: need to add inter-process sync or use POSIX primitives // TODO: need to add inter-process sync or use POSIX primitives
xSemaphore->give_counter++; xSemaphore->give_counter++;