From 79a0e57ca102349ef4206060c45eeb2138edfc91 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 31 Mar 2023 17:06:28 +0200 Subject: [PATCH] fix(mdns): Refactor freertos linux compat layers Move it to a separate component that could be shared by multiple network libs. --- .../linux_compat}/freertos/CMakeLists.txt | 3 +- .../linux_compat}/freertos/Kconfig | 0 .../linux_compat/freertos/freertos_linux.c | 272 ++++++++++++++++++ .../linux_compat}/freertos/include/esp_task.h | 1 + .../freertos/include/freertos/FreeRTOS.h | 2 + .../freertos/include/freertos/event_groups.h | 6 + .../freertos/include/freertos/queue.h | 9 +- .../freertos/include/freertos/semphr.h | 9 +- .../freertos/include/freertos/task.h | 27 +- .../freertos/osal/event_group.cpp | 111 +++++++ .../linux_compat/freertos/osal/mutex.cpp | 31 ++ .../linux_compat/freertos/osal/osal_api.h | 34 +++ .../linux_compat/freertos/osal/queue.cpp | 79 +++++ .../mdns/tests/host_test/CMakeLists.txt | 2 +- .../components/freertos/freertos_linux.c | 174 ----------- .../components/freertos/queue_unique_ptr.cpp | 43 --- .../components/freertos/queue_unique_ptr.hpp | 46 --- 17 files changed, 567 insertions(+), 282 deletions(-) rename {components/mdns/tests/host_test/components => common_components/linux_compat}/freertos/CMakeLists.txt (70%) rename {components/mdns/tests/host_test/components => common_components/linux_compat}/freertos/Kconfig (100%) create mode 100644 common_components/linux_compat/freertos/freertos_linux.c rename {components/mdns/tests/host_test/components => common_components/linux_compat}/freertos/include/esp_task.h (87%) rename {components/mdns/tests/host_test/components => common_components/linux_compat}/freertos/include/freertos/FreeRTOS.h (91%) create mode 100644 common_components/linux_compat/freertos/include/freertos/event_groups.h rename {components/mdns/tests/host_test/components => common_components/linux_compat}/freertos/include/freertos/queue.h (57%) rename {components/mdns/tests/host_test/components => common_components/linux_compat}/freertos/include/freertos/semphr.h (55%) rename {components/mdns/tests/host_test/components => common_components/linux_compat}/freertos/include/freertos/task.h (55%) create mode 100644 common_components/linux_compat/freertos/osal/event_group.cpp create mode 100644 common_components/linux_compat/freertos/osal/mutex.cpp create mode 100644 common_components/linux_compat/freertos/osal/osal_api.h create mode 100644 common_components/linux_compat/freertos/osal/queue.cpp delete mode 100644 components/mdns/tests/host_test/components/freertos/freertos_linux.c delete mode 100644 components/mdns/tests/host_test/components/freertos/queue_unique_ptr.cpp delete mode 100644 components/mdns/tests/host_test/components/freertos/queue_unique_ptr.hpp diff --git a/components/mdns/tests/host_test/components/freertos/CMakeLists.txt b/common_components/linux_compat/freertos/CMakeLists.txt similarity index 70% rename from components/mdns/tests/host_test/components/freertos/CMakeLists.txt rename to common_components/linux_compat/freertos/CMakeLists.txt index 9180dbce1..9c4100fa5 100644 --- a/components/mdns/tests/host_test/components/freertos/CMakeLists.txt +++ b/common_components/linux_compat/freertos/CMakeLists.txt @@ -1,4 +1,5 @@ -idf_component_register(SRCS freertos_linux.c queue_unique_ptr.cpp +idf_component_register(SRCS freertos_linux.c + osal/queue.cpp osal/event_group.cpp osal/mutex.cpp INCLUDE_DIRS include) set(THREADS_PREFER_PTHREAD_FLAG ON) diff --git a/components/mdns/tests/host_test/components/freertos/Kconfig b/common_components/linux_compat/freertos/Kconfig similarity index 100% rename from components/mdns/tests/host_test/components/freertos/Kconfig rename to common_components/linux_compat/freertos/Kconfig diff --git a/common_components/linux_compat/freertos/freertos_linux.c b/common_components/linux_compat/freertos/freertos_linux.c new file mode 100644 index 000000000..40a3a2241 --- /dev/null +++ b/common_components/linux_compat/freertos/freertos_linux.c @@ -0,0 +1,272 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include +#include +#include +#include +#include "osal/osal_api.h" + +static uint64_t s_semaphore_data = 0; + +typedef enum queue_type_tag { + MUTEX_REC, + MUTEX, + SEMA, + QUEUE, +} queue_type_t; + +struct generic_queue_handle { + queue_type_t type; + size_t item_size; + void *q; +}; + +static struct generic_queue_handle *create_generic_queue(queue_type_t type, uint32_t len, uint32_t item_size) +{ + struct generic_queue_handle *h = calloc(1, sizeof(struct generic_queue_handle)); + h->item_size = len; + h->type = type; + switch (type) { + default: + case QUEUE: + case SEMA: + h->q = osal_queue_create(); + break; + + case MUTEX: + case MUTEX_REC: + h->q = osal_mutex_create(); + break; + } + return h; +} + +QueueHandle_t xQueueCreate(uint32_t uxQueueLength, uint32_t uxItemSize ) +{ + return (QueueHandle_t)create_generic_queue(QUEUE, uxQueueLength, uxItemSize); +} + +uint32_t xQueueSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait) +{ + struct generic_queue_handle *h = xQueue; + return osal_queue_send(h->q, (uint8_t *)pvItemToQueue, h->item_size) ? pdTRUE : pdFAIL; +} + +uint32_t xQueueSendToBack(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ) +{ + return xQueueSend(xQueue, pvItemToQueue, xTicksToWait); +} + +uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait) +{ + struct generic_queue_handle *h = xQueue; + return osal_queue_recv(h->q, (uint8_t *)pvBuffer, h->item_size, xTicksToWait) ? pdTRUE : pdFAIL; +} + +BaseType_t xSemaphoreGive( QueueHandle_t xQueue) +{ + struct generic_queue_handle *h = xQueue; + if (h->type == MUTEX) { + osal_mutex_give(h->q); + return pdTRUE; + } + return xQueueSend(xQueue, &s_semaphore_data, portMAX_DELAY); +} + +BaseType_t xSemaphoreGiveRecursive( QueueHandle_t xQueue) +{ + struct generic_queue_handle *h = xQueue; + if (h->type == MUTEX_REC) { + osal_mutex_give(h->q); + return pdTRUE; + } + return pdFALSE; +} +BaseType_t xSemaphoreTake( QueueHandle_t xQueue, TickType_t pvTask ) +{ + struct generic_queue_handle *h = xQueue; + if (h->type == MUTEX) { + osal_mutex_take(h->q); + return pdTRUE; + } + return xQueueReceive(xQueue, &s_semaphore_data, portMAX_DELAY); +} + + +BaseType_t xSemaphoreTakeRecursive( QueueHandle_t xQueue, TickType_t pvTask ) +{ + struct generic_queue_handle *h = xQueue; + if (h->type == MUTEX_REC) { + osal_mutex_take(h->q); + return pdTRUE; + } + return pdFALSE; +} + + + + +void vQueueDelete( QueueHandle_t xQueue ) +{ + struct generic_queue_handle *h = xQueue; + if (h->q) { + if (h->type == MUTEX) { + osal_mutex_delete(h->q); + } else { + osal_queue_delete(h->q); + } + } + free(xQueue); +} + +QueueHandle_t xSemaphoreCreateBinary(void) +{ + QueueHandle_t sempaphore = xQueueCreate(1, 1); + return sempaphore; +} + +QueueHandle_t xSemaphoreCreateMutex(void) +{ + return (QueueHandle_t)create_generic_queue(MUTEX, 1, 1); +} + +QueueHandle_t xSemaphoreCreateRecursiveMutex(void) +{ + return (QueueHandle_t)create_generic_queue(MUTEX_REC, 1, 1); +} + + +void vTaskDelete(TaskHandle_t *task) +{ + if (task == NULL) { + pthread_exit(0); + } + void *thread_rval = NULL; + pthread_join((pthread_t)task, &thread_rval); +} + +void vTaskSuspend(void *task) +{ + vTaskDelete(task); +} + +TickType_t xTaskGetTickCount( void ) +{ + struct timespec spec; + clock_gettime(CLOCK_REALTIME, &spec); + return spec.tv_nsec / 1000000 + spec.tv_sec * 1000; +} + +void vTaskDelay( const TickType_t xTicksToDelay ) +{ + usleep(xTicksToDelay * 1000); +} + +void *pthread_task(void *params) +{ + struct { + void *const param; + TaskFunction_t task; + bool started; + } *pthread_params = params; + + void *const param = pthread_params->param; + TaskFunction_t task = pthread_params->task; + pthread_params->started = true; + + task(param); + + return NULL; +} + +BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode, + const char *const pcName, + const uint32_t usStackDepth, + void *const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t *const pvCreatedTask, + const BaseType_t xCoreID) +{ + xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask); + return pdTRUE; +} + + +BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char *const pcName, const uint32_t usStackDepth, void *const pvParameters, UBaseType_t uxPriority, TaskHandle_t *const pvCreatedTask) +{ + pthread_t new_thread = (pthread_t)NULL; + pthread_attr_t attr; + struct { + void *const param; + TaskFunction_t task; + bool started; + } pthread_params = { .param = pvParameters, .task = pvTaskCode}; + int res = pthread_attr_init(&attr); + assert(res == 0); + res = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + assert(res == 0); + res = pthread_create(&new_thread, &attr, pthread_task, &pthread_params); + assert(res == 0); + + if (pvCreatedTask) { + *pvCreatedTask = (void *)new_thread; + } + + // just wait till the task started so we can unwind params from the stack + while (pthread_params.started == false) { + usleep(1000); + } + return pdTRUE; +} + +void xTaskNotifyGive(TaskHandle_t task) +{ + +} + +BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time ) +{ + return true; +} + +TaskHandle_t xTaskGetCurrentTaskHandle(void) +{ + return NULL; +} + +EventGroupHandle_t xEventGroupCreate( void ) +{ + return osal_signal_create(); +} + +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) +{ + osal_signal_delete(xEventGroup); +} + +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) +{ + return osal_signal_clear(xEventGroup, uxBitsToClear); +} + +EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup) +{ + return osal_signal_get(xEventGroup); +} + +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ + return osal_signal_set(xEventGroup, uxBitsToSet); +} + +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) +{ + return osal_signal_wait(xEventGroup, uxBitsToWaitFor, xWaitForAllBits, xTicksToWait); +} diff --git a/components/mdns/tests/host_test/components/freertos/include/esp_task.h b/common_components/linux_compat/freertos/include/esp_task.h similarity index 87% rename from components/mdns/tests/host_test/components/freertos/include/esp_task.h rename to common_components/linux_compat/freertos/include/esp_task.h index f43cb4ceb..204be440d 100644 --- a/components/mdns/tests/host_test/components/freertos/include/esp_task.h +++ b/common_components/linux_compat/freertos/include/esp_task.h @@ -10,3 +10,4 @@ #define ESP_TASK_PRIO_MAX 25 #define ESP_TASKD_EVENT_PRIO 5 +#define ESP_TASKD_EVENT_STACK 1024 diff --git a/components/mdns/tests/host_test/components/freertos/include/freertos/FreeRTOS.h b/common_components/linux_compat/freertos/include/freertos/FreeRTOS.h similarity index 91% rename from components/mdns/tests/host_test/components/freertos/include/freertos/FreeRTOS.h rename to common_components/linux_compat/freertos/include/freertos/FreeRTOS.h index 6febf24ad..321863227 100644 --- a/components/mdns/tests/host_test/components/freertos/include/freertos/FreeRTOS.h +++ b/common_components/linux_compat/freertos/include/freertos/FreeRTOS.h @@ -16,7 +16,9 @@ typedef void *SemaphoreHandle_t; typedef void *QueueHandle_t; typedef void *TaskHandle_t; +typedef void *EventGroupHandle_t; typedef uint32_t TickType_t; +typedef TickType_t EventBits_t; typedef void (*TaskFunction_t)( void * ); typedef unsigned int UBaseType_t; diff --git a/common_components/linux_compat/freertos/include/freertos/event_groups.h b/common_components/linux_compat/freertos/include/freertos/event_groups.h new file mode 100644 index 000000000..de84a8145 --- /dev/null +++ b/common_components/linux_compat/freertos/include/freertos/event_groups.h @@ -0,0 +1,6 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once diff --git a/components/mdns/tests/host_test/components/freertos/include/freertos/queue.h b/common_components/linux_compat/freertos/include/freertos/queue.h similarity index 57% rename from components/mdns/tests/host_test/components/freertos/include/freertos/queue.h rename to common_components/linux_compat/freertos/include/freertos/queue.h index 38938e0c3..a767a2596 100644 --- a/components/mdns/tests/host_test/components/freertos/include/freertos/queue.h +++ b/common_components/linux_compat/freertos/include/freertos/queue.h @@ -3,11 +3,4 @@ * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ -// -// Created by david on 1/13/23. -// - -#ifndef _QUEUE_H_ -#define _QUEUE_H_ - -#endif //_QUEUE_H_ +#pragma once diff --git a/components/mdns/tests/host_test/components/freertos/include/freertos/semphr.h b/common_components/linux_compat/freertos/include/freertos/semphr.h similarity index 55% rename from components/mdns/tests/host_test/components/freertos/include/freertos/semphr.h rename to common_components/linux_compat/freertos/include/freertos/semphr.h index 175ee7e51..a767a2596 100644 --- a/components/mdns/tests/host_test/components/freertos/include/freertos/semphr.h +++ b/common_components/linux_compat/freertos/include/freertos/semphr.h @@ -3,11 +3,4 @@ * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ -// -// Created by david on 1/13/23. -// - -#ifndef _SEMAPHR_H_ -#define _SEMAPHR_H_ - -#endif //_SEMAPHR_H_ +#pragma once diff --git a/components/mdns/tests/host_test/components/freertos/include/freertos/task.h b/common_components/linux_compat/freertos/include/freertos/task.h similarity index 55% rename from components/mdns/tests/host_test/components/freertos/include/freertos/task.h rename to common_components/linux_compat/freertos/include/freertos/task.h index 91010f465..ee2b8d859 100644 --- a/components/mdns/tests/host_test/components/freertos/include/freertos/task.h +++ b/common_components/linux_compat/freertos/include/freertos/task.h @@ -26,7 +26,7 @@ BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode, TaskHandle_t *const pvCreatedTask, const BaseType_t xCoreID); -void xTaskCreate(TaskFunction_t pvTaskCode, const char *const pcName, const uint32_t usStackDepth, void *const pvParameters, UBaseType_t uxPriority, TaskHandle_t *const pvCreatedTask); +BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char *const pcName, const uint32_t usStackDepth, void *const pvParameters, UBaseType_t uxPriority, TaskHandle_t *const pvCreatedTask); TickType_t xTaskGetTickCount( void ); @@ -35,11 +35,16 @@ void vQueueDelete( QueueHandle_t xQueue ); QueueHandle_t xSemaphoreCreateBinary(void); QueueHandle_t xSemaphoreCreateMutex(void); +QueueHandle_t xSemaphoreCreateRecursiveMutex(void); BaseType_t xSemaphoreGive( QueueHandle_t xQueue); BaseType_t xSemaphoreTake( QueueHandle_t xQueue, TickType_t pvTask ); +BaseType_t xSemaphoreGiveRecursive( QueueHandle_t xQueue); + +BaseType_t xSemaphoreTakeRecursive( QueueHandle_t xQueue, TickType_t pvTask ); + void vTaskDelete(TaskHandle_t *task); QueueHandle_t xQueueCreate( uint32_t uxQueueLength, @@ -48,3 +53,23 @@ QueueHandle_t xQueueCreate( uint32_t uxQueueLength, uint32_t xQueueSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait); uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait); + +void vTaskSuspend(void *task); + +EventGroupHandle_t xEventGroupCreate( void ); +void vEventGroupDelete( EventGroupHandle_t xEventGroup ); +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ); + +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ); + +EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup); + +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ); + +uint32_t xQueueSendToBack(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ); diff --git a/common_components/linux_compat/freertos/osal/event_group.cpp b/common_components/linux_compat/freertos/osal/event_group.cpp new file mode 100644 index 000000000..24438416f --- /dev/null +++ b/common_components/linux_compat/freertos/osal/event_group.cpp @@ -0,0 +1,111 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "osal_api.h" + +struct SignalGroupInternal { + std::condition_variable notify; + std::mutex m; + uint32_t flags{ 0 }; +}; + +using SignalT = std::unique_ptr; + +class SignalGroup { +public: + + explicit SignalGroup(): event_group(std::make_unique()) {} + + void set(uint32_t bits) + { + std::unique_lock lock(event_group->m); + event_group->flags |= bits; + event_group->notify.notify_all(); + } + + uint32_t get() + { + return event_group->flags; + } + + void clear(uint32_t bits) + { + std::unique_lock lock(event_group->m); + event_group->flags &= ~bits; + event_group->notify.notify_all(); + } + + // waiting for all and clearing if set + bool wait(uint32_t flags, uint32_t time_ms) + { + std::unique_lock lock(event_group->m); + return event_group->notify.wait_for(lock, std::chrono::milliseconds(time_ms), [&] { + if ((flags & event_group->flags) == flags) + { + event_group->flags &= ~flags; + return true; + } + return false; + }); + } + + + // waiting for any bit, not clearing them + bool wait_any(uint32_t flags, uint32_t time_ms) + { + std::unique_lock lock(event_group->m); + return event_group->notify.wait_for(lock, std::chrono::milliseconds(time_ms), [&] { return flags & event_group->flags; }); + } + + ~SignalGroup() = default; + +private: + SignalT event_group; +}; + + +void *osal_signal_create() +{ + auto signal = new SignalGroup; + return signal; +} + +void osal_signal_delete(void *s) +{ + delete static_cast(s); +} + +uint32_t osal_signal_clear(void *s, uint32_t bits) +{ + auto signal = static_cast(s); + signal->clear(bits); + return signal->get(); +} + +uint32_t osal_signal_set(void *s, uint32_t bits) +{ + auto signal = static_cast(s); + signal->set(bits); + return signal->get(); +} + +uint32_t osal_signal_get(void *s) +{ + auto signal = static_cast(s); + return signal->get(); +} + +uint32_t osal_signal_wait(void *s, uint32_t flags, bool all, uint32_t timeout) +{ + auto signal = static_cast(s); + if (all) { + signal->wait(flags, timeout); + } else { + signal->wait_any(flags, timeout); + } + return signal->get(); +} diff --git a/common_components/linux_compat/freertos/osal/mutex.cpp b/common_components/linux_compat/freertos/osal/mutex.cpp new file mode 100644 index 000000000..23c8072a3 --- /dev/null +++ b/common_components/linux_compat/freertos/osal/mutex.cpp @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "osal_api.h" + +void *osal_mutex_create() +{ + auto mut = new std::recursive_mutex(); + return mut; +} + +void osal_mutex_delete(void *mut) +{ + delete static_cast(mut); +} + +void osal_mutex_take(void *m) +{ + auto mut = static_cast(m); + mut->lock(); +} + +void osal_mutex_give(void *m) +{ + auto mut = static_cast(m); + mut->unlock(); +} diff --git a/common_components/linux_compat/freertos/osal/osal_api.h b/common_components/linux_compat/freertos/osal/osal_api.h new file mode 100644 index 000000000..242226e04 --- /dev/null +++ b/common_components/linux_compat/freertos/osal/osal_api.h @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +// queue api +void *osal_queue_create(void); +void osal_queue_delete(void *q); +bool osal_queue_send(void *q, uint8_t *data, size_t len); +bool osal_queue_recv(void *q, uint8_t *data, size_t len, uint32_t ms); + +// mutex api +void *osal_mutex_create(void); +void osal_mutex_delete(void *m); +void osal_mutex_take(void *m); +void osal_mutex_give(void *m); + +// event groups +void *osal_signal_create(void); +void osal_signal_delete(void *s); +uint32_t osal_signal_clear(void *s, uint32_t bits); +uint32_t osal_signal_set(void *s, uint32_t bits); +uint32_t osal_signal_get(void *s); +uint32_t osal_signal_wait(void *s, uint32_t flags, bool all, uint32_t timeout); + +#ifdef __cplusplus +} +#endif diff --git a/common_components/linux_compat/freertos/osal/queue.cpp b/common_components/linux_compat/freertos/osal/queue.cpp new file mode 100644 index 000000000..2be3a9826 --- /dev/null +++ b/common_components/linux_compat/freertos/osal/queue.cpp @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "osal_api.h" + +template +class Queue { +public: + Queue(): q(), m(), c() {} + ~Queue() {} + + void send(std::unique_ptr t) + { + std::lock_guard lock(m); + q.push(std::move(t)); + c.notify_one(); + } + + std::unique_ptr receive(uint32_t ms) + { + std::unique_lock lock(m); + while (q.empty()) { + if (c.wait_for(lock, std::chrono::milliseconds(ms)) == std::cv_status::timeout) { + return nullptr; + } + } + std::unique_ptr val = std::move(q.front()); + q.pop(); + return val; + } + +private: + std::queue> q; + mutable std::mutex m; + std::condition_variable c; +}; + +void *osal_queue_create(void) +{ + auto *q = new Queue>(); + return q; +} + +void osal_queue_delete(void *q) +{ + auto *queue = static_cast> *>(q); + delete (queue); +} + +bool osal_queue_send(void *q, uint8_t *data, size_t len) +{ + auto v = std::make_unique>(len); + v->assign(data, data + len); + auto queue = static_cast> *>(q); + queue->send(std::move(v)); + return true; +} + + +bool osal_queue_recv(void *q, uint8_t *data, size_t len, uint32_t ms) +{ + auto queue = static_cast> *>(q); + auto v = queue->receive(ms); + if (v == nullptr) { + return false; + } + memcpy(data, (void *)v->data(), len); + return true; +} diff --git a/components/mdns/tests/host_test/CMakeLists.txt b/components/mdns/tests/host_test/CMakeLists.txt index 8575ac333..ec230d2f9 100644 --- a/components/mdns/tests/host_test/CMakeLists.txt +++ b/components/mdns/tests/host_test/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.5) -set(EXTRA_COMPONENT_DIRS "../..") +set(EXTRA_COMPONENT_DIRS "../.. ../../../../common_components/linux_compat/freertos") include($ENV{IDF_PATH}/tools/cmake/project.cmake) set(COMPONENTS main esp_netif_linux) diff --git a/components/mdns/tests/host_test/components/freertos/freertos_linux.c b/components/mdns/tests/host_test/components/freertos/freertos_linux.c deleted file mode 100644 index fcba4416e..000000000 --- a/components/mdns/tests/host_test/components/freertos/freertos_linux.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include -#include -#include -#include - -void *create_q(void); - -void destroy_q(void *q); - -bool send_q(void *q, uint8_t *data, size_t len); - -bool recv_q(void *q, uint8_t *data, size_t len, uint32_t ms); - -static uint64_t s_semaphore_data = 0; - -struct queue_handle { - size_t item_size; - void *q; -}; - -QueueHandle_t xQueueCreate( uint32_t uxQueueLength, uint32_t uxItemSize ) -{ - struct queue_handle *h = calloc(1, sizeof(struct queue_handle)); - h->item_size = uxItemSize; - h->q = create_q(); - return (QueueHandle_t)h; -} - -uint32_t xQueueSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait) -{ - struct queue_handle *h = xQueue; - return send_q(h->q, (uint8_t *)pvItemToQueue, h->item_size) ? pdTRUE : pdFAIL; -} - -uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait) -{ - struct queue_handle *h = xQueue; - return recv_q(h->q, (uint8_t *)pvBuffer, h->item_size, xTicksToWait) ? pdTRUE : pdFAIL; -} - -BaseType_t xSemaphoreGive( QueueHandle_t xQueue) -{ - return xQueueSend(xQueue, &s_semaphore_data, portMAX_DELAY); -} - -BaseType_t xSemaphoreTake( QueueHandle_t xQueue, TickType_t pvTask ) -{ - return xQueueReceive(xQueue, &s_semaphore_data, portMAX_DELAY); -} - -void vQueueDelete( QueueHandle_t xQueue ) -{ - struct queue_handle *h = xQueue; - if (h->q) { - destroy_q(h->q); - } - free(xQueue); -} - -QueueHandle_t xSemaphoreCreateBinary(void) -{ - QueueHandle_t sempaphore = xQueueCreate(1, 1); - return sempaphore; -} - -QueueHandle_t xSemaphoreCreateMutex(void) -{ - QueueHandle_t sempaphore = xQueueCreate(1, 1); - if (sempaphore) { - xSemaphoreGive(sempaphore); - } - return sempaphore; -} - -void vTaskDelete(TaskHandle_t *task) -{ - if (task == NULL) { - pthread_exit(0); - } - void *thread_rval = NULL; - pthread_join((pthread_t)task, &thread_rval); -} - -TickType_t xTaskGetTickCount( void ) -{ - struct timespec spec; - clock_gettime(CLOCK_REALTIME, &spec); - return spec.tv_nsec / 1000000 + spec.tv_sec * 1000; -} - -void vTaskDelay( const TickType_t xTicksToDelay ) -{ - usleep(xTicksToDelay * 1000); -} - -void *pthread_task(void *params) -{ - struct { - void *const param; - TaskFunction_t task; - bool started; - } *pthread_params = params; - - void *const param = pthread_params->param; - TaskFunction_t task = pthread_params->task; - pthread_params->started = true; - - task(param); - - return NULL; -} - -BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode, - const char *const pcName, - const uint32_t usStackDepth, - void *const pvParameters, - UBaseType_t uxPriority, - TaskHandle_t *const pvCreatedTask, - const BaseType_t xCoreID) -{ - xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask); - return pdTRUE; -} - - -void xTaskCreate(TaskFunction_t pvTaskCode, const char *const pcName, const uint32_t usStackDepth, void *const pvParameters, UBaseType_t uxPriority, TaskHandle_t *const pvCreatedTask) -{ - pthread_t new_thread = (pthread_t)NULL; - pthread_attr_t attr; - struct { - void *const param; - TaskFunction_t task; - bool started; - } pthread_params = { .param = pvParameters, .task = pvTaskCode}; - int res = pthread_attr_init(&attr); - assert(res == 0); - res = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - assert(res == 0); - res = pthread_create(&new_thread, &attr, pthread_task, &pthread_params); - assert(res == 0); - - if (pvCreatedTask) { - *pvCreatedTask = (void *)new_thread; - } - - // just wait till the task started so we can unwind params from the stack - while (pthread_params.started == false) { - usleep(1000); - } -} - -void xTaskNotifyGive(TaskHandle_t task) -{ - -} - -BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time ) -{ - return true; -} - -TaskHandle_t xTaskGetCurrentTaskHandle(void) -{ - return NULL; -} diff --git a/components/mdns/tests/host_test/components/freertos/queue_unique_ptr.cpp b/components/mdns/tests/host_test/components/freertos/queue_unique_ptr.cpp deleted file mode 100644 index 56eef6d17..000000000 --- a/components/mdns/tests/host_test/components/freertos/queue_unique_ptr.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "queue_unique_ptr.hpp" -#include -#include -#include -#include - -extern "C" void *create_q(void) -{ - auto *q = new QueueMock>(); - return q; -} - -extern "C" void destroy_q(void *q) -{ - auto *queue = static_cast> *>(q); - delete (queue); -} - -extern "C" bool send_q(void *q, uint8_t *data, size_t len) -{ - auto v = std::make_unique>(len); - v->assign(data, data + len); - auto queue = static_cast> *>(q); - queue->send(std::move(v)); - return true; -} - -extern "C" bool recv_q(void *q, uint8_t *data, size_t len, uint32_t ms) -{ - auto queue = static_cast> *>(q); - auto v = queue->receive(ms); - if (v == nullptr) { - return false; - } - memcpy(data, (void *)v->data(), len); - return true; -} diff --git a/components/mdns/tests/host_test/components/freertos/queue_unique_ptr.hpp b/components/mdns/tests/host_test/components/freertos/queue_unique_ptr.hpp deleted file mode 100644 index 67fb02b99..000000000 --- a/components/mdns/tests/host_test/components/freertos/queue_unique_ptr.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -template -class QueueMock { -public: - QueueMock(void): q(), m(), c() {} - ~QueueMock(void) {} - - void send(std::unique_ptr t) - { - std::lock_guard lock(m); - q.push(std::move(t)); - c.notify_one(); - } - - std::unique_ptr receive(uint32_t ms) - { - std::unique_lock lock(m); - while (q.empty()) { - if (c.wait_for(lock, std::chrono::milliseconds(ms)) == std::cv_status::timeout) { - return nullptr; - } - } - std::unique_ptr val = std::move(q.front()); - q.pop(); - return val; - } - -private: - std::queue> q; - mutable std::mutex m; - std::condition_variable c; -};