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
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return handler->record->value;
 | 
					    if (xSemaphoreTake(handler->record->mutex, portMAX_DELAY) == pdTRUE) {
 | 
				
			||||||
 | 
					        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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user