Skip to content
Snippets Groups Projects
Commit 16a248d7 authored by q3k's avatar q3k
Browse files

badge23: scope: better locking

This uses atomics to lock out concurrenct writes/reads, and fixes some
potential null pointer dereferences.
parent d65cfeaf
No related branches found
No related tags found
No related merge requests found
......@@ -5,7 +5,8 @@ typedef struct {
int16_t * buffer;
int16_t buffer_size;
int16_t write_head_position; // last written value
volatile uint8_t is_being_read;
// atomic value used to prevent simultaneous reads/writes (not a mutex!).
volatile uint32_t is_being_read;
} scope_t;
void init_scope(uint16_t size);
......
#include "badge23/scope.h"
#include "esp_log.h"
#include <string.h>
#include <freertos/FreeRTOS.h>
#include <freertos/atomic.h>
scope_t * scope;
scope_t * scope = NULL;
static const char* TAG = "scope";
void init_scope(uint16_t size){
if (scope != NULL) {
return;
}
scope_t * scp = malloc(sizeof(scope_t));
if(scp == NULL) scope = NULL;
if(scp == NULL) {
ESP_LOGE(TAG, "scope allocation failed, out of memory");
return;
}
scp->buffer_size = size;
scp->buffer = malloc(sizeof(int16_t) * scp->buffer_size);
if(scp->buffer == NULL){
free(scp);
scope = NULL;
} else {
memset(scp->buffer, 0, sizeof(int16_t) * scp->buffer_size);
scope = scp;
ESP_LOGE(TAG, "scope buffer allocation failed, out of memory");
return;
}
memset(scp->buffer, 0, sizeof(int16_t) * scp->buffer_size);
scope = scp;
ESP_LOGI(TAG, "initialized");
}
static inline bool scope_being_read(void) {
return Atomic_CompareAndSwap_u32(&scope->is_being_read, 0, 0) == ATOMIC_COMPARE_AND_SWAP_FAILURE;
}
void write_to_scope(int16_t value){
if(scope->is_being_read) return;
if(scope == NULL) return;
if(scope == NULL || scope_being_read()) {
return;
}
scope->write_head_position++;
if(scope->write_head_position >= scope->buffer_size) scope->write_head_position = 0;
scope->buffer[scope->write_head_position] = value;
}
void begin_scope_read(){
if(scope == NULL) return;
scope->is_being_read = 1; //best mutex
void begin_scope_read(void) {
if (scope == NULL) {
return;
}
Atomic_Increment_u32(&scope->is_being_read);
}
void read_line_from_scope(uint16_t * line, int16_t point){
if (scope == NULL) {
return;
}
memset(line, 0, 480);
int16_t startpoint = scope->write_head_position - point;
while(startpoint < 0){
......@@ -57,7 +80,9 @@ void read_line_from_scope(uint16_t * line, int16_t point){
}
}
void end_scope_read(){
if(scope == NULL) return;
scope->is_being_read = 0; //best mutex
void end_scope_read(void) {
if (scope == NULL) {
return;
}
Atomic_Decrement_u32(&scope->is_being_read);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment