mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-09-02 07:22:28 +00:00
This commit fixes the bug that the memory of the work request is freed up in the work handler, before it is not needed anymore by the p4wq. This is fixed now, by using the new done_handler in the p4wq for freeing up that memory. Signed-off-by: Florian Weber <Florian.Weber@live.de>
102 lines
2.3 KiB
C
102 lines
2.3 KiB
C
/*
|
|
* Copyright (c) 2024 Croxel Inc.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/rtio/work.h>
|
|
#include <zephyr/kernel.h>
|
|
|
|
#define RTIO_WORKQ_PRIO_MED CONFIG_RTIO_WORKQ_PRIO_MED
|
|
#define RTIO_WORKQ_PRIO_HIGH RTIO_WORKQ_PRIO_MED - 1
|
|
#define RTIO_WORKQ_PRIO_LOW RTIO_WORKQ_PRIO_MED + 1
|
|
|
|
K_MEM_SLAB_DEFINE_STATIC(rtio_work_items_slab,
|
|
sizeof(struct rtio_work_req),
|
|
CONFIG_RTIO_WORKQ_POOL_ITEMS,
|
|
4);
|
|
|
|
static void rtio_work_req_done_handler(struct k_p4wq_work *work)
|
|
{
|
|
struct rtio_work_req *req = CONTAINER_OF(work,
|
|
struct rtio_work_req,
|
|
work);
|
|
k_mem_slab_free(&rtio_work_items_slab, req);
|
|
}
|
|
|
|
K_P4WQ_DEFINE_WITH_DONE_HANDLER(rtio_workq,
|
|
CONFIG_RTIO_WORKQ_THREADS_POOL,
|
|
CONFIG_RTIO_WORKQ_STACK_SIZE,
|
|
rtio_work_req_done_handler);
|
|
|
|
static void rtio_work_handler(struct k_p4wq_work *work)
|
|
{
|
|
struct rtio_work_req *req = CONTAINER_OF(work,
|
|
struct rtio_work_req,
|
|
work);
|
|
struct rtio_iodev_sqe *iodev_sqe = req->iodev_sqe;
|
|
|
|
req->handler(iodev_sqe);
|
|
}
|
|
|
|
struct rtio_work_req *rtio_work_req_alloc(void)
|
|
{
|
|
struct rtio_work_req *req;
|
|
int err;
|
|
|
|
err = k_mem_slab_alloc(&rtio_work_items_slab, (void **)&req, K_NO_WAIT);
|
|
if (err) {
|
|
return NULL;
|
|
}
|
|
|
|
/** Initialize work item before using it as it comes
|
|
* from a Memory slab (no-init region).
|
|
*/
|
|
req->work.thread = NULL;
|
|
(void)k_sem_init(&req->work.done_sem, 1, 1);
|
|
|
|
return req;
|
|
}
|
|
|
|
void rtio_work_req_submit(struct rtio_work_req *req,
|
|
struct rtio_iodev_sqe *iodev_sqe,
|
|
rtio_work_submit_t handler)
|
|
{
|
|
if (!req) {
|
|
return;
|
|
}
|
|
|
|
if (!iodev_sqe || !handler) {
|
|
k_mem_slab_free(&rtio_work_items_slab, req);
|
|
return;
|
|
}
|
|
|
|
struct k_p4wq_work *work = &req->work;
|
|
struct rtio_sqe *sqe = &iodev_sqe->sqe;
|
|
|
|
/** Link the relevant info so that we can get it on the k_p4wq_work work item.
|
|
*/
|
|
req->iodev_sqe = iodev_sqe;
|
|
req->handler = handler;
|
|
|
|
/** Set the required information to handle the action */
|
|
work->handler = rtio_work_handler;
|
|
work->deadline = 0;
|
|
|
|
if (sqe->prio == RTIO_PRIO_LOW) {
|
|
work->priority = RTIO_WORKQ_PRIO_LOW;
|
|
} else if (sqe->prio == RTIO_PRIO_HIGH) {
|
|
work->priority = RTIO_WORKQ_PRIO_HIGH;
|
|
} else {
|
|
work->priority = RTIO_WORKQ_PRIO_MED;
|
|
}
|
|
|
|
/** Decoupling action: Let the P4WQ execute the action. */
|
|
k_p4wq_submit(&rtio_workq, work);
|
|
}
|
|
|
|
uint32_t rtio_work_req_used_count_get(void)
|
|
{
|
|
return k_mem_slab_num_used_get(&rtio_work_items_slab);
|
|
}
|