logging: backend: notify when process thread finishes one cycle
This adds the bits to allow the process thread to notify backends when it has finished processing pending log messages. This allows, for example, flash-based backends to group writing log messages to storage to limit wear, since log_output_flush() is called per message. Also the backend does not have to resort to using timer to periodically flush its buffer to storage, avoiding waking up the device when there are no messages. Another use of this is for backends requiring DMA transfers. Grouping all pending log messages into one DMA transfer is sometimes preferrable. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
31c13c892c
commit
d0d6e1181c
2 changed files with 30 additions and 0 deletions
|
@ -31,6 +31,19 @@ struct log_backend;
|
|||
* @brief Backend events
|
||||
*/
|
||||
enum log_backend_evt {
|
||||
/**
|
||||
* @brief Event when process thread finishes processing.
|
||||
*
|
||||
* This event is emitted when the process thread finishes
|
||||
* processing pending log messages.
|
||||
*
|
||||
* @note This is not emitted when there are no pending
|
||||
* log messages being processed.
|
||||
*
|
||||
* @note Deferred mode only.
|
||||
*/
|
||||
LOG_BACKEND_EVT_PROCESS_THREAD_DONE,
|
||||
|
||||
/** @brief Maximum number of backend events */
|
||||
LOG_BACKEND_EVT_MAX,
|
||||
};
|
||||
|
|
|
@ -624,6 +624,16 @@ int log_mem_get_max_usage(uint32_t *max)
|
|||
return mpsc_pbuf_get_max_utilization(&log_buffer, max);
|
||||
}
|
||||
|
||||
static void log_backend_notify_all(enum log_backend_evt event,
|
||||
union log_backend_evt_arg *arg)
|
||||
{
|
||||
for (int i = 0; i < log_backend_count_get(); i++) {
|
||||
const struct log_backend *backend = log_backend_get(i);
|
||||
|
||||
log_backend_notify(backend, event, arg);
|
||||
}
|
||||
}
|
||||
|
||||
static void log_process_thread_timer_expiry_fn(struct k_timer *timer)
|
||||
{
|
||||
k_sem_give(&log_process_thread_sem);
|
||||
|
@ -635,6 +645,7 @@ static void log_process_thread_func(void *dummy1, void *dummy2, void *dummy3)
|
|||
|
||||
uint32_t activate_mask = z_log_init(false, false);
|
||||
k_timeout_t timeout = K_MSEC(50); /* Arbitrary value */
|
||||
bool processed_any = false;
|
||||
|
||||
thread_set(k_current_get());
|
||||
|
||||
|
@ -650,7 +661,13 @@ static void log_process_thread_func(void *dummy1, void *dummy2, void *dummy3)
|
|||
}
|
||||
|
||||
if (log_process() == false) {
|
||||
if (processed_any) {
|
||||
processed_any = false;
|
||||
log_backend_notify_all(LOG_BACKEND_EVT_PROCESS_THREAD_DONE, NULL);
|
||||
}
|
||||
(void)k_sem_take(&log_process_thread_sem, timeout);
|
||||
} else {
|
||||
processed_any = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue