diff --git a/include/kernel.h b/include/kernel.h index f38cfa80154..f138978b26c 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -2990,10 +2990,7 @@ int k_work_submit_to_queue(struct k_work_q *queue, * * @return as with k_work_submit_to_queue(). */ -static inline int k_work_submit(struct k_work *work) -{ - return k_work_submit_to_queue(&k_sys_work_q, work); -} +extern int k_work_submit(struct k_work *work); /** @brief Wait for last-submitted instance to complete. * @@ -3277,11 +3274,8 @@ int k_work_schedule_for_queue(struct k_work_q *queue, * * @return as with k_work_schedule_for_queue(). */ -static inline int k_work_schedule(struct k_work_delayable *dwork, - k_timeout_t delay) -{ - return k_work_schedule_for_queue(&k_sys_work_q, dwork, delay); -} +extern int k_work_schedule(struct k_work_delayable *dwork, + k_timeout_t delay); /** @brief Reschedule a work item to a queue after a delay. * @@ -3328,11 +3322,8 @@ int k_work_reschedule_for_queue(struct k_work_q *queue, * * @return as with k_work_reschedule_for_queue(). */ -static inline int k_work_reschedule(struct k_work_delayable *dwork, - k_timeout_t delay) -{ - return k_work_reschedule_for_queue(&k_sys_work_q, dwork, delay); -} +extern int k_work_reschedule(struct k_work_delayable *dwork, + k_timeout_t delay); /** @brief Flush delayable work. * diff --git a/include/tracing/tracing.h b/include/tracing/tracing.h index a9b581d3315..9dac1db1984 100644 --- a/include/tracing/tracing.h +++ b/include/tracing/tracing.h @@ -314,6 +314,288 @@ +/** + * @brief Work Tracing APIs + * @defgroup work_tracing_apis Work Tracing APIs + * @ingroup tracing_apis + * @{ + */ + +/** + * @brief Trace initialisation of a Work structure + * @param work Work structure + */ +#define sys_port_trace_k_work_init(work) + +/** + * @brief Trace submit work to work queue call entry + * @param queue Work queue structure + * @param work Work structure + */ +#define sys_port_trace_k_work_submit_to_queue_enter(queue, work) + +/** + * @brief Trace submit work to work queue call exit + * @param queue Work queue structure + * @param work Work structure + * @param ret Return value + */ +#define sys_port_trace_k_work_submit_to_queue_exit(queue, work, ret) + +/** + * @brief Trace submit work to system work queue call entry + * @param work Work structure + */ +#define sys_port_trace_k_work_submit_enter(work) + +/** + * @brief Trace submit work to system work queue call exit + * @param work Work structure + * @param ret Return value + */ +#define sys_port_trace_k_work_submit_exit(work, ret) + +/** + * @brief Trace flush work call entry + * @param work Work structure + */ +#define sys_port_trace_k_work_flush_enter(work) + +/** + * @brief Trace flush work call blocking + * @param work Work structure + * @param timeout Timeout period + */ +#define sys_port_trace_k_work_flush_blocking(work, timeout) + +/** + * @brief Trace flush work call exit + * @param work Work structure + * @param ret Return value + */ +#define sys_port_trace_k_work_flush_exit(work, ret) + +/** + * @brief Trace cancel work call entry + * @param work Work structure + */ +#define sys_port_trace_k_work_cancel_enter(work) + +/** + * @brief Trace cancel work call exit + * @param work Work structure + * @param ret Return value + */ +#define sys_port_trace_k_work_cancel_exit(work, ret) + +/** + * @brief Trace cancel sync work call entry + * @param work Work structure + * @param sync Sync object + */ +#define sys_port_trace_k_work_cancel_sync_enter(work, sync) + +/** + * @brief Trace cancel sync work call blocking + * @param work Work structure + * @param sync Sync object + */ +#define sys_port_trace_k_work_cancel_sync_blocking(work, sync) + +/** + * @brief Trace cancel sync work call exit + * @param work Work structure + * @param sync Sync object + * @param ret Return value + */ +#define sys_port_trace_k_work_cancel_sync_exit(work, sync, ret) + +/** + * @} + */ /* end of work_tracing_apis */ + + + + +/** + * @brief Work Queue Tracing APIs + * @defgroup work_q_tracing_apis Work Queue Tracing APIs + * @ingroup tracing_apis + * @{ + */ + +/** + * @brief Trace start of a Work Queue call entry + * @param queue Work Queue structure + */ +#define sys_port_trace_k_work_queue_start_enter(queue) + +/** + * @brief Trace start of a Work Queue call exit + * @param queue Work Queue structure + */ +#define sys_port_trace_k_work_queue_start_exit(queue) + +/** + * @brief Trace Work Queue drain call entry + * @param queue Work Queue structure + */ +#define sys_port_trace_k_work_queue_drain_enter(queue) + +/** + * @brief Trace Work Queue drain call exit + * @param queue Work Queue structure + * @param ret Return value + */ +#define sys_port_trace_k_work_queue_drain_exit(queue, ret) + +/** + * @brief Trace Work Queue unplug call entry + * @param queue Work Queue structure + */ +#define sys_port_trace_k_work_queue_unplug_enter(queue) + +/** + * @brief Trace Work Queue unplug call exit + * @param queue Work Queue structure + * @param ret Return value + */ +#define sys_port_trace_k_work_queue_unplug_exit(queue, ret) + +/** + * @} + */ /* end of work_q_tracing_apis */ + + + + +/** + * @brief Work Delayable Tracing APIs + * @defgroup work_delayable_tracing_apis Work Delayable Tracing APIs + * @ingroup tracing_apis + * @{ + */ + +/** + * @brief Trace initialisation of a Delayable Work structure + * @param dwork Delayable Work structure + */ +#define sys_port_trace_k_work_delayable_init(dwork) + +/** + * @brief Trace schedule delayable work for queue enter + * @param queue Work Queue structure + * @param dwork Delayable Work structure + * @param delay Delay period + */ +#define sys_port_trace_k_work_schedule_for_queue_enter(queue, dwork, delay) + +/** + * @brief Trace schedule delayable work for queue exit + * @param queue Work Queue structure + * @param dwork Delayable Work structure + * @param delay Delay period + * @param ret Return value + */ +#define sys_port_trace_k_work_schedule_for_queue_exit(queue, dwork, delay, ret) + +/** + * @brief Trace schedule delayable work for system work queue enter + * @param dwork Delayable Work structure + * @param delay Delay period + */ +#define sys_port_trace_k_work_schedule_enter(dwork, delay) + +/** + * @brief Trace schedule delayable work for system work queue exit + * @param dwork Delayable Work structure + * @param delay Delay period + * @param ret Return value + */ +#define sys_port_trace_k_work_schedule_exit(dwork, delay, ret) + +/** + * @brief Trace reschedule delayable work for queue enter + * @param queue Work Queue structure + * @param dwork Delayable Work structure + * @param delay Delay period + */ +#define sys_port_trace_k_work_reschedule_for_queue_enter(queue, dwork, delay) + +/** + * @brief Trace reschedule delayable work for queue exit + * @param queue Work Queue structure + * @param dwork Delayable Work structure + * @param delay Delay period + * @param ret Return value + */ +#define sys_port_trace_k_work_reschedule_for_queue_exit(queue, dwork, delay, ret) + +/** + * @brief Trace reschedule delayable work for system queue enter + * @param dwork Delayable Work structure + * @param delay Delay period + */ +#define sys_port_trace_k_work_reschedule_enter(dwork, delay) + +/** + * @brief Trace reschedule delayable work for system queue exit + * @param dwork Delayable Work structure + * @param delay Delay period + * @param ret Return value + */ +#define sys_port_trace_k_work_reschedule_exit(dwork, delay, ret) + +/** + * @brief Trace delayable work flush enter + * @param dwork Delayable Work structure + * @param sync Sync object + */ +#define sys_port_trace_k_work_flush_delayable_enter(dwork, sync) + +/** + * @brief Trace delayable work flush exit + * @param dwork Delayable Work structure + * @param sync Sync object + * @param ret Return value + */ +#define sys_port_trace_k_work_flush_delayable_exit(dwork, sync, ret) + +/** + * @brief Trace delayable work cancel enter + * @param dwork Delayable Work structure + */ +#define sys_port_trace_k_work_cancel_delayable_enter(dwork) + +/** + * @brief Trace delayable work cancel enter + * @param dwork Delayable Work structure + * @param ret Return value + */ +#define sys_port_trace_k_work_cancel_delayable_exit(dwork, ret) + +/** + * @brief Trace delayable work cancel sync enter + * @param dwork Delayable Work structure + * @param sync Sync object + */ +#define sys_port_trace_k_work_cancel_delayable_sync_enter(dwork, sync) + +/** + * @brief Trace delayable work cancel sync enter + * @param dwork Delayable Work structure + * @param sync Sync object + * @param ret Return value + */ +#define sys_port_trace_k_work_cancel_delayable_sync_exit(dwork, sync, ret) + +/** + * @} + */ /* end of work_delayable_tracing_apis */ + + + + /** * @brief Work Poll Tracing APIs * @defgroup work_poll_tracing_apis Work Poll Tracing APIs diff --git a/kernel/work.c b/kernel/work.c index 9f3161c15bb..55abdd51677 100644 --- a/kernel/work.c +++ b/kernel/work.c @@ -138,6 +138,8 @@ void k_work_init(struct k_work *work, __ASSERT_NO_MSG(handler != NULL); *work = (struct k_work)Z_WORK_INITIALIZER(handler); + + SYS_PORT_TRACING_OBJ_INIT(k_work, work); } static inline int work_busy_get_locked(const struct k_work *work) @@ -359,6 +361,9 @@ int k_work_submit_to_queue(struct k_work_q *queue, __ASSERT_NO_MSG(work != NULL); k_spinlock_key_t key = k_spin_lock(&lock); + + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, submit_to_queue, queue, work); + int ret = submit_to_queue_locked(work, &queue); k_spin_unlock(&lock, key); @@ -372,6 +377,18 @@ int k_work_submit_to_queue(struct k_work_q *queue, k_yield(); } + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, submit_to_queue, queue, work, ret); + + return ret; +} + +int k_work_submit(struct k_work *work) +{ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, submit, work); + + int ret = k_work_submit_to_queue(&k_sys_work_q, work); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, submit, work, ret); return ret; } @@ -420,6 +437,8 @@ bool k_work_flush(struct k_work *work, __ASSERT_NO_MSG(arch_mem_coherent(sync)); #endif + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, flush, work); + struct z_work_flusher *flusher = &sync->flusher; k_spinlock_key_t key = k_spin_lock(&lock); @@ -429,9 +448,13 @@ bool k_work_flush(struct k_work *work, /* If necessary wait until the flusher item completes */ if (need_flush) { + SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_work, flush, work, K_FOREVER); + k_sem_take(&flusher->sem, K_FOREVER); } + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, flush, work, need_flush); + return need_flush; } @@ -503,11 +526,15 @@ int k_work_cancel(struct k_work *work) __ASSERT_NO_MSG(work != NULL); __ASSERT_NO_MSG(!flag_test(&work->flags, K_WORK_DELAYABLE_BIT)); + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, cancel, work); + k_spinlock_key_t key = k_spin_lock(&lock); int ret = cancel_async_locked(work); k_spin_unlock(&lock, key); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, cancel, work, ret); + return ret; } @@ -522,6 +549,8 @@ bool k_work_cancel_sync(struct k_work *work, __ASSERT_NO_MSG(arch_mem_coherent(sync)); #endif + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, cancel_sync, work, sync); + struct z_work_canceller *canceller = &sync->canceller; k_spinlock_key_t key = k_spin_lock(&lock); bool pending = (work_busy_get_locked(work) != 0U); @@ -535,9 +564,12 @@ bool k_work_cancel_sync(struct k_work *work, k_spin_unlock(&lock, key); if (need_wait) { + SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_work, cancel_sync, work, sync); + k_sem_take(&canceller->sem, K_FOREVER); } + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, cancel_sync, work, sync, pending); return pending; } @@ -711,6 +743,8 @@ void k_work_queue_start(struct k_work_q *queue, __ASSERT_NO_MSG(!flag_test(&queue->flags, K_WORK_QUEUE_STARTED_BIT)); uint32_t flags = K_WORK_QUEUE_STARTED; + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work_queue, start, queue); + sys_slist_init(&queue->pending); z_waitq_init(&queue->notifyq); z_waitq_init(&queue->drainq); @@ -734,6 +768,8 @@ void k_work_queue_start(struct k_work_q *queue, } k_thread_start(&queue->thread); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work_queue, start, queue); } int k_work_queue_drain(struct k_work_q *queue, @@ -742,6 +778,8 @@ int k_work_queue_drain(struct k_work_q *queue, __ASSERT_NO_MSG(queue); __ASSERT_NO_MSG(!k_is_in_isr()); + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work_queue, drain, queue); + int ret = 0; k_spinlock_key_t key = k_spin_lock(&lock); @@ -761,6 +799,8 @@ int k_work_queue_drain(struct k_work_q *queue, k_spin_unlock(&lock, key); } + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work_queue, drain, queue, ret); + return ret; } @@ -768,6 +808,8 @@ int k_work_queue_unplug(struct k_work_q *queue) { __ASSERT_NO_MSG(queue); + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work_queue, unplug, queue); + int ret = -EALREADY; k_spinlock_key_t key = k_spin_lock(&lock); @@ -777,6 +819,8 @@ int k_work_queue_unplug(struct k_work_q *queue) k_spin_unlock(&lock, key); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work_queue, unplug, queue, ret); + return ret; } @@ -824,6 +868,8 @@ void k_work_init_delayable(struct k_work_delayable *dwork, }, }; z_init_timeout(&dwork->timeout); + + SYS_PORT_TRACING_OBJ_INIT(k_work_delayable, dwork); } static inline int work_delayable_busy_get_locked(const struct k_work_delayable *dwork) @@ -933,6 +979,8 @@ int k_work_schedule_for_queue(struct k_work_q *queue, { __ASSERT_NO_MSG(dwork != NULL); + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, schedule_for_queue, queue, dwork, delay); + struct k_work *work = &dwork->work; int ret = 0; k_spinlock_key_t key = k_spin_lock(&lock); @@ -944,6 +992,20 @@ int k_work_schedule_for_queue(struct k_work_q *queue, k_spin_unlock(&lock, key); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, schedule_for_queue, queue, dwork, delay, ret); + + return ret; +} + +int k_work_schedule(struct k_work_delayable *dwork, + k_timeout_t delay) +{ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, schedule, dwork, delay); + + int ret = k_work_schedule_for_queue(&k_sys_work_q, dwork, delay); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, schedule, dwork, delay, ret); + return ret; } @@ -953,6 +1015,8 @@ int k_work_reschedule_for_queue(struct k_work_q *queue, { __ASSERT_NO_MSG(dwork != NULL); + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, reschedule_for_queue, queue, dwork, delay); + int ret = 0; k_spinlock_key_t key = k_spin_lock(&lock); @@ -964,6 +1028,20 @@ int k_work_reschedule_for_queue(struct k_work_q *queue, k_spin_unlock(&lock, key); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, reschedule_for_queue, queue, dwork, delay, ret); + + return ret; +} + +int k_work_reschedule(struct k_work_delayable *dwork, + k_timeout_t delay) +{ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, reschedule, dwork, delay); + + int ret = k_work_reschedule_for_queue(&k_sys_work_q, dwork, delay); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, reschedule, dwork, delay, ret); + return ret; } @@ -971,10 +1049,15 @@ int k_work_cancel_delayable(struct k_work_delayable *dwork) { __ASSERT_NO_MSG(dwork != NULL); + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, cancel_delayable, dwork); + k_spinlock_key_t key = k_spin_lock(&lock); int ret = cancel_delayable_async_locked(dwork); k_spin_unlock(&lock, key); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, cancel_delayable, dwork, ret); + return ret; } @@ -988,6 +1071,8 @@ bool k_work_cancel_delayable_sync(struct k_work_delayable *dwork, __ASSERT_NO_MSG(arch_mem_coherent(sync)); #endif + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, cancel_delayable_sync, dwork, sync); + struct z_work_canceller *canceller = &sync->canceller; k_spinlock_key_t key = k_spin_lock(&lock); bool pending = (work_delayable_busy_get_locked(dwork) != 0U); @@ -1004,6 +1089,7 @@ bool k_work_cancel_delayable_sync(struct k_work_delayable *dwork, k_sem_take(&canceller->sem, K_FOREVER); } + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, cancel_delayable_sync, dwork, sync, pending); return pending; } @@ -1017,6 +1103,8 @@ bool k_work_flush_delayable(struct k_work_delayable *dwork, __ASSERT_NO_MSG(arch_mem_coherent(sync)); #endif + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_work, flush_delayable, dwork, sync); + struct k_work *work = &dwork->work; struct z_work_flusher *flusher = &sync->flusher; k_spinlock_key_t key = k_spin_lock(&lock); @@ -1024,6 +1112,9 @@ bool k_work_flush_delayable(struct k_work_delayable *dwork, /* If it's idle release the lock and return immediately. */ if (work_busy_get_locked(work) == 0U) { k_spin_unlock(&lock, key); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, flush_delayable, dwork, sync, false); + return false; } @@ -1046,6 +1137,8 @@ bool k_work_flush_delayable(struct k_work_delayable *dwork, k_sem_take(&flusher->sem, K_FOREVER); } + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, flush_delayable, dwork, sync, need_flush); + return need_flush; }