kernel: Add k_thread_foreach API

Add k_thread_foreach API to iterate over all the threads in
the system.

This API can be used for debugging threads in multi threaded
environment to dump and analyze various thread parameters like
priority, state, stack address etc...

Signed-off-by: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
This commit is contained in:
Ramakrishna Pallala 2018-04-27 12:55:43 +05:30 committed by Anas Nashif
commit 110b8e42ff
2 changed files with 44 additions and 0 deletions

View file

@ -533,6 +533,8 @@ enum execution_context_types {
* @ingroup kernel_apis
* @{
*/
typedef void (*k_thread_user_cb_t)(const struct k_thread *thread,
void *user_data);
/**
* @brief Analyze the main, idle, interrupt and system workqueue call stacks
@ -552,6 +554,25 @@ enum execution_context_types {
*/
extern void k_call_stacks_analyze(void);
/**
* @brief Iterate over all the threads in the system.
*
* This routine iterates over all the threads in the system and
* calls the user_cb function for each thread.
*
* @param user_cb Pointer to the user callback function.
* @param user_data Pointer to user data.
*
* @note CONFIG_THREAD_MONITOR must be set for this function
* to be effective. Also this API uses irq_lock to protect the
* _kernel.threads list which means creation of new threads and
* terminations of existing threads are blocked until this
* API returns.
*
* @return N/A
*/
extern void k_thread_foreach(k_thread_user_cb_t user_cb, void *user_data);
/** @} */
/**

View file

@ -36,6 +36,29 @@ extern struct _static_thread_data _static_thread_data_list_end[];
thread_data < _static_thread_data_list_end; \
thread_data++)
#if defined(CONFIG_THREAD_MONITOR)
void k_thread_foreach(k_thread_user_cb_t user_cb, void *user_data)
{
struct k_thread *thread;
unsigned int key;
__ASSERT(user_cb, "user_cb can not be NULL");
/*
* Lock is needed to make sure that the _kernel.threads is not being
* modified by the user_cb either dircetly or indircetly.
* The indircet ways are through calling k_thread_create and
* k_thread_abort from user_cb.
*/
key = irq_lock();
for (thread = _kernel.threads; thread; thread = thread->next_thread) {
user_cb(thread, user_data);
}
irq_unlock(key);
}
#else
void k_thread_foreach(k_thread_user_cb_t user_cb, void *user_data) { }
#endif
int k_is_in_isr(void)
{