LCOV - code coverage report
Current view: top level - zephyr/sys - p4wq.h Hit Total Coverage
Test: new.info Lines: 10 37 27.0 %
Date: 2024-12-22 00:14:23

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

Generated by: LCOV version 1.14