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:
parent
0307b12fd5
commit
884fccc591
@ -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");
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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++;
|
||||||
|
Loading…
Reference in New Issue
Block a user