From f984823e0de21185704f0bac6c4a2a0a10ef0d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Leksell?= Date: Fri, 26 Mar 2021 11:19:35 +0100 Subject: [PATCH] Tracing: Queue tracing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Queue tracing hooks, default hooks, and documentation. Signed-off-by: Torbjörn Leksell Signed-off-by: Anas Nashif --- include/kernel.h | 29 +----- include/tracing/tracing.h | 207 ++++++++++++++++++++++++++++++++++++++ kernel/queue.c | 124 ++++++++++++++++++++++- 3 files changed, 331 insertions(+), 29 deletions(-) diff --git a/include/kernel.h b/include/kernel.h index 5fa7bde848e..2ff9b803cd9 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -1870,10 +1870,7 @@ __syscall void *k_queue_get(struct k_queue *queue, k_timeout_t timeout); * * @return true if data item was removed */ -static inline bool k_queue_remove(struct k_queue *queue, void *data) -{ - return sys_sflist_find_and_remove(&queue->data_q, (sys_sfnode_t *)data); -} +bool k_queue_remove(struct k_queue *queue, void *data); /** * @brief Append an element to a queue only if it's not present already. @@ -1889,19 +1886,7 @@ static inline bool k_queue_remove(struct k_queue *queue, void *data) * * @return true if data item was added, false if not */ -static inline bool k_queue_unique_append(struct k_queue *queue, void *data) -{ - sys_sfnode_t *test; - - SYS_SFLIST_FOR_EACH_NODE(&queue->data_q, test) { - if (test == (sys_sfnode_t *) data) { - return false; - } - } - - k_queue_append(queue, data); - return true; -} +bool k_queue_unique_append(struct k_queue *queue, void *data); /** * @brief Query a queue to see if it has data available. @@ -1934,11 +1919,6 @@ static inline int z_impl_k_queue_is_empty(struct k_queue *queue) */ __syscall void *k_queue_peek_head(struct k_queue *queue); -static inline void *z_impl_k_queue_peek_head(struct k_queue *queue) -{ - return z_queue_node_peek(sys_sflist_peek_head(&queue->data_q), false); -} - /** * @brief Peek element at the tail of queue. * @@ -1950,11 +1930,6 @@ static inline void *z_impl_k_queue_peek_head(struct k_queue *queue) */ __syscall void *k_queue_peek_tail(struct k_queue *queue); -static inline void *z_impl_k_queue_peek_tail(struct k_queue *queue) -{ - return z_queue_node_peek(sys_sflist_peek_tail(&queue->data_q), false); -} - /** * @brief Statically define and initialize a queue. * diff --git a/include/tracing/tracing.h b/include/tracing/tracing.h index c280d2e48e8..17ef1448d5d 100644 --- a/include/tracing/tracing.h +++ b/include/tracing/tracing.h @@ -494,6 +494,213 @@ */ /* end of condvar_tracing_apis */ + + +/** + * @brief Queue Tracing APIs + * @defgroup queue_tracing_apis Queue Tracing APIs + * @ingroup tracing_apis + * @{ + */ + +/** + * @brief Trace initialization of Queue + * @param queue Queue object + */ +#define sys_port_trace_k_queue_init(queue) + +/** + * @brief Trace Queue cancel wait + * @param queue Queue object + */ +#define sys_port_trace_k_queue_cancel_wait(queue) + +/** + * @brief Trace Queue insert attempt entry + * @param queue Queue object + * @param alloc Allocation flag + */ +#define sys_port_trace_k_queue_queue_insert_enter(queue, alloc) + +/** + * @brief Trace Queue insert attempt blocking + * @param queue Queue object + * @param alloc Allocation flag + * @param timeout Timeout period + */ +#define sys_port_trace_k_queue_queue_insert_blocking(queue, alloc, timeout) + +/** + * @brief Trace Queue insert attempt outcome + * @param queue Queue object + * @param alloc Allocation flag + * @param ret Return value + */ +#define sys_port_trace_k_queue_queue_insert_exit(queue, alloc, ret) + +/** + * @brief Trace Queue append enter + * @param queue Queue object + */ +#define sys_port_trace_k_queue_append_enter(queue) + +/** + * @brief Trace Queue append exit + * @param queue Queue object + */ +#define sys_port_trace_k_queue_append_exit(queue) + +/** + * @brief Trace Queue alloc append enter + * @param queue Queue object + */ +#define sys_port_trace_k_queue_alloc_append_enter(queue) + +/** + * @brief Trace Queue alloc append exit + * @param queue Queue object + * @param ret Return value + */ +#define sys_port_trace_k_queue_alloc_append_exit(queue, ret) + +/** + * @brief Trace Queue prepend enter + * @param queue Queue object + */ +#define sys_port_trace_k_queue_prepend_enter(queue) + +/** + * @brief Trace Queue prepend exit + * @param queue Queue object + */ +#define sys_port_trace_k_queue_prepend_exit(queue) + +/** + * @brief Trace Queue alloc prepend enter + * @param queue Queue object + */ +#define sys_port_trace_k_queue_alloc_prepend_enter(queue) + +/** + * @brief Trace Queue alloc prepend exit + * @param queue Queue object + * @param ret Return value + */ +#define sys_port_trace_k_queue_alloc_prepend_exit(queue, ret) + +/** + * @brief Trace Queue insert attempt entry + * @param queue Queue object + */ +#define sys_port_trace_k_queue_insert_enter(queue) + +/** + * @brief Trace Queue insert attempt blocking + * @param queue Queue object + * @param timeout Timeout period + */ +#define sys_port_trace_k_queue_insert_blocking(queue, timeout) + +/** + * @brief Trace Queue insert attempt exit + * @param queue Queue object + */ +#define sys_port_trace_k_queue_insert_exit(queue) + +/** + * @brief Trace Queue append list enter + * @param queue Queue object + */ +#define sys_port_trace_k_queue_append_list_enter(queue) + +/** + * @brief Trace Queue append list exit + * @param queue Queue object + * @param ret Return value + */ +#define sys_port_trace_k_queue_append_list_exit(queue, ret) + +/** + * @brief Trace Queue merge slist enter + * @param queue Queue object + */ +#define sys_port_trace_k_queue_merge_slist_enter(queue) + +/** + * @brief Trace Queue merge slist exit + * @param queue Queue object + * @param ret Return value + */ +#define sys_port_trace_k_queue_merge_slist_exit(queue, ret) + +/** + * @brief Trace Queue get attempt enter + * @param queue Queue object + * @param timeout Timeout period + */ +#define sys_port_trace_k_queue_get_enter(queue, timeout) + +/** + * @brief Trace Queue get attempt blockings + * @param queue Queue object + * @param timeout Timeout period + */ +#define sys_port_trace_k_queue_get_blocking(queue, timeout) + +/** + * @brief Trace Queue get attempt outcome + * @param queue Queue object + * @param timeout Timeout period + * @param ret Return value + */ +#define sys_port_trace_k_queue_get_exit(queue, timeout, ret) + +/** + * @brief Trace Queue remove enter + * @param queue Queue object + */ +#define sys_port_trace_k_queue_remove_enter(queue) + +/** + * @brief Trace Queue remove exit + * @param queue Queue object + * @param ret Return value + */ +#define sys_port_trace_queue_remove_exit(queue, ret) + +/** + * @brief Trace Queue unique append enter + * @param queue Queue object + */ +#define sys_port_trace_k_queue_unique_append_enter(queue) + +/** + * @brief Trace Queue unique append exit + * @param queue Queue object + * + * @param ret Return value + */ +#define sys_port_trace_k_queue_unique_append_exit(queue, ret) + +/** + * @brief Trace Queue peek head + * @param queue Queue object + * @param ret Return value + */ +#define sys_port_trace_k_queue_peek_head(queue, ret) + +/** + * @brief Trace Queue peek tail + * @param queue Queue object + * @param ret Return value + */ +#define sys_port_trace_k_queue_peek_tail(queue, ret) + +/** + * @} + */ /* end of queue_tracing_apis */ + + /** * @} */ diff --git a/kernel/queue.c b/kernel/queue.c index e082080bc1c..2c113a207f6 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -85,6 +85,8 @@ void z_impl_k_queue_init(struct k_queue *queue) sys_dlist_init(&queue->poll_events); #endif + SYS_PORT_TRACING_OBJ_INIT(k_queue, queue); + SYS_TRACING_OBJ_INIT(k_queue, queue); z_object_init(queue); } @@ -113,6 +115,8 @@ static inline void handle_poll_events(struct k_queue *queue, uint32_t state) void z_impl_k_queue_cancel_wait(struct k_queue *queue) { + SYS_PORT_TRACING_OBJ_FUNC(k_queue, cancel_wait, queue); + k_spinlock_key_t key = k_spin_lock(&queue->lock); struct k_thread *first_pending_thread; @@ -141,14 +145,21 @@ static int32_t queue_insert(struct k_queue *queue, void *prev, void *data, struct k_thread *first_pending_thread; k_spinlock_key_t key = k_spin_lock(&queue->lock); + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, queue_insert, queue, alloc); + if (is_append) { prev = sys_sflist_peek_tail(&queue->data_q); } first_pending_thread = z_unpend_first_thread(&queue->wait_q); if (first_pending_thread != NULL) { + SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_queue, queue_insert, queue, alloc, K_FOREVER); + prepare_thread_to_run(first_pending_thread, data); z_reschedule(&queue->lock, key); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, queue_insert, queue, alloc, 0); + return 0; } @@ -159,6 +170,10 @@ static int32_t queue_insert(struct k_queue *queue, void *prev, void *data, anode = z_thread_malloc(sizeof(*anode)); if (anode == NULL) { k_spin_unlock(&queue->lock, key); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, queue_insert, queue, alloc, + -ENOMEM); + return -ENOMEM; } anode->data = data; @@ -168,30 +183,53 @@ static int32_t queue_insert(struct k_queue *queue, void *prev, void *data, sys_sfnode_init(data, 0x0); } + SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_queue, queue_insert, queue, alloc, K_FOREVER); + sys_sflist_insert(&queue->data_q, prev, data); handle_poll_events(queue, K_POLL_STATE_DATA_AVAILABLE); z_reschedule(&queue->lock, key); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, queue_insert, queue, alloc, 0); + return 0; } void k_queue_insert(struct k_queue *queue, void *prev, void *data) { + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, insert, queue); + (void)queue_insert(queue, prev, data, false, false); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, insert, queue); } void k_queue_append(struct k_queue *queue, void *data) { + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, append, queue); + (void)queue_insert(queue, NULL, data, false, true); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, append, queue); } void k_queue_prepend(struct k_queue *queue, void *data) { + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, prepend, queue); + (void)queue_insert(queue, NULL, data, false, false); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, prepend, queue); } int32_t z_impl_k_queue_alloc_append(struct k_queue *queue, void *data) { - return queue_insert(queue, NULL, data, true, true); + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, alloc_append, queue); + + int32_t ret = queue_insert(queue, NULL, data, true, true); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, alloc_append, queue, ret); + + return ret; } #ifdef CONFIG_USERSPACE @@ -206,8 +244,13 @@ static inline int32_t z_vrfy_k_queue_alloc_append(struct k_queue *queue, int32_t z_impl_k_queue_alloc_prepend(struct k_queue *queue, void *data) { - return queue_insert(queue, NULL, data, true, false); + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, alloc_prepend, queue); + int32_t ret = queue_insert(queue, NULL, data, true, false); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, alloc_prepend, queue, ret); + + return ret; } #ifdef CONFIG_USERSPACE @@ -222,8 +265,12 @@ static inline int32_t z_vrfy_k_queue_alloc_prepend(struct k_queue *queue, int k_queue_append_list(struct k_queue *queue, void *head, void *tail) { + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, append_list, queue); + /* invalid head or tail of list */ CHECKIF(head == NULL || tail == NULL) { + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, append_list, queue, -EINVAL); + return -EINVAL; } @@ -244,6 +291,8 @@ int k_queue_append_list(struct k_queue *queue, void *head, void *tail) sys_sflist_append_list(&queue->data_q, head, tail); } + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, append_list, queue, 0); + handle_poll_events(queue, K_POLL_STATE_DATA_AVAILABLE); z_reschedule(&queue->lock, key); return 0; @@ -253,8 +302,12 @@ int k_queue_merge_slist(struct k_queue *queue, sys_slist_t *list) { int ret; + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, merge_slist, queue); + /* list must not be empty */ CHECKIF(sys_slist_is_empty(list)) { + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, merge_slist, queue, -EINVAL); + return -EINVAL; } @@ -269,10 +322,14 @@ int k_queue_merge_slist(struct k_queue *queue, sys_slist_t *list) */ ret = k_queue_append_list(queue, list->head, list->tail); CHECKIF(ret != 0) { + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, merge_slist, queue, ret); + return ret; } sys_slist_init(list); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, merge_slist, queue, 0); + return 0; } @@ -281,25 +338,88 @@ void *z_impl_k_queue_get(struct k_queue *queue, k_timeout_t timeout) k_spinlock_key_t key = k_spin_lock(&queue->lock); void *data; + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, get, queue, timeout); + if (likely(!sys_sflist_is_empty(&queue->data_q))) { sys_sfnode_t *node; node = sys_sflist_get_not_empty(&queue->data_q); data = z_queue_node_peek(node, true); k_spin_unlock(&queue->lock, key); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, get, queue, timeout, data); + return data; } + SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(k_queue, get, queue, timeout); + if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { k_spin_unlock(&queue->lock, key); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, get, queue, timeout, NULL); + return NULL; } int ret = z_pend_curr(&queue->lock, key, &queue->wait_q, timeout); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, get, queue, timeout, + (ret != 0) ? NULL : _current->base.swap_data); + return (ret != 0) ? NULL : _current->base.swap_data; } +bool k_queue_remove(struct k_queue *queue, void *data) +{ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, remove, queue); + + bool ret = sys_sflist_find_and_remove(&queue->data_q, (sys_sfnode_t *)data); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, remove, queue, ret); + + return ret; +} + +bool k_queue_unique_append(struct k_queue *queue, void *data) +{ + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_queue, unique_append, queue); + + sys_sfnode_t *test; + + SYS_SFLIST_FOR_EACH_NODE(&queue->data_q, test) { + if (test == (sys_sfnode_t *) data) { + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, unique_append, queue, false); + + return false; + } + } + + k_queue_append(queue, data); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_queue, unique_append, queue, true); + + return true; +} + +void *z_impl_k_queue_peek_head(struct k_queue *queue) +{ + void *ret = z_queue_node_peek(sys_sflist_peek_head(&queue->data_q), false); + + SYS_PORT_TRACING_OBJ_FUNC(k_queue, peek_head, queue, ret); + + return ret; +} + +void *z_impl_k_queue_peek_tail(struct k_queue *queue) +{ + void *ret = z_queue_node_peek(sys_sflist_peek_tail(&queue->data_q), false); + + SYS_PORT_TRACING_OBJ_FUNC(k_queue, peek_tail, queue, ret); + + return ret; +} + #ifdef CONFIG_USERSPACE static inline void *z_vrfy_k_queue_get(struct k_queue *queue, k_timeout_t timeout)