Skip to content

Commit ecc0c38

Browse files
committed
fix(lwip): Avoid dual heap allocations of semaphores by LwIP
This avoids one pointer indirection.
1 parent ff97953 commit ecc0c38

File tree

3 files changed

+28
-27
lines changed

3 files changed

+28
-27
lines changed

components/esp_netif/lwip/esp_netif_lwip.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ static void netif_unset_garp_flag(struct netif *netif)
207207
#endif // CONFIG_LWIP_GARP_TMR_INTERVAL
208208

209209
#if !LWIP_TCPIP_CORE_LOCKING
210-
static sys_sem_t api_sync_sem = NULL;
211-
static sys_sem_t api_lock_sem = NULL;
210+
static sys_sem_t api_sync_sem = {0};
211+
static sys_sem_t api_lock_sem = {0};
212212
#endif
213213

214214
/**
@@ -588,14 +588,14 @@ esp_err_t esp_netif_init(void)
588588
}
589589

590590
#if !LWIP_TCPIP_CORE_LOCKING
591-
if (!api_sync_sem) {
591+
if (!sys_sem_valid(&api_sync_sem)) {
592592
if (ERR_OK != sys_sem_new(&api_sync_sem, 0)) {
593593
ESP_LOGE(TAG, "esp netif api sync sem init fail");
594594
return ESP_FAIL;
595595
}
596596
}
597597

598-
if (!api_lock_sem) {
598+
if (!sys_sem_valid(&api_lock_sem)) {
599599
if (ERR_OK != sys_sem_new(&api_lock_sem, 1)) {
600600
ESP_LOGE(TAG, "esp netif api lock sem init fail");
601601
return ESP_FAIL;

components/lwip/port/freertos/include/arch/sys_arch.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* SPDX-License-Identifier: BSD-3-Clause
55
*
6-
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
6+
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
77
*/
88
#ifndef __SYS_ARCH_H__
99
#define __SYS_ARCH_H__
@@ -18,7 +18,7 @@ extern "C" {
1818
#endif
1919

2020

21-
typedef SemaphoreHandle_t sys_sem_t;
21+
typedef StaticSemaphore_t sys_sem_t;
2222
typedef SemaphoreHandle_t sys_mutex_t;
2323
typedef TaskHandle_t sys_thread_t;
2424

@@ -45,9 +45,8 @@ void sys_delay_ms(uint32_t ms);
4545
#define sys_mbox_valid(mbox) (*(mbox) != NULL)
4646
#define sys_mbox_set_invalid(mbox) (*(mbox) = NULL)
4747

48-
#define sys_sem_valid_val(sema) ((sema) != NULL)
49-
#define sys_sem_valid(sema) (((sema) != NULL) && sys_sem_valid_val(*(sema)))
50-
#define sys_sem_set_invalid(sema) ((*(sema)) = NULL)
48+
#define sys_sem_valid(sema) ( ( memcmp((sema), &(StaticSemaphore_t){0}, sizeof(StaticSemaphore_t)) == 0) ? pdFALSE : pdTRUE )
49+
#define sys_sem_set_invalid(sema) memset((sema), 0, sizeof(StaticSemaphore_t))
5150

5251
void sys_delay_ms(uint32_t ms);
5352
sys_sem_t* sys_thread_sem_init(void);

components/lwip/port/freertos/sys_arch.c

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,14 @@ sys_sem_new(sys_sem_t *sem, u8_t count)
108108
LWIP_ASSERT("initial_count invalid (neither 0 nor 1)",
109109
(count == 0) || (count == 1));
110110

111-
*sem = xSemaphoreCreateBinary();
112-
if (*sem == NULL) {
113-
LWIP_DEBUGF(SYS_DEBUG, ("sys_sem_new: out of mem\r\n"));
111+
QueueHandle_t res = xSemaphoreCreateBinaryStatic(sem);
112+
if ((sys_sem_t *)res != sem) {
113+
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_sem_new: out of mem\r\n"));
114114
return ERR_MEM;
115115
}
116116

117117
if (count == 1) {
118-
BaseType_t ret = xSemaphoreGive(*sem);
118+
BaseType_t ret = xSemaphoreGive(sem);
119119
LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE);
120120
(void)ret;
121121
}
@@ -131,7 +131,7 @@ sys_sem_new(sys_sem_t *sem, u8_t count)
131131
void
132132
sys_sem_signal(sys_sem_t *sem)
133133
{
134-
BaseType_t ret = xSemaphoreGive(*sem);
134+
BaseType_t ret = xSemaphoreGive(sem);
135135
/* queue full is OK, this is a signal only... */
136136
LWIP_ASSERT("sys_sem_signal: sane return value",
137137
(ret == pdTRUE) || (ret == errQUEUE_FULL));
@@ -144,7 +144,7 @@ int
144144
sys_sem_signal_isr(sys_sem_t *sem)
145145
{
146146
BaseType_t woken = pdFALSE;
147-
xSemaphoreGiveFromISR(*sem, &woken);
147+
xSemaphoreGiveFromISR(sem, &woken);
148148
return woken == pdTRUE;
149149
}
150150

@@ -162,7 +162,7 @@ sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
162162

163163
if (!timeout) {
164164
/* wait infinite */
165-
ret = xSemaphoreTake(*sem, portMAX_DELAY);
165+
ret = xSemaphoreTake((QueueHandle_t)sem, portMAX_DELAY);
166166
LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
167167
} else {
168168
/* Round up the number of ticks.
@@ -172,7 +172,7 @@ sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
172172
* 1 tick before triggering a timeout. Thus, we need to pass 2 ticks as a timeout
173173
* to `xSemaphoreTake`. */
174174
TickType_t timeout_ticks = ((timeout + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS) + 1;
175-
ret = xSemaphoreTake(*sem, timeout_ticks);
175+
ret = xSemaphoreTake((QueueHandle_t)sem, timeout_ticks);
176176
if (ret == errQUEUE_EMPTY) {
177177
/* timed out */
178178
return SYS_ARCH_TIMEOUT;
@@ -191,8 +191,8 @@ sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
191191
void
192192
sys_sem_free(sys_sem_t *sem)
193193
{
194-
vSemaphoreDelete(*sem);
195-
*sem = NULL;
194+
vSemaphoreDelete((QueueHandle_t)sem);
195+
memset(sem, 0, sizeof(*sem));
196196
}
197197

198198
/**
@@ -490,31 +490,33 @@ sys_thread_sem_free(void* data) // destructor for TLS semaphore
490490
{
491491
sys_sem_t *sem = (sys_sem_t*)(data);
492492

493-
if (sem && *sem){
494-
LWIP_DEBUGF(SYS_DEBUG, ("sem del, sem=%p\n", *sem));
495-
vSemaphoreDelete(*sem);
493+
if (sem){
494+
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sem del, sem=%p\n", sem));
495+
vSemaphoreDelete((QueueHandle_t)sem);
496496
}
497497

498498
if (sem) {
499-
LWIP_DEBUGF(SYS_DEBUG, ("sem pointer del, sem_p=%p\n", sem));
499+
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sem pointer del, sem_p=%p\n", sem));
500500
mem_free(sem);
501501
}
502502
}
503503

504504
sys_sem_t*
505505
sys_thread_sem_init(void)
506506
{
507-
sys_sem_t *sem = (sys_sem_t*)mem_malloc(sizeof(sys_sem_t*));
507+
sys_sem_t *sem = (sys_sem_t*)mem_malloc(sizeof(sys_sem_t));
508508

509509
if (!sem){
510510
ESP_LOGE(TAG, "thread_sem_init: out of memory");
511511
return 0;
512512
}
513513

514-
*sem = xSemaphoreCreateBinary();
515-
if (!(*sem)){
514+
// If successful, create a binary semaphore the pointer to the semaphore is returned
515+
QueueHandle_t res = xSemaphoreCreateBinaryStatic(sem);
516+
517+
if (res != (QueueHandle_t)sem){
516518
mem_free(sem);
517-
ESP_LOGE(TAG, "thread_sem_init: out of memory");
519+
ESP_LOGE(TAG, "thread_sem_init: unable to create semaphore %p != %p", res, sem);
518520
return 0;
519521
}
520522

0 commit comments

Comments
 (0)