LCOV - code coverage report
Current view: top level - zephyr/sys - p4wq.h Coverage Total Hit
Test: new.info Lines: 31.0 % 42 13
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2020 Intel Corporation
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : #ifndef ZEPHYR_INCLUDE_SYS_P4WQ_H_
       7              : #define ZEPHYR_INCLUDE_SYS_P4WQ_H_
       8              : 
       9              : #include <zephyr/kernel.h>
      10              : #include <zephyr/sys/iterable_sections.h>
      11              : 
      12              : /* Zephyr Pooled Parallel Preemptible Priority-based Work Queues */
      13              : 
      14              : struct k_p4wq_work;
      15              : 
      16              : /**
      17              :  * P4 Queue handler callback
      18              :  */
      19            1 : typedef void (*k_p4wq_handler_t)(struct k_p4wq_work *work);
      20              : 
      21              : /**
      22              :  * Optional P4 Queue done callback.
      23              :  * Will be called after the memory structure is not used anymore by the p4wq.
      24              :  * If it is not used it must be set to NULL.
      25              :  */
      26            1 : typedef void (*k_p4wq_done_handler_t)(struct k_p4wq_work *work);
      27              : 
      28              : /**
      29              :  * @brief P4 Queue Work Item
      30              :  *
      31              :  * User-populated struct representing a single work item.  The
      32              :  * priority and deadline fields are interpreted as thread scheduling
      33              :  * priorities, exactly as per k_thread_priority_set() and
      34              :  * k_thread_deadline_set().
      35              :  */
      36            1 : struct k_p4wq_work {
      37              :         /* Filled out by submitting code */
      38            0 :         int32_t priority;
      39            0 :         int32_t deadline;
      40            0 :         k_p4wq_handler_t handler;
      41            0 :         bool sync;
      42            0 :         struct k_sem done_sem;
      43              : 
      44              :         /* reserved for implementation */
      45              :         union {
      46            0 :                 struct rbnode rbnode;
      47            0 :                 sys_dlist_t dlnode;
      48            0 :         };
      49            0 :         struct k_thread *thread;
      50            0 :         struct k_p4wq *queue;
      51              : };
      52              : 
      53            0 : #define K_P4WQ_QUEUE_PER_THREAD         BIT(0)
      54            0 : #define K_P4WQ_DELAYED_START            BIT(1)
      55            0 : #define K_P4WQ_USER_CPU_MASK            BIT(2)
      56              : 
      57              : /**
      58              :  * @brief P4 Queue
      59              :  *
      60              :  * Kernel pooled parallel preemptible priority-based work queue
      61              :  */
      62            1 : struct k_p4wq {
      63            0 :         struct k_spinlock lock;
      64              : 
      65              :         /* Pending threads waiting for work items
      66              :          *
      67              :          * FIXME: a waitq isn't really the right data structure here.
      68              :          * Wait queues are priority-sorted, but we don't want that
      69              :          * sorting overhead since we're effectively doing it ourselves
      70              :          * by directly mutating the priority when a thread is
      71              :          * unpended.  We just want "blocked threads on a list", but
      72              :          * there's no clean scheduler API for that.
      73              :          */
      74            0 :         _wait_q_t waitq;
      75              : 
      76              :         /* Work items waiting for processing */
      77            0 :         struct rbtree queue;
      78              : 
      79              :         /* Work items in progress */
      80            0 :         sys_dlist_t active;
      81              : 
      82              :         /* K_P4WQ_* flags above */
      83            0 :         uint32_t flags;
      84              : 
      85              :         /* done handler which is called every time after work was successfully executed
      86              :          * and k_p4wq_work is not needed by p4wq anymore
      87              :          */
      88            0 :         k_p4wq_done_handler_t done_handler;
      89              : };
      90              : 
      91            0 : struct k_p4wq_initparam {
      92            0 :         uint32_t num;
      93            0 :         uintptr_t stack_size;
      94            0 :         struct k_p4wq *queue;
      95            0 :         struct k_thread *threads;
      96            0 :         struct z_thread_stack_element *stacks;
      97            0 :         uint32_t flags;
      98            0 :         k_p4wq_done_handler_t done_handler;
      99              : };
     100              : 
     101              : /**
     102              :  * @brief Statically initialize a P4 Work Queue
     103              :  *
     104              :  * Statically defines a struct k_p4wq object with the specified number
     105              :  * of threads which will be initialized at boot and ready for use on
     106              :  * entry to main().
     107              :  *
     108              :  * @param name Symbol name of the struct k_p4wq that will be defined
     109              :  * @param n_threads Number of threads in the work queue pool
     110              :  * @param stack_sz Requested stack size of each thread, in bytes
     111              :  * @param dn_handler Function pointer to handler of type k_p4wq_done_handler_t
     112              :  */
     113            1 : #define K_P4WQ_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, dn_handler)                  \
     114              :         static K_THREAD_STACK_ARRAY_DEFINE(_p4stacks_##name,            \
     115              :                                            n_threads, stack_sz);        \
     116              :         static struct k_thread _p4threads_##name[n_threads];            \
     117              :         static struct k_p4wq name;                                      \
     118              :         static const STRUCT_SECTION_ITERABLE(k_p4wq_initparam,          \
     119              :                                              _init_##name) = {          \
     120              :                 .num = n_threads,                                       \
     121              :                 .stack_size = stack_sz,                                 \
     122              :                 .threads = _p4threads_##name,                           \
     123              :                 .stacks = &(_p4stacks_##name[0][0]),                        \
     124              :                 .queue = &name,                                             \
     125              :                 .flags = 0,                                             \
     126              :                 .done_handler = dn_handler,                     \
     127              :         }
     128              : 
     129              : /**
     130              :  * @brief Statically initialize a P4 Work Queue
     131              :  *
     132              :  * Same like K_P4WQ_DEFINE_WITH_DONE_HANDLER but without an
     133              :  * optional handler which is called everytime when work is executed
     134              :  * and not used anymore by the p4wq
     135              :  */
     136            1 : #define K_P4WQ_DEFINE(name, n_threads, stack_sz)                        \
     137              :         K_P4WQ_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, NULL)
     138              : 
     139              : /**
     140              :  * @brief Statically initialize an array of P4 Work Queues
     141              :  *
     142              :  * Statically defines an array of struct k_p4wq objects with the specified
     143              :  * number of threads which will be initialized at boot and ready for use on
     144              :  * entry to main().
     145              :  *
     146              :  * @param name Symbol name of the struct k_p4wq array that will be defined
     147              :  * @param n_threads Number of threads and work queues
     148              :  * @param stack_sz Requested stack size of each thread, in bytes
     149              :  * @param flg Flags
     150              :  * @param dn_handler Function pointer to handler of type k_p4wq_done_handler_t
     151              :  */
     152            1 : #define K_P4WQ_ARRAY_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, flg, dn_handler) \
     153              :         static K_THREAD_STACK_ARRAY_DEFINE(_p4stacks_##name,            \
     154              :                                            n_threads, stack_sz);        \
     155              :         static struct k_thread _p4threads_##name[n_threads];            \
     156              :         static struct k_p4wq name[n_threads];                           \
     157              :         static const STRUCT_SECTION_ITERABLE(k_p4wq_initparam,          \
     158              :                                              _init_##name) = {          \
     159              :                 .num = n_threads,                                       \
     160              :                 .stack_size = stack_sz,                                 \
     161              :                 .threads = _p4threads_##name,                           \
     162              :                 .stacks = &(_p4stacks_##name[0][0]),                        \
     163              :                 .queue = name,                                          \
     164              :                 .flags = K_P4WQ_QUEUE_PER_THREAD | flg,                 \
     165              :                 .done_handler = dn_handler,                                                     \
     166              :         }
     167              : 
     168              : /**
     169              :  * @brief Statically initialize an array of P4 Work Queues
     170              :  *
     171              :  * Same like K_P4WQ_ARRAY_DEFINE_WITH_DONE_HANDLER but without an
     172              :  * optional handler which is called everytime when work is executed
     173              :  * and not used anymore by the p4wq
     174              :  */
     175            1 : #define K_P4WQ_ARRAY_DEFINE(name, n_threads, stack_sz, flg)             \
     176              :         K_P4WQ_ARRAY_DEFINE_WITH_DONE_HANDLER(name, n_threads, stack_sz, flg, NULL)
     177              : 
     178              : /**
     179              :  * @brief Initialize P4 Queue
     180              :  *
     181              :  * Initializes a P4 Queue object.  These objects must be initialized
     182              :  * via this function (or statically using K_P4WQ_DEFINE) before any
     183              :  * other API calls are made on it.
     184              :  *
     185              :  * @param queue P4 Queue to initialize
     186              :  */
     187            1 : void k_p4wq_init(struct k_p4wq *queue);
     188              : 
     189              : /**
     190              :  * @brief Dynamically add a thread object to a P4 Queue pool
     191              :  *
     192              :  * Adds a thread to the pool managed by a P4 queue.  The thread object
     193              :  * must not be in use.  If k_thread_create() has previously been
     194              :  * called on it, it must be aborted before being given to the queue.
     195              :  *
     196              :  * @param queue P4 Queue to which to add the thread
     197              :  * @param thread Uninitialized/aborted thread object to add
     198              :  * @param stack Thread stack memory
     199              :  * @param stack_size Thread stack size
     200              :  */
     201            1 : void k_p4wq_add_thread(struct k_p4wq *queue, struct k_thread *thread,
     202              :                        k_thread_stack_t *stack,
     203              :                        size_t stack_size);
     204              : 
     205              : /**
     206              :  * @brief Submit work item to a P4 queue
     207              :  *
     208              :  * Submits the specified work item to the queue.  The caller must have
     209              :  * already initialized the relevant fields of the struct.  The queue
     210              :  * will execute the handler when CPU time is available and when no
     211              :  * higher-priority work items are available.  The handler may be
     212              :  * invoked on any CPU.
     213              :  *
     214              :  * The caller must not mutate the struct while it is stored in the
     215              :  * queue.  The memory should remain unchanged until k_p4wq_cancel() is
     216              :  * called or until the entry to the handler function.
     217              :  *
     218              :  * @note This call is a scheduling point, so if the submitted item (or
     219              :  * any other ready thread) has a higher priority than the current
     220              :  * thread and the current thread has a preemptible priority then the
     221              :  * caller will yield.
     222              :  *
     223              :  * @param queue P4 Queue to which to submit
     224              :  * @param item P4 work item to be submitted
     225              :  */
     226            1 : void k_p4wq_submit(struct k_p4wq *queue, struct k_p4wq_work *item);
     227              : 
     228              : /**
     229              :  * @brief Cancel submitted P4 work item
     230              :  *
     231              :  * Cancels a previously-submitted work item and removes it from the
     232              :  * queue.  Returns true if the item was found in the queue and
     233              :  * removed.  If the function returns false, either the item was never
     234              :  * submitted, has already been executed, or is still running.
     235              :  *
     236              :  * @return true if the item was successfully removed, otherwise false
     237              :  */
     238            1 : bool k_p4wq_cancel(struct k_p4wq *queue, struct k_p4wq_work *item);
     239              : 
     240              : /**
     241              :  * @brief Regain ownership of the work item, wait for completion if it's synchronous
     242              :  */
     243            1 : int k_p4wq_wait(struct k_p4wq_work *work, k_timeout_t timeout);
     244              : 
     245            0 : void k_p4wq_enable_static_thread(struct k_p4wq *queue, struct k_thread *thread,
     246              :                                  uint32_t cpu_mask);
     247              : 
     248              : #endif /* ZEPHYR_INCLUDE_SYS_P4WQ_H_ */
        

Generated by: LCOV version 2.0-1