From b706a5e9995b54d74be650dc4980c38defa0e160 Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Tue, 24 Nov 2020 16:47:47 -0600 Subject: [PATCH] kernel: remove old work queue implementation Now that the old API has been reimplemented with the new API remove the old implementation and its tests. Signed-off-by: Peter Bigot --- doc/zephyr.doxyfile.in | 1 - include/kernel.h | 449 ----- kernel/CMakeLists.txt | 4 +- kernel/Kconfig | 18 - kernel/system_work_q.c | 9 - kernel/work_q.c | 139 -- lib/os/CMakeLists.txt | 7 +- subsys/net/ip/tcp2.c | 14 +- tests/kernel/workq/user_work/prj.conf | 1 - tests/kernel/workq/user_work/testcase.yaml | 1 - tests/kernel/workq/work/prj.conf | 1 - tests/kernel/workq/work/testcase.yaml | 1 - .../workq/work_queue_api/CMakeLists.txt | 8 - tests/kernel/workq/work_queue_api/prj.conf | 9 - tests/kernel/workq/work_queue_api/src/main.c | 1564 ----------------- .../kernel/workq/work_queue_api/testcase.yaml | 5 - 16 files changed, 6 insertions(+), 2225 deletions(-) delete mode 100644 kernel/work_q.c delete mode 100644 tests/kernel/workq/work_queue_api/CMakeLists.txt delete mode 100644 tests/kernel/workq/work_queue_api/prj.conf delete mode 100644 tests/kernel/workq/work_queue_api/src/main.c delete mode 100644 tests/kernel/workq/work_queue_api/testcase.yaml diff --git a/doc/zephyr.doxyfile.in b/doc/zephyr.doxyfile.in index 20c56189ce1..3ee6cee14e2 100644 --- a/doc/zephyr.doxyfile.in +++ b/doc/zephyr.doxyfile.in @@ -1973,7 +1973,6 @@ PREDEFINED = "CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT" \ "CONFIG_FPU" \ "CONFIG_FPU_SHARING" \ "CONFIG_HEAP_MEM_POOL_SIZE" \ - "CONFIG_KERNEL_WORK2" \ "CONFIG_MMU" \ "CONFIG_NET_L2_ETHERNET_MGMT" \ "CONFIG_NET_MGMT_EVENT" \ diff --git a/include/kernel.h b/include/kernel.h index 2d34166f4cd..3ebd63b4282 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -2496,451 +2496,6 @@ extern struct k_work_q k_sys_work_q; * INTERNAL_HIDDEN @endcond */ -#ifdef CONFIG_KERNEL_WORK1 - -/** - * @addtogroup thread_apis - * @{ - */ - -/** - * @typedef k_work_handler_t - * @brief Work item handler function type. - * - * A work item's handler function is executed by a workqueue's thread - * when the work item is processed by the workqueue. - * - * @param work Address of the work item. - * - * @return N/A - */ -typedef void (*k_work_handler_t)(struct k_work *work); - -/** - * @cond INTERNAL_HIDDEN - */ - -struct k_work_q { - struct k_queue queue; - struct k_thread thread; -}; - -enum { - K_WORK_STATE_PENDING, /* Work item pending state */ -}; - -struct k_work { - void *_reserved; /* Used by k_queue implementation. */ - k_work_handler_t handler; - atomic_t flags[1]; -}; - -struct k_delayed_work { - struct k_work work; - struct _timeout timeout; - struct k_work_q *work_q; -}; - -/** - * INTERNAL_HIDDEN @endcond - */ - -#define Z_WORK_INITIALIZER(work_handler) \ - { \ - ._reserved = NULL, \ - .handler = work_handler, \ - .flags = { 0 } \ - } - -/** - * @brief Initialize a work item. - * - * This routine initializes a workqueue work item, prior to its first use. - * - * @param work Address of work item. - * @param handler Function to invoke each time work item is processed. - * - * @return N/A - */ -static inline void k_work_init(struct k_work *work, k_work_handler_t handler) -{ - *work = (struct k_work)Z_WORK_INITIALIZER(handler); -} - -/** - * @brief Submit a work item. - * - * This routine submits work item @p work to be processed by workqueue @p - * work_q. If the work item is already pending in @p work_q or any other - * workqueue as a result of an earlier submission, this routine has no - * effect on the work item. If the work item has already been processed, or - * is currently being processed, its work is considered complete and the - * work item can be resubmitted. - * - * @warning - * A submitted work item must not be modified until it has been processed - * by the workqueue. - * - * @note Can be called by ISRs. - * - * @param work_q Address of workqueue. - * @param work Address of work item. - * - * @return N/A - */ -static inline void k_work_submit_to_queue(struct k_work_q *work_q, - struct k_work *work) -{ - if (!atomic_test_and_set_bit(work->flags, K_WORK_STATE_PENDING)) { - k_queue_append(&work_q->queue, work); - } -} - -/** - * @brief Submit a work item to a user mode workqueue - * - * Submits a work item to a workqueue that runs in user mode. A temporary - * memory allocation is made from the caller's resource pool which is freed - * once the worker thread consumes the k_work item. The workqueue - * thread must have memory access to the k_work item being submitted. The caller - * must have permission granted on the work_q parameter's queue object. - * - * Otherwise this works the same as k_work_submit_to_queue(). - * - * @note Can be called by ISRs. - * - * @param work_q Address of workqueue. - * @param work Address of work item. - * - * @retval -EBUSY if the work item was already in some workqueue - * @retval -ENOMEM if no memory for thread resource pool allocation - * @retval 0 Success - */ -static inline int k_work_submit_to_user_queue(struct k_work_q *work_q, - struct k_work *work) -{ - int ret = -EBUSY; - - if (!atomic_test_and_set_bit(work->flags, K_WORK_STATE_PENDING)) { - ret = k_queue_alloc_append(&work_q->queue, work); - - /* Couldn't insert into the queue. Clear the pending bit - * so the work item can be submitted again - */ - if (ret != 0) { - atomic_clear_bit(work->flags, K_WORK_STATE_PENDING); - } - } - - return ret; -} - -/** - * @brief Check if a work item is pending. - * - * This routine indicates if work item @a work is pending in a workqueue's - * queue. - * - * @note Checking if the work is pending gives no guarantee that the - * work will still be pending when this information is used. It is up to - * the caller to make sure that this information is used in a safe manner. - * - * @note Can be called by ISRs. - * - * @param work Address of work item. - * - * @return true if work item is pending, or false if it is not pending. - */ -static inline bool k_work_pending(struct k_work *work) -{ - return atomic_test_bit(work->flags, K_WORK_STATE_PENDING); -} - -/** - * @brief Check if a delayed work item is pending. - * - * This routine indicates if the work item @a work is pending in a workqueue's - * queue or waiting for the delay timeout. - * - * @note Checking if the delayed work is pending gives no guarantee that the - * work will still be pending when this information is used. It is up to - * the caller to make sure that this information is used in a safe manner. - * - * @note Can be called by ISRs. - * - * @param work Address of delayed work item. - * - * @return true if work item is waiting for the delay to expire or pending on a - * work queue, or false if it is not pending. - */ -bool k_delayed_work_pending(struct k_delayed_work *work); - -/** - * @brief Start a workqueue. - * - * This routine starts workqueue @a work_q. The workqueue spawns its work - * processing thread, which runs forever. - * - * @param work_q Address of workqueue. - * @param stack Pointer to work queue thread's stack space, as defined by - * K_THREAD_STACK_DEFINE() - * @param stack_size Size of the work queue thread's stack (in bytes), which - * should either be the same constant passed to - * K_THREAD_STACK_DEFINE() or the value of K_THREAD_STACK_SIZEOF(). - * @param prio Priority of the work queue's thread. - * - * @return N/A - */ -extern void k_work_q_start(struct k_work_q *work_q, - k_thread_stack_t *stack, - size_t stack_size, int prio); - -/** - * @brief Start a workqueue in user mode - * - * This works identically to k_work_q_start() except it is callable from user - * mode, and the worker thread created will run in user mode. - * The caller must have permissions granted on both the work_q parameter's - * thread and queue objects, and the same restrictions on priority apply as - * k_thread_create(). - * - * @param work_q Address of workqueue. - * @param stack Pointer to work queue thread's stack space, as defined by - * K_THREAD_STACK_DEFINE() - * @param stack_size Size of the work queue thread's stack (in bytes), which - * should either be the same constant passed to - * K_THREAD_STACK_DEFINE() or the value of K_THREAD_STACK_SIZEOF(). - * @param prio Priority of the work queue's thread. - * - * @return N/A - */ -extern void k_work_q_user_start(struct k_work_q *work_q, - k_thread_stack_t *stack, - size_t stack_size, int prio); - -#define Z_DELAYED_WORK_INITIALIZER(work_handler) \ - { \ - .work = Z_WORK_INITIALIZER(work_handler), \ - .timeout = { \ - .node = {},\ - .fn = NULL, \ - .dticks = 0, \ - }, \ - .work_q = NULL, \ - } - -/** - * @brief Initialize a delayed work item. - * - * This routine initializes a workqueue delayed work item, prior to - * its first use. - * - * @param work Address of delayed work item. - * @param handler Function to invoke each time work item is processed. - * - * @return N/A - */ -static inline void k_delayed_work_init(struct k_delayed_work *work, - k_work_handler_t handler) -{ - *work = (struct k_delayed_work)Z_DELAYED_WORK_INITIALIZER(handler); -} - -/** - * @brief Submit a delayed work item. - * - * This routine schedules work item @a work to be processed by workqueue - * @a work_q after a delay of @a delay milliseconds. The routine initiates - * an asynchronous countdown for the work item and then returns to the caller. - * Only when the countdown completes is the work item actually submitted to - * the workqueue and becomes pending. - * - * Submitting a previously submitted delayed work item that is still counting - * down or is pending cancels the existing submission and restarts the - * countdown using the new delay. Note that this behavior is inherently - * subject to race conditions with the pre-existing timeouts and work queue, - * so care must be taken to synchronize such resubmissions externally. - * - * Attempts to submit a work item to a queue after it has been submitted to a - * different queue will fail with @c -EALREADY until k_delayed_work_cancel() - * is successfully invoked on the work item to clear its internal state. - * - * @warning - * A delayed work item must not be modified until it has been processed - * by the workqueue. - * - * @note Can be called by ISRs. - * - * @param work_q Address of workqueue. - * @param work Address of delayed work item. - * @param delay Delay before submitting the work item - * - * @retval 0 Work item countdown started. - * @retval -EINVAL - * * if a previously submitted work item had to be cancelled and the - * cancellation failed; or - * * Work item is being processed or has completed its work. - * @retval -EADDRINUSE Work item was submitted to a different workqueue. - */ -extern int k_delayed_work_submit_to_queue(struct k_work_q *work_q, - struct k_delayed_work *work, - k_timeout_t delay); - -/** - * @brief Cancel a delayed work item. - * - * This routine cancels the submission of delayed work item @a work. Whether - * the work item can be successfully cancelled depends on its state. - * - * @note Can be called by ISRs. - * - * @note When @c -EALREADY is returned the caller cannot distinguish whether - * the work item handler is still being invoked by the work queue thread or - * has completed. - * - * @param work Address of delayed work item. - * - * @retval 0 - * * Work item countdown cancelled before the item was submitted to its - * queue; or - * * Work item was removed from its queue before it was processed. - * @retval -EINVAL - * * Work item has never been submitted; or - * * Work item has been successfully cancelled; or - * * Timeout handler is in the process of submitting the work item to its - * queue; or - * * Work queue thread has removed the work item from the queue but has not - * called its handler. - * @retval -EALREADY - * * Work queue thread has removed the work item from the queue and cleared - * its pending flag; or - * * Work queue thread is invoking the item handler; or - * * Work item handler has completed. - */ -extern int k_delayed_work_cancel(struct k_delayed_work *work); - -/** - * @brief Submit a work item to the system workqueue. - * - * This routine submits work item @a work to be processed by the system - * workqueue. If the work item is already pending in the system workqueue or - * any other workqueue as a result of an earlier submission, this routine - * has no effect on the work item. If the work item has already been - * processed, or is currently being processed, its work is considered - * complete and the work item can be resubmitted. - * - * @warning - * Work items submitted to the system workqueue should avoid using handlers - * that block or yield since this may prevent the system workqueue from - * processing other work items in a timely manner. - * - * @note Can be called by ISRs. - * - * @param work Address of work item. - * - * @return N/A - */ -static inline void k_work_submit(struct k_work *work) -{ - k_work_submit_to_queue(&k_sys_work_q, work); -} - -/** - * @brief Submit a delayed work item to the system workqueue. - * - * This routine schedules work item @a work to be processed by the system - * workqueue after a delay of @a delay milliseconds. The routine initiates - * an asynchronous countdown for the work item and then returns to the caller. - * Only when the countdown completes is the work item actually submitted to - * the workqueue and becomes pending. - * - * Submitting a previously submitted delayed work item that is still - * counting down cancels the existing submission and restarts the countdown - * using the new delay. If the work item is currently pending on the - * workqueue's queue because the countdown has completed it is too late to - * resubmit the item, and resubmission fails without impacting the work item. - * If the work item has already been processed, or is currently being processed, - * its work is considered complete and the work item can be resubmitted. - * - * Attempts to submit a work item to a queue after it has been submitted to a - * different queue will fail with @c -EALREADY until k_delayed_work_cancel() - * is invoked on the work item to clear its internal state. - * - * @warning - * Work items submitted to the system workqueue should avoid using handlers - * that block or yield since this may prevent the system workqueue from - * processing other work items in a timely manner. - * - * @note Can be called by ISRs. - * - * @param work Address of delayed work item. - * @param delay Delay before submitting the work item - * - * @retval 0 Work item countdown started. - * @retval -EINVAL Work item is being processed or has completed its work. - * @retval -EADDRINUSE Work item was submitted to a different workqueue. - */ -static inline int k_delayed_work_submit(struct k_delayed_work *work, - k_timeout_t delay) -{ - return k_delayed_work_submit_to_queue(&k_sys_work_q, work, delay); -} - -/** - * @brief Get time when a delayed work will be scheduled - * - * This routine computes the system uptime when a delayed work gets - * executed. If the delayed work is not waiting to be scheduled, it - * returns current system time. - * - * @param work Delayed work item. - * - * @return Uptime of execution (in ticks). - */ -static inline k_ticks_t k_delayed_work_expires_ticks( - const struct k_delayed_work *work) -{ - return z_timeout_expires(&work->timeout); -} - -/** - * @brief Get time remaining before a delayed work gets scheduled, in - * system ticks - * - * This routine computes the time remaining before a delayed work gets - * executed. If the delayed work is not waiting to be scheduled, it - * returns zero. - * - * @param work Delayed work item. - * - * @return Remaining time (in ticks). - */ -static inline k_ticks_t k_delayed_work_remaining_ticks( - const struct k_delayed_work *work) -{ - return z_timeout_remaining(&work->timeout); -} - -/** - * @brief Get time remaining before a delayed work gets scheduled. - * - * This routine computes the (approximate) time remaining before a - * delayed work gets executed. If the delayed work is not waiting to be - * scheduled, it returns zero. - * - * @param work Delayed work item. - * - * @return Remaining time (in milliseconds). - */ -static inline int32_t k_delayed_work_remaining_get(const struct k_delayed_work *work) -{ - return k_ticks_to_ms_floor32(z_timeout_remaining(&work->timeout)); -} - -/** @} */ - -#endif /* CONFIG_KERNEL_WORK1 */ - /** * @defgroup mutex_apis Mutex APIs * @ingroup kernel_apis @@ -3275,8 +2830,6 @@ static inline unsigned int z_impl_k_sem_count_get(struct k_sem *sem) /** @} */ -#ifndef CONFIG_KERNEL_WORK1 - /** * @cond INTERNAL_HIDDEN */ @@ -4369,8 +3922,6 @@ extern void k_work_user_queue_start(struct k_work_user_q *work_q, /** @} */ -#endif /* !CONFIG_KERNEL_WORK1 */ - /** * @cond INTERNAL_HIDDEN */ diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 68b41420e8c..46a0be3e622 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -23,6 +23,7 @@ list(APPEND kernel_files thread.c version.c condvar.c + work.c smp.c banner.c ) @@ -44,9 +45,6 @@ set_target_properties( __ZEPHYR_SUPERVISOR__ ) -target_sources_ifdef(CONFIG_KERNEL_WORK1 kernel PRIVATE work_q.c) -target_sources_ifdef(CONFIG_KERNEL_WORK2 kernel PRIVATE work.c) - target_sources_ifdef(CONFIG_STACK_CANARIES kernel PRIVATE compiler_stack_protect.c) target_sources_ifdef(CONFIG_SYS_CLOCK_EXISTS kernel PRIVATE timeout.c timer.c) target_sources_ifdef(CONFIG_ATOMIC_OPERATIONS_C kernel PRIVATE atomic_c.c) diff --git a/kernel/Kconfig b/kernel/Kconfig index e5172d9d1c7..6258ef4d2bf 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -884,22 +884,4 @@ config THREAD_LOCAL_STORAGE help This option enables thread local storage (TLS) support in kernel. -choice KERNEL_WORK - prompt "Which work queue implementation to use" - default KERNEL_WORK2 - -config KERNEL_WORK1 - bool "Select the original racy work API" - help - This selects the original k_work_* implementation, and excludes the - new simplementation. - -config KERNEL_WORK2 - bool "Select alternative work API" - help - This disables the original k_work_* implementation and replaces it - with a new one. - -endchoice # KERNEL_WORK - endmenu diff --git a/kernel/system_work_q.c b/kernel/system_work_q.c index 496fbbe62d9..2213625fc15 100644 --- a/kernel/system_work_q.c +++ b/kernel/system_work_q.c @@ -27,19 +27,10 @@ static int k_sys_work_q_init(const struct device *dev) .no_yield = IS_ENABLED(CONFIG_SYSTEM_WORKQUEUE_NO_YIELD), }; -#ifdef CONFIG_KERNEL_WORK1 - k_work_q_start(&k_sys_work_q, - sys_work_q_stack, - K_KERNEL_STACK_SIZEOF(sys_work_q_stack), - CONFIG_SYSTEM_WORKQUEUE_PRIORITY); - k_thread_name_set(&k_sys_work_q.thread, "sysworkq"); -#else /* CONFIG_KERNEL_WORK1 */ k_work_queue_start(&k_sys_work_q, sys_work_q_stack, K_KERNEL_STACK_SIZEOF(sys_work_q_stack), CONFIG_SYSTEM_WORKQUEUE_PRIORITY, &cfg); -#endif /* CONFIG_KERNEL_WORK1 */ - return 0; } diff --git a/kernel/work_q.c b/kernel/work_q.c deleted file mode 100644 index c13c4f346c7..00000000000 --- a/kernel/work_q.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation - * Copyright (c) 2016 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * - * Workqueue support functions - */ - -#include -#include -#include -#include -#include -#include - -#define WORKQUEUE_THREAD_NAME "workqueue" - -#ifdef CONFIG_SYS_CLOCK_EXISTS -static struct k_spinlock lock; -#endif - -extern void z_work_q_main(void *work_q_ptr, void *p2, void *p3); - -void k_work_q_start(struct k_work_q *work_q, k_thread_stack_t *stack, - size_t stack_size, int prio) -{ - k_queue_init(&work_q->queue); - (void)k_thread_create(&work_q->thread, stack, stack_size, z_work_q_main, - work_q, NULL, NULL, prio, 0, K_NO_WAIT); - - k_thread_name_set(&work_q->thread, WORKQUEUE_THREAD_NAME); -} - -#ifdef CONFIG_SYS_CLOCK_EXISTS -static void work_timeout(struct _timeout *t) -{ - struct k_delayed_work *w = CONTAINER_OF(t, struct k_delayed_work, - timeout); - - /* submit work to workqueue */ - k_work_submit_to_queue(w->work_q, &w->work); -} - -static int work_cancel(struct k_delayed_work *work) -{ - if (k_work_pending(&work->work)) { - /* Remove from the queue if already submitted */ - if (!k_queue_remove(&work->work_q->queue, &work->work)) { - return -EINVAL; - } - } else { - int err = z_abort_timeout(&work->timeout); - - if (err) { - return -EALREADY; - } - } - - /* Detach from workqueue */ - work->work_q = NULL; - - atomic_clear_bit(work->work.flags, K_WORK_STATE_PENDING); - - return 0; -} - -int k_delayed_work_submit_to_queue(struct k_work_q *work_q, - struct k_delayed_work *work, - k_timeout_t delay) -{ - k_spinlock_key_t key = k_spin_lock(&lock); - int err = 0; - - /* Work cannot be active in multiple queues */ - if (work->work_q != NULL && work->work_q != work_q) { - err = -EADDRINUSE; - goto done; - } - - /* Cancel if work has been submitted */ - if (work->work_q == work_q) { - err = work_cancel(work); - /* -EALREADY may indicate the work has already completed so - * this is likely a recurring work. It may also indicate that - * the work handler is still executing. But it's neither - * delayed nor pending, so it can be rescheduled. - */ - if (err == -EALREADY) { - err = 0; - } else if (err < 0) { - goto done; - } - } - - /* Attach workqueue so the timeout callback can submit it */ - work->work_q = work_q; - - /* Submit work directly if no delay. Note that this is a - * blocking operation, so release the lock first. - */ - if (K_TIMEOUT_EQ(delay, K_NO_WAIT)) { - k_spin_unlock(&lock, key); - k_work_submit_to_queue(work_q, &work->work); - return 0; - } - - /* Add timeout */ - z_add_timeout(&work->timeout, work_timeout, delay); - -done: - k_spin_unlock(&lock, key); - return err; -} - -int k_delayed_work_cancel(struct k_delayed_work *work) -{ - k_spinlock_key_t key = k_spin_lock(&lock); - int ret = -EINVAL; - - if (work->work_q != NULL) { - ret = work_cancel(work); - } - - k_spin_unlock(&lock, key); - return ret; -} - -bool k_delayed_work_pending(struct k_delayed_work *work) -{ - return !z_is_inactive_timeout(&work->timeout) || - k_work_pending(&work->work); -} - -#endif /* CONFIG_SYS_CLOCK_EXISTS */ diff --git a/lib/os/CMakeLists.txt b/lib/os/CMakeLists.txt index 049d689f85b..61b026d8fe0 100644 --- a/lib/os/CMakeLists.txt +++ b/lib/os/CMakeLists.txt @@ -23,11 +23,6 @@ zephyr_sources( heap-validate.c ) -zephyr_sources_ifdef(CONFIG_KERNEL_WORK1 work_q.c) -if(${CONFIG_USERSPACE}) -zephyr_sources_ifdef(CONFIG_KERNEL_WORK2 user_work.c) -endif() - zephyr_sources_ifdef(CONFIG_CBPRINTF_COMPLETE cbprintf_complete.c) zephyr_sources_ifdef(CONFIG_CBPRINTF_NANO cbprintf_nano.c) @@ -37,7 +32,7 @@ zephyr_sources_ifdef(CONFIG_RING_BUFFER ring_buffer.c) zephyr_sources_ifdef(CONFIG_ASSERT assert.c) -zephyr_sources_ifdef(CONFIG_USERSPACE mutex.c) +zephyr_sources_ifdef(CONFIG_USERSPACE mutex.c user_work.c) zephyr_sources_ifdef(CONFIG_SCHED_DEADLINE p4wq.c) diff --git a/subsys/net/ip/tcp2.c b/subsys/net/ip/tcp2.c index 07aef5e6d49..a7cb37dca59 100644 --- a/subsys/net/ip/tcp2.c +++ b/subsys/net/ip/tcp2.c @@ -1942,13 +1942,8 @@ int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt) if (tcp_window_full(conn)) { /* Trigger resend if the timer is not active */ -#ifdef CONFIG_KERNEL_WORK1 - if (!k_delayed_work_remaining_get(&conn->send_data_timer)) { - NET_DBG("Window full, trigger resend"); - tcp_resend_data(&conn->send_data_timer.work); - } -#else - /* HACK: use new API with legacy wrapper. + /* TODO: use k_work_delayable for send_data_timer so we don't + * have to directly access the internals of the legacy object. * * NOTE: It is not permitted to access any fields of k_work or * k_work_delayable directly. This replacement does so, but @@ -1969,9 +1964,8 @@ int net_tcp_queue_data(struct net_context *context, struct net_pkt *pkt) * conn is embedded, and calling that function directly here * and in the work handler. */ - (void)k_work_schedule_to_queue(&tcp_work_q, - &conn->send_data_timer.work, K_NO_WAIT); -#endif + (void)k_work_schedule_for_queue(&tcp_work_q, + &conn->send_data_timer.work, K_NO_WAIT); ret = -EAGAIN; goto out; diff --git a/tests/kernel/workq/user_work/prj.conf b/tests/kernel/workq/user_work/prj.conf index a087ec0915e..db011855dd2 100644 --- a/tests/kernel/workq/user_work/prj.conf +++ b/tests/kernel/workq/user_work/prj.conf @@ -6,4 +6,3 @@ CONFIG_TEST_USERSPACE=y CONFIG_POLL=y CONFIG_MP_NUM_CPUS=1 CONFIG_MAX_THREAD_BYTES=3 -CONFIG_KERNEL_WORK2=y diff --git a/tests/kernel/workq/user_work/testcase.yaml b/tests/kernel/workq/user_work/testcase.yaml index e3183d039e0..2e35f651d0e 100644 --- a/tests/kernel/workq/user_work/testcase.yaml +++ b/tests/kernel/workq/user_work/testcase.yaml @@ -1,6 +1,5 @@ tests: kernel.work.user: - filter: CONFIG_KERNEL_WORK2 min_flash: 34 filter: CONFIG_ARCH_HAS_USERSPACE tags: kernel userspace diff --git a/tests/kernel/workq/work/prj.conf b/tests/kernel/workq/work/prj.conf index 31afa3fe4bb..bb385ff2fc4 100644 --- a/tests/kernel/workq/work/prj.conf +++ b/tests/kernel/workq/work/prj.conf @@ -8,4 +8,3 @@ CONFIG_NUM_COOP_PRIORITIES=4 CONFIG_NUM_PREEMPT_PRIORITIES=4 CONFIG_SYSTEM_WORKQUEUE_PRIORITY=-3 CONFIG_ZTEST_THREAD_PRIORITY=-2 -CONFIG_KERNEL_WORK2=y diff --git a/tests/kernel/workq/work/testcase.yaml b/tests/kernel/workq/work/testcase.yaml index 521af70317b..0aa7c143c89 100644 --- a/tests/kernel/workq/work/testcase.yaml +++ b/tests/kernel/workq/work/testcase.yaml @@ -1,5 +1,4 @@ tests: kernel.work.api: - filter: CONFIG_KERNEL_WORK2 min_flash: 34 tags: kernel diff --git a/tests/kernel/workq/work_queue_api/CMakeLists.txt b/tests/kernel/workq/work_queue_api/CMakeLists.txt deleted file mode 100644 index e0d35c7c45c..00000000000 --- a/tests/kernel/workq/work_queue_api/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.13.1) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(work_queue_api) - -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kernel/workq/work_queue_api/prj.conf b/tests/kernel/workq/work_queue_api/prj.conf deleted file mode 100644 index 58b106c2360..00000000000 --- a/tests/kernel/workq/work_queue_api/prj.conf +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG_ZTEST=y -CONFIG_IRQ_OFFLOAD=y -CONFIG_HEAP_MEM_POOL_SIZE=1024 -CONFIG_THREAD_NAME=y -CONFIG_TEST_USERSPACE=y -CONFIG_POLL=y -CONFIG_MP_NUM_CPUS=1 -CONFIG_MAX_THREAD_BYTES=3 -CONFIG_KERNEL_WORK1=y diff --git a/tests/kernel/workq/work_queue_api/src/main.c b/tests/kernel/workq/work_queue_api/src/main.c deleted file mode 100644 index 0a540fce311..00000000000 --- a/tests/kernel/workq/work_queue_api/src/main.c +++ /dev/null @@ -1,1564 +0,0 @@ -/* - * Copyright (c) 2016, 2020 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @brief Workqueue Tests - * @defgroup kernel_workqueue_tests Workqueue - * @ingroup all_tests - * @{ - * @} - */ - -#include -#include - -#define TIMEOUT_MS 100 -#define TIMEOUT K_MSEC(TIMEOUT_MS) -#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE) -#define NUM_OF_WORK 2 -#define SYNC_SEM_INIT_VAL (0U) -#define COM_SEM_MAX_VAL (1U) -#define COM_SEM_INIT_VAL (0U) -#define MAX_WORK_Q_NUMBER 10 -#define MY_PRIORITY 5 - -struct k_delayed_work work_item_delayed; -struct k_sem common_sema, sema_fifo_one, sema_fifo_two; -struct k_work work_item, work_item_1, work_item_2; -struct k_work_q work_q_max_number[MAX_WORK_Q_NUMBER]; -K_THREAD_STACK_DEFINE(my_stack_area, STACK_SIZE); -K_THREAD_STACK_DEFINE(new_stack_area[MAX_WORK_Q_NUMBER], STACK_SIZE); - -static K_THREAD_STACK_DEFINE(tstack, STACK_SIZE); -static K_THREAD_STACK_DEFINE(user_tstack, STACK_SIZE); -static struct k_work_q workq; -struct k_work_q work_q_1; -static struct k_work_q user_workq; -static ZTEST_BMEM struct k_work work[NUM_OF_WORK]; -static struct k_delayed_work new_work; -static struct k_delayed_work delayed_work[NUM_OF_WORK], delayed_work_sleepy; -static struct k_work_poll triggered_work[NUM_OF_WORK]; -static struct k_poll_event triggered_work_event[NUM_OF_WORK]; -static struct k_poll_signal triggered_work_signal[NUM_OF_WORK]; -static struct k_work_poll triggered_work_sleepy; -static struct k_poll_event triggered_work_sleepy_event; -static struct k_poll_signal triggered_work_sleepy_signal; -static struct k_sem sync_sema; -static struct k_sem dummy_sema; -static struct k_thread *main_thread; - -/** - * @brief Common function using like a handler for workqueue tests - * API call in it means successful execution of that function - * - * @param unused of type k_work to make handler function accepted - * by k_work_init - * - * @return N/A - */ -void common_work_handler(struct k_work *unused) -{ - k_sem_give(&sync_sema); -} - -/** - * @brief Test work item can take call back function defined by user - * @details - * Test Objective: - * - Test a work item shall be supplied as a user-defined callback - * function, and the handler function of a work item shall be able - * to utilize any kernel API available to threads. - * - * Test techniques: - * - Dynamic analysis and testing - * - Interface testing - * - * Prerequisite Conditions: - * - N/A - * - * Input Specifications: - * - N/A - * - * Test Procedure: - * -# Creating a work item, then add handler function to that work item. - * -# Then process that work item. - * -# To check that handler function executed successfully, we use semaphore - * sync_sema with initial count 0. - * -# Handler function gives semaphore, then we wait for that semaphore - * from the test function body. - * -# Check if semaphore was obtained successfully. - * -# Set a work item's flag in pending state and append the item into workqueue. - * -# Check if the queue is empty. - * - * Expected Test Result: - * - The work item can be submit to workqueue whenever it is in right state. - * - * Pass/Fail Criteria: - * - Successful if check points in test procedure are all passed, - * otherwise failure. - * - * Assumptions and Constraints: - * - N/A - * - * @see k_work_init() - * - * @ingroup kernel_workqueue_tests - */ -void test_work_item_supplied_with_func(void) -{ - uint32_t sem_count = 0; - - k_sem_reset(&sync_sema); - - /**TESTPOINT: init work item with a user-defined function*/ - k_work_init(&work_item, common_work_handler); - k_work_submit_to_queue(&workq, &work_item); - - k_sem_take(&sync_sema, K_FOREVER); - sem_count = k_sem_count_get(&sync_sema); - zassert_equal(sem_count, COM_SEM_INIT_VAL, NULL); - - /* TESTPOINT: When a work item be added to a workqueue, - * it's flag will be in pending state, before the work item be processed, - * it cannot be append to a workqueue another time. - */ - zassert_false(k_work_pending(&work_item), NULL); - k_work_submit_to_queue(&workq, &work_item); - zassert_true(k_work_pending(&work_item), NULL); - k_work_submit_to_queue(&workq, &work_item); - - /* Test the work item's callback function can only be invoked once */ - k_sem_take(&sync_sema, K_FOREVER); - zassert_true(k_queue_is_empty(&workq.queue), NULL); -} - - -/** - * @brief Test k_work_submit_to_user_queue API - * - * @details Funcion k_work_submit_to_user_queue() will return - * -EBUSY: if the work item was already in some workqueue and - * -ENOMEM: if no memory for thread resource pool allocation. - * Create two situation to meet the error return value. - * - * @see k_work_submit_to_user_queue() - * @ingroup kernel_workqueue_tests - */ -void test_k_work_submit_to_user_queue_fail(void) -{ - int ret = 0; - - k_sem_reset(&sync_sema); - k_work_init(&work[0], common_work_handler); - k_work_init(&work[1], common_work_handler); - - /* TESTPOINT: When a work item be added to a workqueue, - * it's flag will be in pending state, before the work item be processed, - * it cannot be append to a workqueue another time. - */ - k_work_submit_to_user_queue(&user_workq, &work[0]); - k_work_submit_to_user_queue(&user_workq, &work[0]); - - /* Test the work item's callback function can only be invoked once */ - k_sem_take(&sync_sema, K_FOREVER); - zassert_true(k_queue_is_empty(&user_workq.queue), NULL); - - /* use up the memory in resource pool */ - for (int i = 0; i < 100; i++) { - ret = k_queue_alloc_append(&user_workq.queue, &work[1]); - if (ret == -ENOMEM) { - break; - } - } - - k_work_submit_to_user_queue(&user_workq, &work[0]); - /* if memory is used up, the work cannot be append into the workqueue */ - zassert_false(k_work_pending(&work[0]), NULL); -} - - -/* Two handler functions fifo_work_first() and fifo_work_second - * are made for two work items to test first in, first out. - * It tests workqueue thread process work items - * in first in, first out manner - */ -void fifo_work_first(struct k_work *unused) -{ - k_sem_take(&sema_fifo_one, K_FOREVER); - k_sem_give(&sema_fifo_two); -} - -void fifo_work_second(struct k_work *unused) -{ - k_sem_take(&sema_fifo_two, K_FOREVER); -} - -/** - * @brief Test kernel process work items in fifo way - * @details To test it we use 2 functions-handlers. - * - fifo_work_first() added to the work_item_1 and fifo_work_second() - * added to the work_item_2. - * - We expect that firstly should run work_item_1, and only then - * will run work_item_2. - * - To test it, we initialize semaphore sema_fifo_one - * with count 1(available) and fifo_work_first() takes that semaphore. - * fifo_work_second() is waiting for the semaphore sema_fifo_two, - * which will be given from function fifo_work_first(). - * - If work_item_2() will try to be executed before work_item_1(), - * will happen a timeout error. - * - Because sema_fifo_two will be never obtained by fifo_work_second() - * due to K_FOREVER macro in it while waiting for the semaphore. - * @ingroup kernel_workqueue_tests - */ -void test_process_work_items_fifo(void) -{ - k_work_init(&work_item_1, fifo_work_first); - k_work_init(&work_item_2, fifo_work_second); - - /**TESTPOINT: submit work items to the queue in fifo manner*/ - k_work_submit_to_queue(&workq, &work_item_1); - k_work_submit_to_queue(&workq, &work_item_2); -} - -/** - * @brief Test submitting a delayed work item to a workqueue - * @details - * Test Objective: - * - Test kernel support scheduling work item that is to be processed - * after user defined period of time. - * - * Test techniques: - * - Dynamic analysis and testing - * - Interface testing - * - * Prerequisite Conditions: - * - N/A - * - * Input Specifications: - * - N/A - * - * Test Procedure: - * -# For that test is using semaphore sync_sema, with initial count 0. - * -# In that test we measure actual spent time and compare it with time - * which was measured by function k_delayed_work_remaining_get(). - * -# Using system clocks we measure actual spent time - * in the period between delayed work submitted and delayed work - * executed. - * -# To know that delayed work was executed, we use semaphore. - * -# Right after semaphore was given from handler function, we stop - * measuring actual time. - * -# Then compare results. - * - * Expected Test Result: - * - The measured time results are in a very small range. - * - * Pass/Fail Criteria: - * - Successful if check points in test procedure are all passed, - * otherwise failure. - * - * Assumptions and Constraints: - * - N/A - * - * @see k_delayed_work_init() - * - * @ingroup kernel_workqueue_tests - */ -void test_sched_delayed_work_item(void) -{ - int32_t ms_remain, ms_spent, start_time, stop_time, cycles_spent; - int32_t ms_delta = 15; - - k_sem_reset(&sync_sema); - - /* TESTPOINT: init delayed work to be processed - * only after specific period of time - */ - k_delayed_work_init(&work_item_delayed, common_work_handler); - /* align to tick before schedule */ - k_usleep(1); - start_time = k_cycle_get_32(); - k_delayed_work_submit_to_queue(&workq, &work_item_delayed, TIMEOUT); - ms_remain = k_delayed_work_remaining_get(&work_item_delayed); - - k_sem_take(&sync_sema, K_FOREVER); - stop_time = k_cycle_get_32(); - cycles_spent = stop_time - start_time; - ms_spent = (uint32_t)k_cyc_to_ms_floor32(cycles_spent); - - zassert_within(ms_spent, ms_remain, ms_delta, NULL); -} - -/** - * @brief Test define any number of workqueues - * @details - * Test Objective: - * - Test application can define workqueues without any limit. - * - * Test techniques: - * - Dynamic analysis and testing - * - Interface testing - * - * Prerequisite Conditions: - * - N/A - * - * Input Specifications: - * - N/A - * - * Test Procedure: - * -# Define any number of workqueus using a var of type - * struct k_work_q. - * -# Define and initialize maximum possible real number of the - * workqueues available according to the stack size. - * -# Test defines and initializes max number of the workqueues - * and starts them. - * -# Check if the number of workqueues defined is the same as the - * number of times the definition operation was performed. - * - * Expected Test Result: - * - The max number of workqueues be created. - * - * Pass/Fail Criteria: - * - Successful if check points in test procedure are all passed, - * otherwise failure. - * - * Assumptions and Constraints: - * - N/A - * - * @see k_work_q_start() - * - * @ingroup kernel_workqueue_tests - */ -void test_workqueue_max_number(void) -{ - uint32_t work_q_num = 0; - - for (uint32_t i = 0; i < MAX_WORK_Q_NUMBER; i++) { - work_q_num++; - k_work_q_start(&work_q_max_number[i], new_stack_area[i], - K_THREAD_STACK_SIZEOF(new_stack_area[i]), - MY_PRIORITY); - } - zassert_true(work_q_num == MAX_WORK_Q_NUMBER, - "Max number of the defined work queues not reached, " - "real number of the created work queues is " - "%d, expected %d", work_q_num, MAX_WORK_Q_NUMBER); -} - -static void work_sleepy(struct k_work *w) -{ - k_sleep(TIMEOUT); - k_sem_give(&sync_sema); -} - -static void work_handler(struct k_work *w) -{ - /* Just to show an API call on this will succeed */ - k_sem_init(&dummy_sema, 0, 1); - - k_sem_give(&sync_sema); -} - -static void new_work_handler(struct k_work *w) -{ - k_sem_give(&sync_sema); -} - -static void twork_submit_1(struct k_work_q *work_q, struct k_work *w, - k_work_handler_t handler) -{ - /**TESTPOINT: init via k_work_init*/ - k_work_init(w, handler); - /**TESTPOINT: check pending after work init*/ - zassert_false(k_work_pending(w), NULL); - - if (work_q) { - /**TESTPOINT: work submit to queue*/ - zassert_false(k_work_submit_to_user_queue(work_q, w), - "failed to submit to queue"); - } else { - /**TESTPOINT: work submit to system queue*/ - k_work_submit(w); - } -} - -static void twork_submit(const void *data) -{ - struct k_work_q *work_q = (struct k_work_q *)data; - - for (int i = 0; i < NUM_OF_WORK; i++) { - twork_submit_1(work_q, &work[i], work_handler); - } -} - -static void twork_submit_multipleq(void *data) -{ - struct k_work_q *work_q = (struct k_work_q *)data; - - if (IS_ENABLED(CONFIG_SOC_QEMU_ARC_HS)) { - /* On this platform the wait for first submission to - * timeout returns after the pending work has been - * taken off the work queue. - */ - ztest_test_skip(); - return; - } - - /**TESTPOINT: init via k_work_init*/ - k_delayed_work_init(&new_work, new_work_handler); - zassert_equal(k_delayed_work_cancel(&new_work), - -EINVAL, NULL); - - /* align to tick before schedule */ - k_usleep(1); - k_delayed_work_submit_to_queue(work_q, &new_work, TIMEOUT); - zassert_true(k_delayed_work_pending(&new_work), NULL); - - zassert_equal(k_delayed_work_submit(&new_work, TIMEOUT), - -EADDRINUSE, NULL); - - /* wait for first submission to complete timeout, then sleep - * once to ensure the work thread gets to run (depending on - * timing it may or may not be submitted right after the - * timeout sleep returns. - */ - k_sleep(TIMEOUT); - k_usleep(1); - zassert_false(k_delayed_work_pending(&new_work), NULL); - - /* confirm legacy behavior that completed work item can't be - * submitted on a new queue. - */ - zassert_equal(k_delayed_work_submit(&new_work, TIMEOUT), - -EADDRINUSE, NULL); - - /* still can't if the (completed) work item is unsuccessfully - * cancelled - */ - zassert_equal(k_delayed_work_cancel(&new_work), - -EALREADY, NULL); - zassert_equal(k_delayed_work_submit(&new_work, TIMEOUT), - -EADDRINUSE, NULL); - - /* but can if the work item is successfully cancelled */ - zassert_equal(k_delayed_work_submit_to_queue(work_q, &new_work, - TIMEOUT), - 0, NULL); - zassert_equal(k_delayed_work_cancel(&new_work), - 0, NULL); - zassert_equal(k_delayed_work_cancel(&new_work), - -EINVAL, NULL); - zassert_equal(k_delayed_work_submit(&new_work, TIMEOUT), - 0, NULL); -} - -static void twork_resubmit(void *data) -{ - struct k_work_q *work_q = (struct k_work_q *)data; - - /**TESTPOINT: init via k_work_init*/ - k_delayed_work_init(&new_work, new_work_handler); - - k_delayed_work_submit_to_queue(work_q, &new_work, K_NO_WAIT); - - /* This is done to test a neagtive case when k_delayed_work_cancel() - * fails in k_delayed_work_submit_to_queue API. Removing work from it - * queue make sure that k_delayed_work_cancel() fails when the Work is - * resubmitted. - */ - k_queue_remove(&(new_work.work_q->queue), &(new_work.work)); - - zassert_equal(k_delayed_work_submit_to_queue(work_q, &new_work, - K_NO_WAIT), - -EINVAL, NULL); - - k_sem_give(&sync_sema); -} - -static void twork_resubmit_nowait(void *data) -{ - struct k_work_q *work_q = (struct k_work_q *)data; - - k_delayed_work_init(&delayed_work_sleepy, work_sleepy); - k_delayed_work_init(&delayed_work[0], work_handler); - k_delayed_work_init(&delayed_work[1], work_handler); - - zassert_equal(k_delayed_work_submit_to_queue(work_q, - &delayed_work_sleepy, - K_NO_WAIT), - 0, NULL); - zassert_equal(k_delayed_work_submit_to_queue(work_q, &delayed_work[0], - K_NO_WAIT), - 0, NULL); - zassert_equal(k_delayed_work_submit_to_queue(work_q, &delayed_work[1], - K_NO_WAIT), - 0, NULL); - - /* No-wait submissions are pended immediately. */ - zassert_true(k_work_pending(&delayed_work_sleepy.work), NULL); - zassert_true(k_work_pending(&delayed_work[0].work), NULL); - zassert_true(k_work_pending(&delayed_work[1].work), NULL); - - /* Release sleeper, check other two still pending */ - do { - k_usleep(1); - } while (k_work_pending(&delayed_work_sleepy.work)); - zassert_false(k_work_pending(&delayed_work_sleepy.work), NULL); - zassert_true(k_work_pending(&delayed_work[0].work), NULL); - zassert_true(k_work_pending(&delayed_work[1].work), NULL); - - /* Verify order of pending */ - zassert_equal(k_queue_peek_head(&workq.queue), - &delayed_work[0].work, NULL); - zassert_equal(k_queue_peek_tail(&workq.queue), - &delayed_work[1].work, NULL); - - /* Verify that resubmitting moves to end. */ - zassert_equal(k_delayed_work_submit_to_queue(work_q, &delayed_work[0], - K_NO_WAIT), - 0, NULL); - zassert_equal(k_queue_peek_head(&workq.queue), - &delayed_work[1].work, NULL); - zassert_equal(k_queue_peek_tail(&workq.queue), - &delayed_work[0].work, NULL); - - k_sem_give(&sync_sema); -} - -static void tdelayed_work_submit_1(struct k_work_q *work_q, - struct k_delayed_work *w, - k_work_handler_t handler) -{ - int32_t time_remaining; - int32_t timeout_ticks; - uint64_t tick_to_ms; - - /**TESTPOINT: init via k_delayed_work_init*/ - k_delayed_work_init(w, handler); - /**TESTPOINT: check pending after delayed work init*/ - zassert_false(k_work_pending(&w->work), NULL); - zassert_false(k_delayed_work_pending(w), NULL); - /**TESTPOINT: check remaining timeout before submit*/ - zassert_equal(k_delayed_work_remaining_get(w), 0, NULL); - - /* align to tick before schedule */ - if (!k_is_in_isr()) { - k_usleep(1); - } - if (work_q) { - /**TESTPOINT: delayed work submit to queue*/ - zassert_true(k_delayed_work_submit_to_queue(work_q, w, TIMEOUT) - == 0, NULL); - } else { - /**TESTPOINT: delayed work submit to system queue*/ - zassert_true(k_delayed_work_submit(w, TIMEOUT) == 0, NULL); - } - - zassert_false(k_work_pending(&w->work), NULL); - zassert_true(k_delayed_work_pending(w), NULL); - - time_remaining = k_delayed_work_remaining_get(w); - timeout_ticks = z_ms_to_ticks(TIMEOUT_MS); - tick_to_ms = k_ticks_to_ms_floor64(timeout_ticks + _TICK_ALIGN); - - /**TESTPOINT: check remaining timeout after submit */ - zassert_true(time_remaining <= tick_to_ms, NULL); - - timeout_ticks -= z_ms_to_ticks(15); - tick_to_ms = k_ticks_to_ms_floor64(timeout_ticks); - - zassert_true(time_remaining >= tick_to_ms, NULL); - - /**TESTPOINT: check pending after delayed work submit*/ - zassert_false(k_work_pending(&w->work), NULL); -} - -static void tdelayed_work_submit(const void *data) -{ - struct k_work_q *work_q = (struct k_work_q *)data; - - for (int i = 0; i < NUM_OF_WORK; i++) { - tdelayed_work_submit_1(work_q, &delayed_work[i], work_handler); - } -} - -static void tdelayed_work_cancel(const void *data) -{ - struct k_work_q *work_q = (struct k_work_q *)data; - int ret; - - k_delayed_work_init(&delayed_work_sleepy, work_sleepy); - k_delayed_work_init(&delayed_work[0], work_handler); - k_delayed_work_init(&delayed_work[1], work_handler); - - /* align to tick before schedule */ - if (!k_is_in_isr()) { - k_usleep(1); - } - if (work_q) { - ret = k_delayed_work_submit_to_queue(work_q, - &delayed_work_sleepy, - TIMEOUT); - ret |= k_delayed_work_submit_to_queue(work_q, &delayed_work[0], - TIMEOUT); - ret |= k_delayed_work_submit_to_queue(work_q, &delayed_work[1], - TIMEOUT); - } else { - ret = k_delayed_work_submit(&delayed_work_sleepy, TIMEOUT); - ret |= k_delayed_work_submit(&delayed_work[0], TIMEOUT); - ret |= k_delayed_work_submit(&delayed_work[1], TIMEOUT); - } - /* - * t0: delayed submit three work items, all with delay=TIMEOUT - * >t0: cancel delayed_work[0], expected cancellation success - * >t0+TIMEOUT: handling delayed_work_sleepy, which do k_sleep TIMEOUT - * pending delayed_work[1], check pending flag, expected 1 - * cancel delayed_work[1], expected 0 - * >t0+2*TIMEOUT: delayed_work_sleepy completed - * delayed_work[1] completed - * cancel delayed_work_sleepy, expected 0 - */ - zassert_true(ret == 0, NULL); - /**TESTPOINT: delayed work cancel when countdown*/ - zassert_false(k_work_pending(&delayed_work[0].work), NULL); - zassert_true(k_delayed_work_pending(&delayed_work[0]), NULL); - ret = k_delayed_work_cancel(&delayed_work[0]); - zassert_true(ret == 0, NULL); - /**TESTPOINT: check pending after delayed work cancel*/ - zassert_false(k_work_pending(&delayed_work[0].work), NULL); - zassert_false(k_delayed_work_pending(&delayed_work[0]), NULL); - if (!k_is_in_isr()) { - /*wait for handling work_sleepy*/ - k_sleep(TIMEOUT); - /**TESTPOINT: check pending when work pending*/ - zassert_true(k_work_pending(&delayed_work[1].work), NULL); - zassert_true(k_delayed_work_pending(&delayed_work[1]), NULL); - /**TESTPOINT: delayed work cancel when pending*/ - ret = k_delayed_work_cancel(&delayed_work[1]); - zassert_equal(ret, 0, NULL); - zassert_false(k_work_pending(&delayed_work[1].work), NULL); - zassert_false(k_delayed_work_pending(&delayed_work[1]), NULL); - k_sem_give(&sync_sema); - /*wait for completed work_sleepy and delayed_work[1]*/ - k_sleep(TIMEOUT); - /**TESTPOINT: check pending when work completed*/ - zassert_false(k_work_pending(&delayed_work_sleepy.work), - NULL); - /**TESTPOINT: delayed work cancel when completed */ - ret = k_delayed_work_cancel(&delayed_work_sleepy); - zassert_equal(ret, -EALREADY, NULL); - } - /*work items not cancelled: delayed_work[1], delayed_work_sleepy*/ -} - -static void ttriggered_work_submit(const void *data) -{ - struct k_work_q *work_q = (struct k_work_q *)data; - - for (int i = 0; i < NUM_OF_WORK; i++) { - k_poll_signal_init(&triggered_work_signal[i]); - k_poll_event_init(&triggered_work_event[i], - K_POLL_TYPE_SIGNAL, - K_POLL_MODE_NOTIFY_ONLY, - &triggered_work_signal[i]); - - /**TESTPOINT: init via k_work_poll_init*/ - k_work_poll_init(&triggered_work[i], work_handler); - /**TESTPOINT: check pending after triggered work init*/ - zassert_false(k_work_pending(&triggered_work[i].work), - NULL); - if (work_q) { - /**TESTPOINT: triggered work submit to queue*/ - zassert_true(k_work_poll_submit_to_queue( - work_q, - &triggered_work[i], - &triggered_work_event[i], 1, - K_FOREVER) == 0, NULL); - } else { - /**TESTPOINT: triggered work submit to system queue*/ - zassert_true(k_work_poll_submit( - &triggered_work[i], - &triggered_work_event[i], 1, - K_FOREVER) == 0, NULL); - } - - /**TESTPOINT: check pending after triggered work submit*/ - zassert_false(k_work_pending(&triggered_work[i].work), - NULL); - } - - for (int i = 0; i < NUM_OF_WORK; i++) { - /**TESTPOINT: trigger work execution*/ - zassert_true(k_poll_signal_raise( - &triggered_work_signal[i], 1) == 0, - NULL); - /**TESTPOINT: check pending after sending signal */ - zassert_true(k_work_pending(&triggered_work[i].work) != 0, - NULL); - } -} - -static void ttriggered_work_cancel(const void *data) -{ - struct k_work_q *work_q = (struct k_work_q *)data; - int ret; - - for (int i = 0; i < NUM_OF_WORK; i++) { - k_poll_signal_init(&triggered_work_signal[i]); - k_poll_event_init(&triggered_work_event[i], - K_POLL_TYPE_SIGNAL, - K_POLL_MODE_NOTIFY_ONLY, - &triggered_work_signal[i]); - - k_work_poll_init(&triggered_work[i], work_handler); - } - - k_poll_signal_init(&triggered_work_sleepy_signal); - k_poll_event_init(&triggered_work_sleepy_event, - K_POLL_TYPE_SIGNAL, - K_POLL_MODE_NOTIFY_ONLY, - &triggered_work_sleepy_signal); - - k_work_poll_init(&triggered_work_sleepy, work_sleepy); - - if (work_q) { - ret = k_work_poll_submit_to_queue(work_q, - &triggered_work_sleepy, - &triggered_work_sleepy_event, - 1, K_FOREVER); - ret |= k_work_poll_submit_to_queue(work_q, - &triggered_work[0], - &triggered_work_event[0], 1, - K_FOREVER); - ret |= k_work_poll_submit_to_queue(work_q, - &triggered_work[1], - &triggered_work_event[1], 1, - K_FOREVER); - } else { - ret = k_work_poll_submit(&triggered_work_sleepy, - &triggered_work_sleepy_event, 1, - K_FOREVER); - ret |= k_work_poll_submit(&triggered_work[0], - &triggered_work_event[0], 1, - K_FOREVER); - ret |= k_work_poll_submit(&triggered_work[1], - &triggered_work_event[1], 1, - K_FOREVER); - } - /* Check if all submission succeeded */ - zassert_true(ret == 0, NULL); - - /**TESTPOINT: triggered work cancel when waiting for event*/ - ret = k_work_poll_cancel(&triggered_work[0]); - zassert_true(ret == 0, NULL); - - /**TESTPOINT: check pending after triggerd work cancel*/ - ret = k_work_pending(&triggered_work[0].work); - zassert_true(ret == 0, NULL); - - /* Trigger work #1 */ - ret = k_poll_signal_raise(&triggered_work_signal[1], 1); - zassert_true(ret == 0, NULL); - - /**TESTPOINT: check pending after sending signal */ - ret = k_work_pending(&triggered_work[1].work); - zassert_true(ret != 0, NULL); - - /**TESTPOINT: triggered work cancel when pending for event*/ - ret = k_work_poll_cancel(&triggered_work[1]); - zassert_true(ret == -EINVAL, NULL); - - /* Trigger sleepy work */ - ret = k_poll_signal_raise(&triggered_work_sleepy_signal, 1); - zassert_true(ret == 0, NULL); - - if (!k_is_in_isr()) { - /*wait for completed work_sleepy and triggered_work[1]*/ - k_msleep(2 * TIMEOUT_MS); - - /**TESTPOINT: check pending when work completed*/ - ret = k_work_pending(&triggered_work_sleepy.work); - zassert_true(ret == 0, NULL); - - /**TESTPOINT: delayed work cancel when completed*/ - ret = k_work_poll_cancel(&triggered_work_sleepy); - zassert_true(ret == -EINVAL, NULL); - - } - - /*work items not cancelled: triggered_work[1], triggered_work_sleepy*/ -} - -/** - * @brief Test work queue start before submit - * @details - * Test Objective: - * - Test the workqueue is initialized by defining the stack area used by - * its thread and then calling k_work_q_start(). - * - * Test techniques: - * - Dynamic analysis and testing - * - Interface testing - * - * Prerequisite Conditions: - * - N/A - * - * Input Specifications: - * - N/A - * - * Test Procedure: - * -# Call the k_work_q_start() to create a work queue which has it's own - * thread that processes the work items in the queue. - * - * Expected Test Result: - * - The user-defined work queue was created successfully. - * - * Pass/Fail Criteria: - * - Successful if check points in test procedure are all passed, - *otherwise failure. - * - * Assumptions and Constraints: - * - N/A - * - * @see k_work_q_start() - * - * @ingroup kernel_workqueue_tests - */ -void test_workq_start_before_submit(void) -{ - k_work_q_start(&workq, tstack, STACK_SIZE, - CONFIG_MAIN_THREAD_PRIORITY); - zassert_equal(strcmp(k_thread_name_get(&workq.thread), "workqueue"), 0, - "workq thread creat failed"); -} - -/** - * @brief Test user mode work queue start before submit - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_q_user_start() - */ -void test_user_workq_start_before_submit(void) -{ - k_work_q_user_start(&user_workq, user_tstack, STACK_SIZE, - CONFIG_MAIN_THREAD_PRIORITY); -} - -/** - * @brief Setup object permissions before test_user_workq_granted_access() - * - * @ingroup kernel_workqueue_tests - */ -void test_user_workq_granted_access_setup(void) -{ - /* Subsequent test cases will have access to the dummy_sema, - * but not the user workqueue since it already started. - */ - k_object_access_grant(&dummy_sema, main_thread); -} - -/** - * @brief Test user mode grant workqueue permissions - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_q_object_access_grant() - */ -void test_user_workq_granted_access(void) -{ - k_object_access_grant(&dummy_sema, &user_workq.thread); -} - -/** - * @brief Test work submission to work queue - * @ingroup kernel_workqueue_tests - * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(), - * k_work_submit() - */ -void test_work_submit_to_queue_thread(void) -{ - k_sem_reset(&sync_sema); - twork_submit(&workq); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test work submission to work queue (user mode) - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(), - * k_work_submit() - */ -void test_user_work_submit_to_queue_thread(void) -{ - k_sem_reset(&sync_sema); - twork_submit(&user_workq); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test submission of work to multiple queues - * - * @ingroup kernel_workqueue_tests - * - * @see k_delayed_work_init(), k_delayed_work_submit_to_queue(), - * k_delayed_work_submit() - */ -void test_work_submit_to_multipleq(void) -{ - k_sem_reset(&sync_sema); - twork_submit_multipleq(&workq); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test work queue resubmission - * - * @ingroup kernel_workqueue_tests - * - * @see k_queue_remove(), k_delayed_work_init(), - * k_delayed_work_submit_to_queue() - */ -void test_work_resubmit_to_queue(void) -{ - k_sem_reset(&sync_sema); - twork_resubmit(&workq); - k_sem_take(&sync_sema, K_FOREVER); -} - -/** - * @brief Test work queue resubmission behavior without wait - * - * @ingroup kernel_workqueue_tests - * - * @see k_queue_remove(), k_delayed_work_init(), - * k_delayed_work_submit_to_queue() - */ -void test_work_resubmit_nowait_to_queue(void) -{ - k_sem_reset(&sync_sema); - twork_resubmit_nowait(&workq); - k_sem_take(&sync_sema, K_FOREVER); -} - -/** - * @brief Test work submission to queue from ISR context - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(), - * k_work_submit() - */ -void test_work_submit_to_queue_isr(void) -{ - k_sem_reset(&sync_sema); - irq_offload(twork_submit, (const void *)&workq); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test work submission to queue - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(), - * k_work_submit() - */ -void test_work_submit_thread(void) -{ - k_sem_reset(&sync_sema); - twork_submit(NULL); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test work submission from ISR context - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(), - * k_work_submit() - */ -void test_work_submit_isr(void) -{ - k_sem_reset(&sync_sema); - irq_offload(twork_submit, NULL); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -static void work_handler_resubmit(struct k_work *w) -{ - k_sem_give(&sync_sema); - - if (k_sem_count_get(&sync_sema) < NUM_OF_WORK) { - k_work_submit(w); - } -} - -/** - * @brief Test resubmitting work item in callback - * @details - * Test Objective: - * - Test work submission to queue from handler context, resubmitting - * a work item during execution of its callback. - * - * Test techniques: - * - Dynamic analysis and testing - * - Functional and black box testing - * - Interface testing - * - * Prerequisite Conditions: - * - N/A - * - * Input Specifications: - * - N/A - * - * Test Procedure: - * -# Uses sync_sema semaphore with initial count 0. - * -# Verifies that it is possible during execution of the handler - * function, resubmit a work item from that handler function. - * -# twork_submit_1() initializes a work item with handler function. - * -# Then handler function gives a semaphore sync_sema. - * -# Then in test main body using for() loop, we are waiting for that - * semaphore. - * -# When semaphore given, handler function checks count of the semaphore - * and submits work one more time. - * - * Expected Test Result: - * - The work item is recommitted. The callback will normally terminated - * according to the exit condition(semaphore count). - * - * Pass/Fail Criteria: - * - Successful if check points in test procedure are all passed, - * otherwise failure. - * - * Assumptions and Constraints: - * - N/A - * - * @see k_work_init(), k_work_pending(), k_work_submit_to_queue(), - * k_work_submit() - * - * @ingroup kernel_workqueue_tests - */ -void test_work_submit_handler(void) -{ - k_sem_reset(&sync_sema); - twork_submit_1(NULL, &work[0], work_handler_resubmit); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test delayed work submission to queue - * - * @ingroup kernel_workqueue_tests - * - * @see k_delayed_work_init(), k_work_pending(), - * k_delayed_work_remaining_get(), k_delayed_work_submit_to_queue(), - * k_delayed_work_submit() - */ -void test_delayed_work_submit_to_queue_thread(void) -{ - k_sem_reset(&sync_sema); - tdelayed_work_submit(&workq); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test delayed work submission to queue in ISR context - * - * @ingroup kernel_workqueue_tests - * - * @see k_delayed_work_init(), k_work_pending(), - * k_delayed_work_remaining_get(), k_delayed_work_submit_to_queue(), - * k_delayed_work_submit() - */ -void test_delayed_work_submit_to_queue_isr(void) -{ - k_sem_reset(&sync_sema); - irq_offload(tdelayed_work_submit, (const void *)&workq); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test delayed work submission - * - * @ingroup kernel_workqueue_tests - * - * @see k_delayed_work_init(), k_work_pending(), - * k_delayed_work_remaining_get(), k_delayed_work_submit_to_queue(), - * k_delayed_work_submit() - */ -void test_delayed_work_submit_thread(void) -{ - k_sem_reset(&sync_sema); - tdelayed_work_submit(NULL); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test delayed work submission from ISR context - * - * @ingroup kernel_workqueue_tests - * - * @see k_delayed_work_init(), k_work_pending(), - * k_delayed_work_remaining_get(), k_delayed_work_submit_to_queue(), - * k_delayed_work_submit() - */ -void test_delayed_work_submit_isr(void) -{ - k_sem_reset(&sync_sema); - irq_offload(tdelayed_work_submit, NULL); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -static void delayed_work_handler_resubmit(struct k_work *w) -{ - struct k_delayed_work *delayed_w = (struct k_delayed_work *)w; - - k_sem_give(&sync_sema); - - if (k_sem_count_get(&sync_sema) < NUM_OF_WORK) { - /**TESTPOINT: check if work can be resubmit from handler */ - zassert_false(k_delayed_work_submit(delayed_w, TIMEOUT), NULL); - } -} - -/** - * @brief Test delayed work submission to queue from handler context - * - * @ingroup kernel_workqueue_tests - * - * @see k_delayed_work_init(), k_work_pending(), - * k_delayed_work_remaining_get(), k_delayed_work_submit_to_queue(), - * k_delayed_work_submit() - */ -void test_delayed_work_submit_handler(void) -{ - k_sem_reset(&sync_sema); - tdelayed_work_submit_1(NULL, &delayed_work[0], - delayed_work_handler_resubmit); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } - k_delayed_work_cancel(&delayed_work[0]); -} - -/** - * @brief Test delayed work cancel from work queue - * - * @ingroup kernel_workqueue_tests - * - * @see k_delayed_work_cancel(), k_work_pending() - */ -void test_delayed_work_cancel_from_queue_thread(void) -{ - k_sem_reset(&sync_sema); - tdelayed_work_cancel(&workq); - /*wait for work items that could not be cancelled*/ - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test delayed work cancel from work queue from ISR context - * - * @ingroup kernel_workqueue_tests - * - * @see k_delayed_work_cancel(), k_work_pending() - */ -void test_delayed_work_cancel_from_queue_isr(void) -{ - k_sem_reset(&sync_sema); - irq_offload(tdelayed_work_cancel, (const void *)&workq); - /*wait for work items that could not be cancelled*/ - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test delayed work cancel - * - * @ingroup kernel_workqueue_tests - * - * @see k_delayed_work_cancel(), k_work_pending() - */ -void test_delayed_work_cancel_thread(void) -{ - k_sem_reset(&sync_sema); - tdelayed_work_cancel(NULL); - /*wait for work items that could not be cancelled*/ - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test delayed work cancel from ISR context - * - * @ingroup kernel_workqueue_tests - * - * @see k_delayed_work_cancel(), k_work_pending() - */ -void test_delayed_work_cancel_isr(void) -{ - k_sem_reset(&sync_sema); - irq_offload(tdelayed_work_cancel, NULL); - /*wait for work items that could not be cancelled*/ - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test triggered work submission to queue - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_poll_init(), k_work_pending(), - * k_work_poll_submit_to_queue(), - * k_work_poll_submit() - */ -void test_triggered_work_submit_to_queue_thread(void) -{ - k_sem_reset(&sync_sema); - ttriggered_work_submit(&workq); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test triggered work submission to queue in ISR context - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_poll_init(), k_work_pending(), - * k_work_poll_submit_to_queue(), - * k_work_poll_submit() - */ -void test_triggered_work_submit_to_queue_isr(void) -{ - k_sem_reset(&sync_sema); - irq_offload(ttriggered_work_submit, (const void *)&workq); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test triggered work submission - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_poll_init(), k_work_pending(), - * k_work_poll_submit_to_queue(), - * k_work_poll_submit() - */ -void test_triggered_work_submit_thread(void) -{ - k_sem_reset(&sync_sema); - ttriggered_work_submit(NULL); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test triggered work submission from ISR context - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_poll_init(), k_work_pending(), - * k_work_poll_submit_to_queue(), - * k_work_poll_submit() - */ -void test_triggered_work_submit_isr(void) -{ - k_sem_reset(&sync_sema); - irq_offload(ttriggered_work_submit, NULL); - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test triggered work cancel from work queue - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_poll_cancel(), k_work_pending() - */ -void test_triggered_work_cancel_from_queue_thread(void) -{ - k_sem_reset(&sync_sema); - ttriggered_work_cancel(&workq); - /*wait for work items that could not be cancelled*/ - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test triggered work cancel from work queue from ISR context - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_poll_cancel(), k_work_pending() - */ -void test_triggered_work_cancel_from_queue_isr(void) -{ - k_sem_reset(&sync_sema); - irq_offload(ttriggered_work_cancel, (const void *)&workq); - /*wait for work items that could not be cancelled*/ - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test triggered work cancel - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_poll_cancel(), k_work_pending() - */ -void test_triggered_work_cancel_thread(void) -{ - k_sem_reset(&sync_sema); - ttriggered_work_cancel(NULL); - /*wait for work items that could not be cancelled*/ - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -/** - * @brief Test triggered work cancel from ISR context - * - * @ingroup kernel_workqueue_tests - * - * @see k_work_poll_cancel(), k_work_pending() - */ -void test_triggered_work_cancel_isr(void) -{ - k_sem_reset(&sync_sema); - irq_offload(ttriggered_work_cancel, NULL); - /*wait for work items that could not be cancelled*/ - for (int i = 0; i < NUM_OF_WORK; i++) { - k_sem_take(&sync_sema, K_FOREVER); - } -} - -void new_common_work_handler(struct k_work *unused) -{ - k_sem_give(&sync_sema); - k_sem_take(&sema_fifo_two, K_FOREVER); -} - -/** - * @brief Test cancel already processed work item - * @details That test is created to increase coverage and to check that we can - * cancel already processed delayed work item. - * @ingroup kernel_workqueue_tests - * @see k_delayed_work_cancel() - */ -void test_cancel_processed_work_item(void) -{ - int ret; - - k_sem_reset(&sync_sema); - k_sem_reset(&sema_fifo_two); - - k_delayed_work_init(&work_item_delayed, common_work_handler); - - ret = k_delayed_work_cancel(&work_item_delayed); - zassert_true(ret == -EINVAL, NULL); - k_delayed_work_submit_to_queue(&workq, &work_item_delayed, TIMEOUT); - k_sem_take(&sync_sema, K_FOREVER); - k_sem_give(&sema_fifo_two); - - /**TESTPOINT: try to delay already processed work item*/ - ret = k_delayed_work_cancel(&work_item_delayed); - - zassert_true(ret == -EALREADY, NULL); - k_sleep(TIMEOUT); -} - -/* negative testcase */ -/** - * @brief Test workq of work poll is not NULL statement for - * API k_work_poll_submit_to_queue() - * - * @details Using workq of work poll is not NULL as - * parameter to cover some branches. - * - * @see k_work_poll_submit_to_queue() - * - * @ingroup kernel_poll_tests - */ -void test_work_submit_to_queue_workq(void) -{ - triggered_work[0].workq = &workq; - k_work_poll_submit_to_queue(&workq, - &triggered_work[0], - &triggered_work_event[0], 1, - K_FOREVER); -} - -/** - * @brief Test workq of work poll is invalid statement for - * API k_work_poll_submit_to_queue() - * - * @details Using workq of work poll is invalid as - * parameter to cover some branches. - * - * @see k_work_poll_submit_to_queue() - * - * @ingroup kernel_poll_tests - */ -void test_work_submit_to_queue_invalid_workq(void) -{ - triggered_work[0].workq = &user_workq; - k_work_poll_submit_to_queue(&workq, - &triggered_work[0], - &triggered_work_event[0], 1, - K_FOREVER); -} - -/** - * @brief Test set a specific time for - * API k_work_poll_submit_to_queue() - * - * @details Set a specific time to test - * uncovered branches - * - * @see k_work_poll_submit_to_queue() - * - * @ingroup kernel_poll_tests - */ -void test_work_poll_submit_to_queue_timeout(void) -{ - k_poll_event_init(&triggered_work_event[0], - K_POLL_TYPE_SIGNAL, - K_POLL_MODE_NOTIFY_ONLY, - &triggered_work_signal[0]); - - /**TESTPOINT: init via k_work_poll_init*/ - k_work_poll_init(&triggered_work[0], work_handler); - k_work_poll_submit_to_queue(&workq, - &triggered_work[0], - &triggered_work_event[0], 1, - K_MSEC(1)); -} - -/** - * @brief Test set a specific time for - * API k_work_poll_submit_to_queue() - * - * @details Set a K_NO_WAIT time to test - * uncovered branches - * - * @see k_work_poll_submit_to_queue() - * - * @ingroup kernel_poll_tests - */ -void test_work_poll_submit_to_queue_no_wait(void) -{ - k_poll_event_init(&triggered_work_event[1], - K_POLL_TYPE_SIGNAL, - K_POLL_MODE_NOTIFY_ONLY, - &triggered_work_signal[1]); - /**TESTPOINT: init via k_work_poll_init*/ - k_work_poll_init(&triggered_work[1], work_handler); - - k_work_poll_submit_to_queue(&workq, - &triggered_work[1], - &triggered_work_event[1], 1, - K_NO_WAIT); -} - -void test_main(void) -{ - main_thread = k_current_get(); - k_thread_access_grant(main_thread, &sync_sema, &user_workq.thread, - &user_workq.queue, - &user_tstack); - k_sem_init(&sync_sema, SYNC_SEM_INIT_VAL, NUM_OF_WORK); - k_sem_init(&sema_fifo_one, COM_SEM_MAX_VAL, COM_SEM_MAX_VAL); - k_sem_init(&sema_fifo_two, COM_SEM_INIT_VAL, COM_SEM_MAX_VAL); - k_thread_system_pool_assign(k_current_get()); - - ztest_test_suite(workqueue_api, - /* Do not disturb the ordering of these test cases */ - ztest_unit_test(test_workq_start_before_submit), - ztest_user_unit_test(test_user_workq_start_before_submit), - ztest_unit_test(test_user_workq_granted_access_setup), - ztest_user_unit_test(test_user_workq_granted_access), - /* End order-important tests */ - ztest_1cpu_unit_test(test_work_submit_to_multipleq), - ztest_unit_test(test_work_resubmit_to_queue), - ztest_unit_test(test_work_resubmit_nowait_to_queue), - ztest_1cpu_unit_test(test_work_submit_to_queue_thread), - ztest_1cpu_unit_test(test_work_submit_to_queue_isr), - ztest_1cpu_unit_test(test_work_submit_thread), - ztest_1cpu_unit_test(test_work_submit_isr), - ztest_1cpu_unit_test(test_work_submit_handler), - ztest_1cpu_user_unit_test(test_user_work_submit_to_queue_thread), - ztest_1cpu_unit_test(test_delayed_work_submit_to_queue_thread), - ztest_1cpu_unit_test(test_delayed_work_submit_to_queue_isr), - ztest_1cpu_unit_test(test_delayed_work_submit_thread), - ztest_1cpu_unit_test(test_delayed_work_submit_isr), - ztest_1cpu_unit_test(test_delayed_work_submit_handler), - ztest_1cpu_unit_test(test_delayed_work_cancel_from_queue_thread), - ztest_1cpu_unit_test(test_delayed_work_cancel_from_queue_isr), - ztest_1cpu_unit_test(test_delayed_work_cancel_thread), - ztest_1cpu_unit_test(test_delayed_work_cancel_isr), - ztest_1cpu_unit_test(test_triggered_work_submit_to_queue_thread), - ztest_1cpu_unit_test(test_triggered_work_submit_to_queue_isr), - ztest_1cpu_unit_test(test_triggered_work_submit_thread), - ztest_1cpu_unit_test(test_triggered_work_submit_isr), - ztest_1cpu_unit_test(test_triggered_work_cancel_from_queue_thread), - ztest_1cpu_unit_test(test_triggered_work_cancel_from_queue_isr), - ztest_1cpu_unit_test(test_triggered_work_cancel_thread), - ztest_1cpu_unit_test(test_triggered_work_cancel_isr), - ztest_unit_test(test_work_item_supplied_with_func), - ztest_user_unit_test(test_k_work_submit_to_user_queue_fail), - ztest_unit_test(test_process_work_items_fifo), - ztest_unit_test(test_sched_delayed_work_item), - ztest_unit_test(test_workqueue_max_number), - ztest_unit_test(test_cancel_processed_work_item), - ztest_1cpu_unit_test(test_work_submit_to_queue_workq), - ztest_1cpu_unit_test(test_work_submit_to_queue_invalid_workq), - ztest_1cpu_unit_test(test_work_poll_submit_to_queue_timeout), - ztest_1cpu_unit_test(test_work_poll_submit_to_queue_no_wait) - ); - ztest_run_test_suite(workqueue_api); -} diff --git a/tests/kernel/workq/work_queue_api/testcase.yaml b/tests/kernel/workq/work_queue_api/testcase.yaml deleted file mode 100644 index 57b1d1513dc..00000000000 --- a/tests/kernel/workq/work_queue_api/testcase.yaml +++ /dev/null @@ -1,5 +0,0 @@ -tests: - kernel.workqueue.api: - filter: CONFIG_KERNEL_WORK1 - min_flash: 34 - tags: kernel userspace