From 9e8c9ea47f5b8b001f0f1d374ed1ddb4f64a7038 Mon Sep 17 00:00:00 2001 From: Tiago Medicci Serrano Date: Wed, 24 Apr 2024 16:12:30 -0300 Subject: [PATCH] esp: Update libc stubs to properly acquire/release locks. Avoid using static mutex and recursive mutex as the resource to be acquired/release. Instead, create a specific lock for each call if it does not exist. --- .../src/common/espressif/esp_libc_stubs.c | 86 +++++-- .../espressif/platform_include/sys/lock.h | 213 ++++++++++++++++++ arch/risc-v/src/esp32c3/Make.defs | 2 + arch/risc-v/src/esp32c6/Make.defs | 2 + arch/risc-v/src/esp32h2/Make.defs | 2 + 5 files changed, 283 insertions(+), 22 deletions(-) create mode 100644 arch/risc-v/src/common/espressif/platform_include/sys/lock.h diff --git a/arch/risc-v/src/common/espressif/esp_libc_stubs.c b/arch/risc-v/src/common/espressif/esp_libc_stubs.c index dfe6a160f1..f7cb7afca3 100644 --- a/arch/risc-v/src/common/espressif/esp_libc_stubs.c +++ b/arch/risc-v/src/common/espressif/esp_libc_stubs.c @@ -45,8 +45,6 @@ * Pre-processor Definitions ****************************************************************************/ -#define _lock_t int - #define ROM_MUTEX_MAGIC 0xbb10c433 /**************************************************************************** @@ -180,64 +178,108 @@ void _raise_r(struct _reent *r) void _lock_init(_lock_t *lock) { - nxmutex_init(&g_nxlock_common); - nxsem_get_value(&g_nxlock_common.sem, lock); + mutex_t *mutex = (mutex_t *)kmm_malloc(sizeof(mutex_t)); + + nxmutex_init(mutex); + + *lock = (_lock_t)mutex; } void _lock_init_recursive(_lock_t *lock) { - nxmutex_init(&g_nxlock_recursive); - nxsem_get_value(&g_nxlock_recursive.sem, lock); + rmutex_t *rmutex = (rmutex_t *)kmm_malloc(sizeof(rmutex_t)); + + nxrmutex_init(rmutex); + + *lock = (_lock_t)rmutex; } void _lock_close(_lock_t *lock) { - nxmutex_destroy(&g_nxlock_common); + mutex_t *mutex = (mutex_t *)(*lock); + + nxmutex_destroy(mutex); + kmm_free(*lock); *lock = 0; } void _lock_close_recursive(_lock_t *lock) { - nxmutex_destroy(&g_nxlock_recursive); + rmutex_t *rmutex = (rmutex_t *)(*lock); + + nxrmutex_destroy(rmutex); + kmm_free(*lock); *lock = 0; } void _lock_acquire(_lock_t *lock) { - nxmutex_lock(&g_nxlock_common); - nxsem_get_value(&g_nxlock_common.sem, lock); + if (*lock == NULL) + { + mutex_t *mutex = (mutex_t *)kmm_malloc(sizeof(mutex_t)); + + nxmutex_init(mutex); + + *lock = (_lock_t)mutex; + } + + nxmutex_lock((mutex_t *)(*lock)); } void _lock_acquire_recursive(_lock_t *lock) { - nxmutex_lock(&g_nxlock_recursive); - nxsem_get_value(&g_nxlock_recursive.sem, lock); + if (*lock == NULL) + { + rmutex_t *rmutex = (rmutex_t *)kmm_malloc(sizeof(rmutex_t)); + + nxrmutex_init(rmutex); + + *lock = (_lock_t)rmutex; + } + + nxrmutex_lock((rmutex_t *)(*lock)); } int _lock_try_acquire(_lock_t *lock) { - nxmutex_trylock(&g_nxlock_common); - nxsem_get_value(&g_nxlock_common.sem, lock); - return 0; + if (*lock == NULL) + { + mutex_t *mutex = (mutex_t *)kmm_malloc(sizeof(mutex_t)); + + nxmutex_init(mutex); + + *lock = (_lock_t)mutex; + } + + return nxmutex_trylock((mutex_t *)(*lock)); } int _lock_try_acquire_recursive(_lock_t *lock) { - nxmutex_trylock(&g_nxlock_recursive); - nxsem_get_value(&g_nxlock_recursive.sem, lock); - return 0; + if (*lock == NULL) + { + rmutex_t *rmutex = (rmutex_t *)kmm_malloc(sizeof(rmutex_t)); + + nxrmutex_init(rmutex); + + *lock = (_lock_t)rmutex; + } + + return nxrmutex_trylock((rmutex_t *)(*lock)); } void _lock_release(_lock_t *lock) { - nxmutex_unlock(&g_nxlock_common); - nxsem_get_value(&g_nxlock_common.sem, lock); + mutex_t *mutex = (mutex_t *)(*lock); + + nxmutex_unlock(mutex); } void _lock_release_recursive(_lock_t *lock) { - nxmutex_unlock(&g_nxlock_recursive); - nxsem_get_value(&g_nxlock_recursive.sem, lock); + rmutex_t *rmutex = (rmutex_t *)(*lock); + + nxrmutex_unlock(rmutex); } #if ESP_ROM_HAS_RETARGETABLE_LOCKING diff --git a/arch/risc-v/src/common/espressif/platform_include/sys/lock.h b/arch/risc-v/src/common/espressif/platform_include/sys/lock.h new file mode 100644 index 0000000000..4f177097bc --- /dev/null +++ b/arch/risc-v/src/common/espressif/platform_include/sys/lock.h @@ -0,0 +1,213 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/platform_include/sys/lock.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#pragma once + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include_next + +#ifdef _RETARGETABLE_LOCKING + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ + +/* Actual platfrom-specific definition of struct __lock. + * The size here should be sufficient for a NuttX mutex and recursive mutex. + * This is checked by a static assertion in _libc_stubs.c + */ + +struct __lock +{ + int reserved[4]; +}; + +typedef _LOCK_T _lock_t; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: _lock_init + * + * Description: + * Allocate lock related resources. + * + * Input Parameters: + * plock - pointer to user defined lock object + * + * Returned Value: + * None + * + ****************************************************************************/ + +void _lock_init(_lock_t *plock); + +/**************************************************************************** + * Name: _lock_init_recursive + * + * Description: + * Allocate recursive lock related resources. + * + * Input Parameters: + * plock - pointer to user defined lock object + * + * Returned Value: + * None + * + ****************************************************************************/ + +void _lock_init_recursive(_lock_t *plock); + +/**************************************************************************** + * Name: _lock_close + * + * Description: + * Free lock related resources. + * + * Input Parameters: + * plock - pointer to user defined lock object + * + * Returned Value: + * None + * + ****************************************************************************/ + +void _lock_close(_lock_t *plock); + +/**************************************************************************** + * Name: _lock_close_recursive + * + * Description: + * Free recursive lock related resources. + * + * Input Parameters: + * plock - pointer to user defined lock object + * + * Returned Value: + * None + * + ****************************************************************************/ + +void _lock_close_recursive(_lock_t *plock); + +/**************************************************************************** + * Name: _lock_acquire + * + * Description: + * Acquire lock immediately after the lock object is available. + * + * Input Parameters: + * plock - pointer to user defined lock object + * + * Returned Value: + * None + * + ****************************************************************************/ + +void _lock_acquire(_lock_t *plock); + +/**************************************************************************** + * Name: _lock_acquire_recursive + * + * Description: + * Acquire recursive lock immediately after the lock object is available. + * + * Input Parameters: + * plock - pointer to user defined lock object + * + * Returned Value: + * None + * + ****************************************************************************/ + +void _lock_acquire_recursive(_lock_t *plock); + +/**************************************************************************** + * Name: _lock_try_acquire + * + * Description: + * Acquire lock if the lock object is available. + * + * Input Parameters: + * plock - pointer to user defined lock object + * + * Returned Value: + * Zero for success and non-zero to indicate that the lock cannot be + * acquired + * + ****************************************************************************/ + +int _lock_try_acquire(_lock_t *plock); + +/**************************************************************************** + * Name: _lock_try_acquire_recursive + * + * Description: + * Acquire recursive lock if the lock object is available. + * + * Input Parameters: + * plock - pointer to user defined lock object + * + * Returned Value: + * Zero for success and non-zero to indicate that the lock cannot be + * acquired + * + ****************************************************************************/ + +int _lock_try_acquire_recursive(_lock_t *plock); + +/**************************************************************************** + * Name: _lock_release + * + * Description: + * Relinquish the lock ownership. + * + * Input Parameters: + * plock - pointer to user defined lock object + * + * Returned Value: + * None + * + ****************************************************************************/ + +void _lock_release(_lock_t *plock); + +/**************************************************************************** + * Name: _lock_release_recursive + * + * Description: + * Relinquish the recursive lock ownership. + * + * Input Parameters: + * plock - pointer to user defined lock object + * + * Returned Value: + * None + * + ****************************************************************************/ + +void _lock_release_recursive(_lock_t *plock); + +#endif // _RETARGETABLE_LOCKING diff --git a/arch/risc-v/src/esp32c3/Make.defs b/arch/risc-v/src/esp32c3/Make.defs index 7a10e38f01..a8bdc3b46a 100644 --- a/arch/risc-v/src/esp32c3/Make.defs +++ b/arch/risc-v/src/esp32c3/Make.defs @@ -20,3 +20,5 @@ include common/Make.defs include common/espressif/Make.defs + +CFLAGS += ${DEFINE_PREFIX}_RETARGETABLE_LOCKING diff --git a/arch/risc-v/src/esp32c6/Make.defs b/arch/risc-v/src/esp32c6/Make.defs index ccd4b90737..13ba12c297 100644 --- a/arch/risc-v/src/esp32c6/Make.defs +++ b/arch/risc-v/src/esp32c6/Make.defs @@ -20,3 +20,5 @@ include common/Make.defs include common/espressif/Make.defs + +CFLAGS += ${DEFINE_PREFIX}_RETARGETABLE_LOCKING diff --git a/arch/risc-v/src/esp32h2/Make.defs b/arch/risc-v/src/esp32h2/Make.defs index 0b77cc501d..98a16698f1 100644 --- a/arch/risc-v/src/esp32h2/Make.defs +++ b/arch/risc-v/src/esp32h2/Make.defs @@ -20,3 +20,5 @@ include common/Make.defs include common/espressif/Make.defs + +CFLAGS += ${DEFINE_PREFIX}_RETARGETABLE_LOCKING