blob: 7c17ef5491c7ce38324bea23d6a2b0654a7e6aee [file] [log] [blame]
/*
* Copyright (c) 2024 Croxel Inc.
* Copyright (c) 2025 Croxel Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/rtio/work.h>
#include <zephyr/kernel.h>
K_MEM_SLAB_DEFINE_STATIC(rtio_work_items_slab,
sizeof(struct rtio_work_req),
CONFIG_RTIO_WORKQ_POOL_ITEMS,
4);
static K_THREAD_STACK_ARRAY_DEFINE(rtio_workq_threads_stack,
CONFIG_RTIO_WORKQ_THREADS_POOL,
CONFIG_RTIO_WORKQ_THREADS_POOL_STACK_SIZE);
static struct k_thread rtio_work_threads[CONFIG_RTIO_WORKQ_THREADS_POOL];
static K_QUEUE_DEFINE(rtio_workq);
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;
}
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;
}
req->iodev_sqe = iodev_sqe;
req->handler = handler;
/** For now we're simply treating this as a FIFO queue. It may be
* desirable to expand this to handle queue ordering based on RTIO
* SQE priority.
*/
k_queue_append(&rtio_workq, req);
}
uint32_t rtio_work_req_used_count_get(void)
{
return k_mem_slab_num_used_get(&rtio_work_items_slab);
}
static void rtio_workq_thread_fn(void *arg1, void *arg2, void *arg3)
{
ARG_UNUSED(arg1);
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
while (true) {
struct rtio_work_req *req = k_queue_get(&rtio_workq, K_FOREVER);
if (req != NULL) {
req->handler(req->iodev_sqe);
k_mem_slab_free(&rtio_work_items_slab, req);
}
}
}
static int static_init(void)
{
for (size_t i = 0 ; i < ARRAY_SIZE(rtio_work_threads) ; i++) {
k_thread_create(&rtio_work_threads[i],
rtio_workq_threads_stack[i],
CONFIG_RTIO_WORKQ_THREADS_POOL_STACK_SIZE,
rtio_workq_thread_fn,
NULL, NULL, NULL,
CONFIG_RTIO_WORKQ_THREADS_POOL_PRIO,
0,
K_NO_WAIT);
}
return 0;
}
SYS_INIT(static_init, POST_KERNEL, 1);