You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
2.3 KiB
101 lines
2.3 KiB
/* |
|
* 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); |
|
}
|
|
|