change(cache): added mutex to guarantee the atomicity

This mutex is only added when msync is called from the task. This means only one task will compete with the msync-calls from ISRs.
This commit is contained in:
Armando 2024-07-23 14:47:07 +08:00
parent 3bfc134a23
commit 074ed08251
3 changed files with 29 additions and 2 deletions

View File

@ -7,6 +7,7 @@
#include <sys/param.h>
#include <inttypes.h>
#include <string.h>
#include "sys/lock.h"
#include "sdkconfig.h"
#include "esp_check.h"
#include "esp_log.h"
@ -58,6 +59,28 @@ static void s_c2m_ops(uint32_t vaddr, size_t size)
}
#endif
//no ops if ISR context or critical section context
static void s_acquire_mutex_from_task_context(void)
{
#if CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS
if (xPortCanYield()) {
_lock_acquire(&s_mutex);
ESP_LOGD(TAG, "mutex is taken");
}
#endif //#if CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS
}
//no ops if ISR context or critical section context
static void s_release_mutex_from_task_context(void)
{
#if CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS
if (xPortCanYield()) {
_lock_release(&s_mutex);
ESP_LOGD(TAG, "mutex is free");
}
#endif //#if CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS
}
esp_err_t esp_cache_msync(void *addr, size_t size, int flags)
{
ESP_RETURN_ON_FALSE_ISR(addr, ESP_ERR_INVALID_ARG, TAG, "null pointer");
@ -88,6 +111,7 @@ esp_err_t esp_cache_msync(void *addr, size_t size, int flags)
ESP_RETURN_ON_FALSE_ISR(aligned_addr, ESP_ERR_INVALID_ARG, TAG, "start address: 0x%" PRIx32 ", or the size: 0x%" PRIx32 " is(are) not aligned with cache line size (0x%" PRIx32 ")B", (uint32_t)addr, (uint32_t)size, cache_line_size);
}
s_acquire_mutex_from_task_context();
if (flags & ESP_CACHE_MSYNC_FLAG_DIR_M2C) {
ESP_EARLY_LOGV(TAG, "M2C DIR");
@ -117,6 +141,7 @@ esp_err_t esp_cache_msync(void *addr, size_t size, int flags)
assert(valid);
#endif //#if SOC_CACHE_WRITEBACK_SUPPORTED
}
s_release_mutex_from_task_context();
return ESP_OK;
}

View File

@ -13,7 +13,7 @@ const static char *TAG = "cache_utils";
esp_err_t test_set_buffer_dirty(intptr_t vaddr_start, size_t size)
{
if (((vaddr_start % 32) != 0) || ((size % 32) != 0)) {
ESP_LOGE(TAG, "addr not 4B aligned");
ESP_LOGE(TAG, "addr or size not 4B aligned");
return ESP_ERR_INVALID_ARG;
}

View File

@ -33,12 +33,14 @@ const static char *TAG = "CACHE_TEST";
#define TEST_OFFSET 0x100000
#if CONFIG_IDF_TARGET_ESP32S2
#define TEST_SYNC_START (SOC_DPORT_CACHE_ADDRESS_LOW + TEST_OFFSET)
#define TEST_SYNC_SIZE CONFIG_ESP32S2_DATA_CACHE_SIZE
#elif CONFIG_IDF_TARGET_ESP32S3
#define TEST_SYNC_START (SOC_DRAM0_CACHE_ADDRESS_LOW + TEST_OFFSET)
#define TEST_SYNC_SIZE CONFIG_ESP32S3_DATA_CACHE_SIZE
#elif CONFIG_IDF_TARGET_ESP32P4
#define TEST_SYNC_START (SOC_DRAM_PSRAM_ADDRESS_LOW + TEST_OFFSET)
#define TEST_SYNC_SIZE CONFIG_CACHE_L2_CACHE_SIZE
#endif
#define TEST_SYNC_SIZE 0x8000
#define RECORD_TIME_PREPARE() uint32_t __t1, __t2
#define RECORD_TIME_START() do {__t1 = esp_cpu_get_cycle_count();} while(0)