LCOV - code coverage report
Current view: top level - home/runner/zephyrproject/zephyr/subsys/logging - log_core.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 79 219 36.1 %
Date: 2024-09-16 20:15:30 Functions: 14 43 32.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 20 80 25.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2018 Nordic Semiconductor ASA
       3                 :            :  *
       4                 :            :  * SPDX-License-Identifier: Apache-2.0
       5                 :            :  */
       6                 :            : #include <zephyr/logging/log.h>
       7                 :            : #include <zephyr/logging/log_backend.h>
       8                 :            : #include <zephyr/logging/log_ctrl.h>
       9                 :            : #include <zephyr/logging/log_output.h>
      10                 :            : #include <zephyr/logging/log_internal.h>
      11                 :            : #include <zephyr/sys/mpsc_pbuf.h>
      12                 :            : #include <zephyr/logging/log_link.h>
      13                 :            : #include <zephyr/sys/printk.h>
      14                 :            : #include <zephyr/sys_clock.h>
      15                 :            : #include <zephyr/init.h>
      16                 :            : #include <zephyr/sys/__assert.h>
      17                 :            : #include <zephyr/sys/atomic.h>
      18                 :            : #include <zephyr/sys/iterable_sections.h>
      19                 :            : #include <ctype.h>
      20                 :            : #include <zephyr/logging/log_frontend.h>
      21                 :            : #include <zephyr/internal/syscall_handler.h>
      22                 :            : #include <zephyr/logging/log_output_dict.h>
      23                 :            : #include <zephyr/logging/log_output_custom.h>
      24                 :            : #include <zephyr/linker/utils.h>
      25                 :            : 
      26                 :            : #ifdef CONFIG_LOG_TIMESTAMP_USE_REALTIME
      27                 :            : #include <zephyr/posix/time.h>
      28                 :            : #endif
      29                 :            : 
      30                 :            : LOG_MODULE_REGISTER(log);
      31                 :            : 
      32                 :            : #ifndef CONFIG_LOG_PROCESS_THREAD_SLEEP_MS
      33                 :            : #define CONFIG_LOG_PROCESS_THREAD_SLEEP_MS 0
      34                 :            : #endif
      35                 :            : 
      36                 :            : #ifndef CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD
      37                 :            : #define CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD 0
      38                 :            : #endif
      39                 :            : 
      40                 :            : #ifndef CONFIG_LOG_PROCESS_THREAD_STACK_SIZE
      41                 :            : #define CONFIG_LOG_PROCESS_THREAD_STACK_SIZE 1
      42                 :            : #endif
      43                 :            : 
      44                 :            : #ifndef CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS
      45                 :            : #define CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS 0
      46                 :            : #endif
      47                 :            : 
      48                 :            : #ifndef CONFIG_LOG_PROCESSING_LATENCY_US
      49                 :            : #define CONFIG_LOG_PROCESSING_LATENCY_US 0
      50                 :            : #endif
      51                 :            : 
      52                 :            : #ifndef CONFIG_LOG_BUFFER_SIZE
      53                 :            : #define CONFIG_LOG_BUFFER_SIZE 4
      54                 :            : #endif
      55                 :            : 
      56                 :            : #ifdef CONFIG_LOG_PROCESS_THREAD_CUSTOM_PRIORITY
      57                 :            : #define LOG_PROCESS_THREAD_PRIORITY CONFIG_LOG_PROCESS_THREAD_PRIORITY
      58                 :            : #else
      59                 :            : #define LOG_PROCESS_THREAD_PRIORITY K_LOWEST_APPLICATION_THREAD_PRIO
      60                 :            : #endif
      61                 :            : 
      62                 :            : #ifndef CONFIG_LOG_TAG_MAX_LEN
      63                 :            : #define CONFIG_LOG_TAG_MAX_LEN 0
      64                 :            : #endif
      65                 :            : 
      66                 :            : #ifndef CONFIG_LOG_FAILURE_REPORT_PERIOD
      67                 :            : #define CONFIG_LOG_FAILURE_REPORT_PERIOD 0
      68                 :            : #endif
      69                 :            : 
      70                 :            : #ifndef CONFIG_LOG_ALWAYS_RUNTIME
      71                 :            : BUILD_ASSERT(!IS_ENABLED(CONFIG_NO_OPTIMIZATIONS),
      72                 :            :              "CONFIG_LOG_ALWAYS_RUNTIME must be enabled when "
      73                 :            :              "CONFIG_NO_OPTIMIZATIONS is set");
      74                 :            : BUILD_ASSERT(!IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE),
      75                 :            :              "CONFIG_LOG_ALWAYS_RUNTIME must be enabled when "
      76                 :            :              "CONFIG_LOG_MODE_IMMEDIATE is set");
      77                 :            : #endif
      78                 :            : 
      79                 :            : static const log_format_func_t format_table[] = {
      80                 :            :         [LOG_OUTPUT_TEXT] = IS_ENABLED(CONFIG_LOG_OUTPUT) ?
      81                 :            :                                                 log_output_msg_process : NULL,
      82                 :            :         [LOG_OUTPUT_SYST] = IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE) ?
      83                 :            :                                                 log_output_msg_syst_process : NULL,
      84                 :            :         [LOG_OUTPUT_DICT] = IS_ENABLED(CONFIG_LOG_DICTIONARY_SUPPORT) ?
      85                 :            :                                                 log_dict_output_msg_process : NULL,
      86                 :            :         [LOG_OUTPUT_CUSTOM] = IS_ENABLED(CONFIG_LOG_CUSTOM_FORMAT_SUPPORT) ?
      87                 :            :                                                 log_custom_output_msg_process : NULL,
      88                 :            : };
      89                 :            : 
      90                 :        177 : log_format_func_t log_format_func_t_get(uint32_t log_type)
      91                 :            : {
      92                 :        177 :         return format_table[log_type];
      93                 :            : }
      94                 :            : 
      95                 :          0 : size_t log_format_table_size(void)
      96                 :            : {
      97                 :          0 :         return ARRAY_SIZE(format_table);
      98                 :            : }
      99                 :            : 
     100                 :            : K_SEM_DEFINE(log_process_thread_sem, 0, 1);
     101                 :            : 
     102                 :            : static atomic_t initialized;
     103                 :            : static bool panic_mode;
     104                 :            : static bool backend_attached;
     105                 :            : static atomic_t buffered_cnt;
     106                 :            : static atomic_t dropped_cnt;
     107                 :            : static k_tid_t proc_tid;
     108                 :            : static struct k_timer log_process_thread_timer;
     109                 :            : 
     110                 :            : static log_timestamp_t dummy_timestamp(void);
     111                 :            : static log_timestamp_get_t timestamp_func = dummy_timestamp;
     112                 :            : static uint32_t timestamp_freq;
     113                 :            : static log_timestamp_t proc_latency;
     114                 :            : static log_timestamp_t prev_timestamp;
     115                 :            : static atomic_t unordered_cnt;
     116                 :            : static uint64_t last_failure_report;
     117                 :            : 
     118                 :            : static STRUCT_SECTION_ITERABLE(log_msg_ptr, log_msg_ptr);
     119                 :            : static STRUCT_SECTION_ITERABLE_ALTERNATE(log_mpsc_pbuf, mpsc_pbuf_buffer, log_buffer);
     120                 :            : static struct mpsc_pbuf_buffer *curr_log_buffer;
     121                 :            : 
     122                 :            : #ifdef CONFIG_MPSC_PBUF
     123                 :            : static uint32_t __aligned(Z_LOG_MSG_ALIGNMENT)
     124                 :            :         buf32[CONFIG_LOG_BUFFER_SIZE / sizeof(int)];
     125                 :            : 
     126                 :            : static void z_log_notify_drop(const struct mpsc_pbuf_buffer *buffer,
     127                 :            :                               const union mpsc_pbuf_generic *item);
     128                 :            : 
     129                 :            : static const struct mpsc_pbuf_buffer_config mpsc_config = {
     130                 :            :         .buf = (uint32_t *)buf32,
     131                 :            :         .size = ARRAY_SIZE(buf32),
     132                 :            :         .notify_drop = z_log_notify_drop,
     133                 :            :         .get_wlen = log_msg_generic_get_wlen,
     134                 :            :         .flags = (IS_ENABLED(CONFIG_LOG_MODE_OVERFLOW) ?
     135                 :            :                   MPSC_PBUF_MODE_OVERWRITE : 0) |
     136                 :            :                  (IS_ENABLED(CONFIG_LOG_MEM_UTILIZATION) ?
     137                 :            :                   MPSC_PBUF_MAX_UTILIZATION : 0)
     138                 :            : };
     139                 :            : #endif
     140                 :            : 
     141                 :            : /* Check that default tag can fit in tag buffer. */
     142                 :            : COND_CODE_0(CONFIG_LOG_TAG_MAX_LEN, (),
     143                 :            :         (BUILD_ASSERT(sizeof(CONFIG_LOG_TAG_DEFAULT) <= CONFIG_LOG_TAG_MAX_LEN + 1,
     144                 :            :                       "Default string longer than tag capacity")));
     145                 :            : 
     146                 :            : static char tag[CONFIG_LOG_TAG_MAX_LEN + 1] =
     147                 :            :         COND_CODE_0(CONFIG_LOG_TAG_MAX_LEN, ({}), (CONFIG_LOG_TAG_DEFAULT));
     148                 :            : 
     149                 :            : static void msg_process(union log_msg_generic *msg);
     150                 :            : 
     151                 :          0 : static log_timestamp_t dummy_timestamp(void)
     152                 :            : {
     153                 :          0 :         return 0;
     154                 :            : }
     155                 :            : 
     156                 :          0 : log_timestamp_t z_log_timestamp(void)
     157                 :            : {
     158                 :          0 :         return timestamp_func();
     159                 :            : }
     160                 :            : 
     161                 :            : static void z_log_msg_post_finalize(void)
     162                 :            : {
     163                 :            :         atomic_val_t cnt = atomic_inc(&buffered_cnt);
     164                 :            : 
     165                 :            :         if (panic_mode) {
     166                 :            :                 static struct k_spinlock process_lock;
     167                 :            :                 k_spinlock_key_t key = k_spin_lock(&process_lock);
     168                 :            :                 (void)log_process();
     169                 :            : 
     170                 :            :                 k_spin_unlock(&process_lock, key);
     171                 :            :         } else if (proc_tid != NULL) {
     172                 :            :                 /*
     173                 :            :                  * If CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD == 1,
     174                 :            :                  * timer is never needed. We release the processing
     175                 :            :                  * thread after every message is posted.
     176                 :            :                  */
     177                 :            :                 if (CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD == 1) {
     178                 :            :                         if (cnt == 0) {
     179                 :            :                                 k_sem_give(&log_process_thread_sem);
     180                 :            :                         }
     181                 :            :                 } else {
     182                 :            :                         if (cnt == 0) {
     183                 :            :                                 k_timer_start(&log_process_thread_timer,
     184                 :            :                                               K_MSEC(CONFIG_LOG_PROCESS_THREAD_SLEEP_MS),
     185                 :            :                                               K_NO_WAIT);
     186                 :            :                         } else if (CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD &&
     187                 :            :                                    (cnt + 1) == CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD) {
     188                 :            :                                 k_timer_stop(&log_process_thread_timer);
     189                 :            :                                 k_sem_give(&log_process_thread_sem);
     190                 :            :                         } else {
     191                 :            :                                 /* No action needed. Message processing will be triggered by the
     192                 :            :                                  * timeout or when number of upcoming messages exceeds the
     193                 :            :                                  * threshold.
     194                 :            :                                  */
     195                 :            :                         }
     196                 :            :                 }
     197                 :            :         }
     198                 :            : }
     199                 :            : 
     200                 :          0 : const struct log_backend *log_format_set_all_active_backends(size_t log_type)
     201                 :            : {
     202                 :          0 :         const struct log_backend *failed_backend = NULL;
     203                 :            : 
     204   [ #  #  #  # ]:          0 :         STRUCT_SECTION_FOREACH(log_backend, backend) {
     205         [ #  # ]:          0 :                 if (log_backend_is_active(backend)) {
     206                 :          0 :                         int retCode = log_backend_format_set(backend, log_type);
     207                 :            : 
     208         [ #  # ]:          0 :                         if (retCode != 0) {
     209                 :          0 :                                 failed_backend = backend;
     210                 :            :                         }
     211                 :            :                 }
     212                 :            :         }
     213                 :          0 :         return failed_backend;
     214                 :            : }
     215                 :            : 
     216                 :        177 : void z_log_vprintk(const char *fmt, va_list ap)
     217                 :            : {
     218                 :        177 :         if (!IS_ENABLED(CONFIG_LOG_PRINTK)) {
     219                 :            :                 return;
     220                 :            :         }
     221                 :            : 
     222                 :        177 :         z_log_msg_runtime_vcreate(Z_LOG_LOCAL_DOMAIN_ID, NULL,
     223                 :            :                                    LOG_LEVEL_INTERNAL_RAW_STRING, NULL, 0,
     224                 :            :                                    Z_LOG_MSG_CBPRINTF_FLAGS(0),
     225                 :            :                                    fmt, ap);
     226                 :            : }
     227                 :            : 
     228                 :            : #ifndef CONFIG_LOG_TIMESTAMP_USE_REALTIME
     229                 :        177 : static log_timestamp_t default_get_timestamp(void)
     230                 :            : {
     231                 :        177 :         return IS_ENABLED(CONFIG_LOG_TIMESTAMP_64BIT) ?
     232                 :        177 :                 sys_clock_tick_get() : k_cycle_get_32();
     233                 :            : }
     234                 :            : 
     235                 :            : static log_timestamp_t default_lf_get_timestamp(void)
     236                 :            : {
     237                 :            :         return IS_ENABLED(CONFIG_LOG_TIMESTAMP_64BIT) ?
     238                 :            :                 k_uptime_get() : k_uptime_get_32();
     239                 :            : }
     240                 :            : #else
     241                 :            : static log_timestamp_t default_rt_get_timestamp(void)
     242                 :            : {
     243                 :            :         struct timespec tspec;
     244                 :            : 
     245                 :            :         clock_gettime(CLOCK_REALTIME, &tspec);
     246                 :            : 
     247                 :            :         return ((uint64_t)tspec.tv_sec * MSEC_PER_SEC) + (tspec.tv_nsec / NSEC_PER_MSEC);
     248                 :            : }
     249                 :            : #endif /* CONFIG_LOG_TIMESTAMP_USE_REALTIME */
     250                 :            : 
     251                 :          1 : void log_core_init(void)
     252                 :            : {
     253                 :          1 :         panic_mode = false;
     254                 :          1 :         dropped_cnt = 0;
     255                 :          1 :         buffered_cnt = 0;
     256                 :            : 
     257                 :          1 :         if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
     258                 :            :                 log_frontend_init();
     259                 :            : 
     260                 :            :                 for (uint16_t s = 0; s < log_src_cnt_get(0); s++) {
     261                 :            :                         log_frontend_filter_set(s, CONFIG_LOG_MAX_LEVEL);
     262                 :            :                 }
     263                 :            : 
     264                 :            :                 if (IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY)) {
     265                 :            :                         return;
     266                 :            :                 }
     267                 :            :         }
     268                 :            : 
     269                 :            :         /* Set default timestamp. */
     270                 :            : #ifdef CONFIG_LOG_TIMESTAMP_USE_REALTIME
     271                 :            :         log_set_timestamp_func(default_rt_get_timestamp, 1000U);
     272                 :            : #else
     273                 :          1 :         if (sys_clock_hw_cycles_per_sec() > 1000000) {
     274                 :            :                 log_set_timestamp_func(default_lf_get_timestamp, 1000U);
     275                 :            :         } else {
     276                 :          1 :                 uint32_t freq = IS_ENABLED(CONFIG_LOG_TIMESTAMP_64BIT) ?
     277                 :            :                         CONFIG_SYS_CLOCK_TICKS_PER_SEC : sys_clock_hw_cycles_per_sec();
     278                 :          1 :                 log_set_timestamp_func(default_get_timestamp, freq);
     279                 :            :         }
     280                 :            : #endif /* CONFIG_LOG_TIMESTAMP_USE_REALTIME */
     281                 :            : 
     282                 :          1 :         if (IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
     283                 :            :                 z_log_msg_init();
     284                 :            :         }
     285                 :            : 
     286                 :          1 :         if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) {
     287                 :            :                 z_log_runtime_filters_init();
     288                 :            :         }
     289                 :            : }
     290                 :            : 
     291                 :          0 : static uint32_t activate_foreach_backend(uint32_t mask)
     292                 :            : {
     293                 :          0 :         uint32_t mask_cpy = mask;
     294                 :            : 
     295         [ #  # ]:          0 :         while (mask_cpy) {
     296                 :          0 :                 uint32_t i = __builtin_ctz(mask_cpy);
     297                 :          0 :                 const struct log_backend *backend = log_backend_get(i);
     298                 :            : 
     299                 :          0 :                 mask_cpy &= ~BIT(i);
     300   [ #  #  #  # ]:          0 :                 if (backend->autostart && (log_backend_is_ready(backend) == 0)) {
     301                 :          0 :                         mask &= ~BIT(i);
     302                 :          0 :                         log_backend_enable(backend,
     303                 :          0 :                                            backend->cb->ctx,
     304                 :            :                                            CONFIG_LOG_MAX_LEVEL);
     305                 :            :                 }
     306                 :            :         }
     307                 :            : 
     308                 :          0 :         return mask;
     309                 :            : }
     310                 :            : 
     311                 :          2 : static uint32_t z_log_init(bool blocking, bool can_sleep)
     312                 :            : {
     313                 :          2 :         uint32_t mask = 0;
     314                 :            : 
     315                 :          2 :         if (IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY)) {
     316                 :            :                 return 0;
     317                 :            :         }
     318                 :            : 
     319         [ -  + ]:          2 :         __ASSERT_NO_MSG(log_backend_count_get() < LOG_FILTERS_MAX_BACKENDS);
     320                 :            : 
     321         [ +  + ]:          2 :         if (atomic_inc(&initialized) != 0) {
     322                 :            :                 return 0;
     323                 :            :         }
     324                 :            : 
     325                 :            :         if (IS_ENABLED(CONFIG_LOG_MULTIDOMAIN)) {
     326                 :            :                 z_log_links_initiate();
     327                 :            :         }
     328                 :            : 
     329                 :            :         int backend_index = 0;
     330                 :            : 
     331                 :            :         /* Activate autostart backends */
     332   [ -  +  +  + ]:          2 :         STRUCT_SECTION_FOREACH(log_backend, backend) {
     333         [ +  - ]:          1 :                 if (backend->autostart) {
     334                 :          1 :                         log_backend_init(backend);
     335                 :            : 
     336                 :            :                         /* If backend has activation function then backend is
     337                 :            :                          * not ready until activated.
     338                 :            :                          */
     339         [ +  - ]:          1 :                         if (log_backend_is_ready(backend) == 0) {
     340                 :          1 :                                 log_backend_enable(backend,
     341                 :          1 :                                                    backend->cb->ctx,
     342                 :            :                                                    CONFIG_LOG_MAX_LEVEL);
     343                 :            :                         } else {
     344                 :          0 :                                 mask |= BIT(backend_index);
     345                 :            :                         }
     346                 :            :                 }
     347                 :            : 
     348                 :          1 :                 ++backend_index;
     349                 :            :         }
     350                 :            : 
     351                 :            :         /* If blocking init, wait until all backends are activated. */
     352         [ -  + ]:          1 :         if (blocking) {
     353         [ #  # ]:          0 :                 while (mask) {
     354                 :          0 :                         mask = activate_foreach_backend(mask);
     355         [ #  # ]:          0 :                         if (IS_ENABLED(CONFIG_MULTITHREADING) && can_sleep) {
     356                 :          0 :                                 k_msleep(10);
     357                 :            :                         }
     358                 :            :                 }
     359                 :            :         }
     360                 :            : 
     361                 :            :         return mask;
     362                 :            : }
     363                 :            : 
     364                 :          0 : void log_init(void)
     365                 :            : {
     366                 :          0 :         (void)z_log_init(true, true);
     367                 :          0 : }
     368                 :            : 
     369                 :          0 : void log_thread_trigger(void)
     370                 :            : {
     371                 :          0 :         if (IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) {
     372                 :          0 :                 return;
     373                 :            :         }
     374                 :            : 
     375                 :            :         k_timer_stop(&log_process_thread_timer);
     376                 :            :         k_sem_give(&log_process_thread_sem);
     377                 :            : }
     378                 :            : 
     379                 :          0 : static void thread_set(k_tid_t process_tid)
     380                 :            : {
     381                 :          0 :         proc_tid = process_tid;
     382                 :            : 
     383                 :          0 :         if (IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) {
     384                 :          0 :                 return;
     385                 :            :         }
     386                 :            : 
     387                 :            :         if (CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD &&
     388                 :            :             process_tid &&
     389                 :            :             buffered_cnt >= CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD) {
     390                 :            :                 k_sem_give(&log_process_thread_sem);
     391                 :            :         }
     392                 :            : }
     393                 :            : 
     394                 :          0 : void log_thread_set(k_tid_t process_tid)
     395                 :            : {
     396                 :          0 :         if (IS_ENABLED(CONFIG_LOG_PROCESS_THREAD)) {
     397                 :            :                 __ASSERT_NO_MSG(0);
     398                 :            :         } else {
     399                 :          0 :                 thread_set(process_tid);
     400                 :            :         }
     401                 :          0 : }
     402                 :            : 
     403                 :          1 : int log_set_timestamp_func(log_timestamp_get_t timestamp_getter, uint32_t freq)
     404                 :            : {
     405         [ +  - ]:          1 :         if (timestamp_getter == NULL) {
     406                 :            :                 return -EINVAL;
     407                 :            :         }
     408                 :            : 
     409                 :          1 :         timestamp_func = timestamp_getter;
     410                 :          1 :         timestamp_freq = freq;
     411                 :          1 :         if (CONFIG_LOG_PROCESSING_LATENCY_US) {
     412                 :            :                 proc_latency = (freq * CONFIG_LOG_PROCESSING_LATENCY_US) / 1000000;
     413                 :            :         }
     414                 :            : 
     415                 :          1 :         if (IS_ENABLED(CONFIG_LOG_OUTPUT)) {
     416                 :          1 :                 log_output_timestamp_freq_set(freq);
     417                 :            :         }
     418                 :            : 
     419                 :          1 :         return 0;
     420                 :            : }
     421                 :            : 
     422                 :          1 : void z_impl_log_panic(void)
     423                 :            : {
     424         [ +  - ]:          1 :         if (panic_mode) {
     425                 :            :                 return;
     426                 :            :         }
     427                 :            : 
     428                 :            :         /* If panic happened early logger might not be initialized.
     429                 :            :          * Forcing initialization of the logger and auto-starting backends.
     430                 :            :          */
     431                 :          1 :         (void)z_log_init(true, false);
     432                 :            : 
     433                 :          1 :         if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
     434                 :            :                 log_frontend_panic();
     435                 :            :                 if (IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY)) {
     436                 :            :                         goto out;
     437                 :            :                 }
     438                 :            :         }
     439                 :            : 
     440   [ -  +  +  + ]:          2 :         STRUCT_SECTION_FOREACH(log_backend, backend) {
     441         [ +  - ]:          1 :                 if (log_backend_is_active(backend)) {
     442                 :          1 :                         log_backend_panic(backend);
     443                 :            :                 }
     444                 :            :         }
     445                 :            : 
     446                 :          1 :         if (!IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) {
     447                 :            :                 /* Flush */
     448                 :            :                 while (log_process() == true) {
     449                 :            :                 }
     450                 :            :         }
     451                 :            : 
     452                 :          1 : out:
     453                 :          1 :         panic_mode = true;
     454                 :            : }
     455                 :            : 
     456                 :            : #ifdef CONFIG_USERSPACE
     457                 :            : void z_vrfy_log_panic(void)
     458                 :            : {
     459                 :            :         z_impl_log_panic();
     460                 :            : }
     461                 :            : #include <zephyr/syscalls/log_panic_mrsh.c>
     462                 :            : #endif
     463                 :            : 
     464                 :        177 : static bool msg_filter_check(struct log_backend const *backend,
     465                 :            :                              union log_msg_generic *msg)
     466                 :            : {
     467                 :        177 :         if (!z_log_item_is_msg(msg)) {
     468                 :            :                 return true;
     469                 :            :         }
     470                 :            : 
     471                 :        177 :         if (!IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) {
     472                 :        177 :                 return true;
     473                 :            :         }
     474                 :            : 
     475                 :            :         uint32_t backend_level;
     476                 :            :         uint8_t level;
     477                 :            :         uint8_t domain_id;
     478                 :            :         int16_t source_id;
     479                 :            : 
     480                 :            :         level = log_msg_get_level(&msg->log);
     481                 :            :         domain_id = log_msg_get_domain(&msg->log);
     482                 :            :         source_id = log_msg_get_source_id(&msg->log);
     483                 :            : 
     484                 :            :         /* Accept all non-logging messages. */
     485                 :            :         if (level == LOG_LEVEL_NONE) {
     486                 :            :                 return true;
     487                 :            :         }
     488                 :            :         if (source_id >= 0) {
     489                 :            :                 backend_level = log_filter_get(backend, domain_id, source_id, true);
     490                 :            : 
     491                 :            :                 return (level <= backend_level);
     492                 :            :         } else {
     493                 :            :                 return true;
     494                 :            :         }
     495                 :            : }
     496                 :            : 
     497                 :        177 : static void msg_process(union log_msg_generic *msg)
     498                 :            : {
     499   [ -  +  +  + ]:        354 :         STRUCT_SECTION_FOREACH(log_backend, backend) {
     500         [ +  - ]:        177 :                 if (log_backend_is_active(backend) &&
     501         [ +  - ]:        177 :                     msg_filter_check(backend, msg)) {
     502                 :        177 :                         log_backend_msg_process(backend, msg);
     503                 :            :                 }
     504                 :            :         }
     505                 :        177 : }
     506                 :            : 
     507                 :          0 : void dropped_notify(void)
     508                 :            : {
     509                 :          0 :         uint32_t dropped = z_log_dropped_read_and_clear();
     510                 :            : 
     511   [ #  #  #  # ]:          0 :         STRUCT_SECTION_FOREACH(log_backend, backend) {
     512         [ #  # ]:          0 :                 if (log_backend_is_active(backend)) {
     513                 :          0 :                         log_backend_dropped(backend, dropped);
     514                 :            :                 }
     515                 :            :         }
     516                 :          0 : }
     517                 :            : 
     518                 :          0 : void unordered_notify(void)
     519                 :            : {
     520                 :          0 :         uint32_t unordered = atomic_set(&unordered_cnt, 0);
     521                 :            : 
     522                 :          0 :         LOG_WRN("%d unordered messages since last report", unordered);
     523                 :          0 : }
     524                 :            : 
     525                 :          1 : void z_log_notify_backend_enabled(void)
     526                 :            : {
     527                 :            :         /* Wakeup logger thread after attaching first backend. It might be
     528                 :            :          * blocked with log messages pending.
     529                 :            :          */
     530                 :          1 :         if (IS_ENABLED(CONFIG_LOG_PROCESS_THREAD) && !backend_attached) {
     531                 :            :                 k_sem_give(&log_process_thread_sem);
     532                 :            :         }
     533                 :            : 
     534                 :          1 :         backend_attached = true;
     535                 :          1 : }
     536                 :            : 
     537                 :            : static inline bool z_log_unordered_pending(void)
     538                 :            : {
     539                 :            :         return IS_ENABLED(CONFIG_LOG_MULTIDOMAIN) && unordered_cnt;
     540                 :            : }
     541                 :            : 
     542                 :         19 : bool z_impl_log_process(void)
     543                 :            : {
     544                 :         19 :         if (!IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
     545                 :         19 :                 return false;
     546                 :            :         }
     547                 :            : 
     548                 :            :         k_timeout_t backoff = K_NO_WAIT;
     549                 :            :         union log_msg_generic *msg;
     550                 :            : 
     551                 :            :         if (!backend_attached) {
     552                 :            :                 return false;
     553                 :            :         }
     554                 :            : 
     555                 :            :         msg = z_log_msg_claim(&backoff);
     556                 :            : 
     557                 :            :         if (msg) {
     558                 :            :                 atomic_dec(&buffered_cnt);
     559                 :            :                 msg_process(msg);
     560                 :            :                 z_log_msg_free(msg);
     561                 :            :         } else if (CONFIG_LOG_PROCESSING_LATENCY_US > 0 && !K_TIMEOUT_EQ(backoff, K_NO_WAIT)) {
     562                 :            :                 /* If backoff is requested, it means that there are pending
     563                 :            :                  * messages but they are too new and processing shall back off
     564                 :            :                  * to allow arrival of newer messages from remote domains.
     565                 :            :                  */
     566                 :            :                 k_timer_start(&log_process_thread_timer, backoff, K_NO_WAIT);
     567                 :            : 
     568                 :            :                 return false;
     569                 :            :         }
     570                 :            : 
     571                 :            :         if (IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
     572                 :            :                 bool dropped_pend = z_log_dropped_pending();
     573                 :            :                 bool unordered_pend = z_log_unordered_pending();
     574                 :            : 
     575                 :            :                 if ((dropped_pend || unordered_pend) &&
     576                 :            :                    (k_uptime_get() - last_failure_report) > CONFIG_LOG_FAILURE_REPORT_PERIOD) {
     577                 :            :                         if (dropped_pend) {
     578                 :            :                                 dropped_notify();
     579                 :            :                         }
     580                 :            : 
     581                 :            :                         if (unordered_pend) {
     582                 :            :                                 unordered_notify();
     583                 :            :                         }
     584                 :            :                 }
     585                 :            : 
     586                 :            :                 last_failure_report += CONFIG_LOG_FAILURE_REPORT_PERIOD;
     587                 :            :         }
     588                 :            : 
     589                 :            :         return z_log_msg_pending();
     590                 :            : }
     591                 :            : 
     592                 :            : #ifdef CONFIG_USERSPACE
     593                 :            : bool z_vrfy_log_process(void)
     594                 :            : {
     595                 :            :         return z_impl_log_process();
     596                 :            : }
     597                 :            : #include <zephyr/syscalls/log_process_mrsh.c>
     598                 :            : #endif
     599                 :            : 
     600                 :          0 : uint32_t z_impl_log_buffered_cnt(void)
     601                 :            : {
     602                 :          0 :         return buffered_cnt;
     603                 :            : }
     604                 :            : 
     605                 :            : #ifdef CONFIG_USERSPACE
     606                 :            : uint32_t z_vrfy_log_buffered_cnt(void)
     607                 :            : {
     608                 :            :         return z_impl_log_buffered_cnt();
     609                 :            : }
     610                 :            : #include <zephyr/syscalls/log_buffered_cnt_mrsh.c>
     611                 :            : #endif
     612                 :            : 
     613                 :          0 : void z_log_dropped(bool buffered)
     614                 :            : {
     615                 :          0 :         atomic_inc(&dropped_cnt);
     616         [ #  # ]:          0 :         if (buffered) {
     617                 :          0 :                 atomic_dec(&buffered_cnt);
     618                 :            :         }
     619                 :            : 
     620                 :          0 :         if (IS_ENABLED(CONFIG_LOG_PROCESS_THREAD)) {
     621                 :            :                 k_timer_stop(&log_process_thread_timer);
     622                 :            :                 k_sem_give(&log_process_thread_sem);
     623                 :            :         }
     624                 :          0 : }
     625                 :            : 
     626                 :          0 : uint32_t z_log_dropped_read_and_clear(void)
     627                 :            : {
     628                 :          0 :         return atomic_set(&dropped_cnt, 0);
     629                 :            : }
     630                 :            : 
     631                 :          0 : bool z_log_dropped_pending(void)
     632                 :            : {
     633                 :          0 :         return dropped_cnt > 0;
     634                 :            : }
     635                 :            : 
     636                 :          0 : void z_log_msg_init(void)
     637                 :            : {
     638                 :            : #ifdef CONFIG_MPSC_PBUF
     639                 :            :         mpsc_pbuf_init(&log_buffer, &mpsc_config);
     640                 :            :         curr_log_buffer = &log_buffer;
     641                 :            : #endif
     642                 :          0 : }
     643                 :            : 
     644                 :          0 : static struct log_msg *msg_alloc(struct mpsc_pbuf_buffer *buffer, uint32_t wlen)
     645                 :            : {
     646                 :          0 :         if (!IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
     647                 :          0 :                 return NULL;
     648                 :            :         }
     649                 :            : 
     650                 :            :         return (struct log_msg *)mpsc_pbuf_alloc(
     651                 :            :                 buffer, wlen,
     652                 :            :                 (CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS == -1)
     653                 :            :                         ? K_FOREVER
     654                 :            :                         : K_MSEC(CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS));
     655                 :            : }
     656                 :            : 
     657                 :          0 : struct log_msg *z_log_msg_alloc(uint32_t wlen)
     658                 :            : {
     659                 :          0 :         return msg_alloc(&log_buffer, wlen);
     660                 :            : }
     661                 :            : 
     662                 :        177 : static void msg_commit(struct mpsc_pbuf_buffer *buffer, struct log_msg *msg)
     663                 :            : {
     664                 :        177 :         union log_msg_generic *m = (union log_msg_generic *)msg;
     665                 :            : 
     666                 :        177 :         if (IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) {
     667                 :        177 :                 msg_process(m);
     668                 :            : 
     669                 :        177 :                 return;
     670                 :            :         }
     671                 :            : 
     672                 :            : #ifdef CONFIG_MPSC_PBUF
     673                 :            :         mpsc_pbuf_commit(buffer, &m->buf);
     674                 :            : #endif
     675                 :            :         z_log_msg_post_finalize();
     676                 :            : }
     677                 :            : 
     678                 :        177 : void z_log_msg_commit(struct log_msg *msg)
     679                 :            : {
     680                 :        177 :         msg->hdr.timestamp = timestamp_func();
     681                 :        177 :         msg_commit(&log_buffer, msg);
     682                 :        177 : }
     683                 :            : 
     684                 :          0 : union log_msg_generic *z_log_msg_local_claim(void)
     685                 :            : {
     686                 :            : #ifdef CONFIG_MPSC_PBUF
     687                 :            :         return (union log_msg_generic *)mpsc_pbuf_claim(&log_buffer);
     688                 :            : #else
     689                 :          0 :         return NULL;
     690                 :            : #endif
     691                 :            : 
     692                 :            : }
     693                 :            : 
     694                 :            : /* If there are buffers dedicated for each link, claim the oldest message (lowest timestamp). */
     695                 :          0 : union log_msg_generic *z_log_msg_claim_oldest(k_timeout_t *backoff)
     696                 :            : {
     697                 :          0 :         union log_msg_generic *msg = NULL;
     698                 :          0 :         struct log_msg_ptr *chosen;
     699                 :          0 :         log_timestamp_t t_min = sizeof(log_timestamp_t) > sizeof(uint32_t) ?
     700                 :            :                                 UINT64_MAX : UINT32_MAX;
     701                 :          0 :         int i = 0;
     702                 :            : 
     703                 :            :         /* Else iterate on all available buffers and get the oldest message. */
     704   [ #  #  #  # ]:          0 :         STRUCT_SECTION_FOREACH(log_msg_ptr, msg_ptr) {
     705                 :          0 :                 struct log_mpsc_pbuf *buf;
     706                 :            : 
     707                 :          0 :                 STRUCT_SECTION_GET(log_mpsc_pbuf, i, &buf);
     708                 :            : 
     709                 :            : #ifdef CONFIG_MPSC_PBUF
     710                 :            :                 if (msg_ptr->msg == NULL) {
     711                 :            :                         msg_ptr->msg = (union log_msg_generic *)mpsc_pbuf_claim(&buf->buf);
     712                 :            :                 }
     713                 :            : #endif
     714                 :            : 
     715         [ #  # ]:          0 :                 if (msg_ptr->msg) {
     716                 :          0 :                         log_timestamp_t t = log_msg_get_timestamp(&msg_ptr->msg->log);
     717                 :            : 
     718         [ #  # ]:          0 :                         if (t < t_min) {
     719                 :          0 :                                 t_min = t;
     720                 :          0 :                                 msg = msg_ptr->msg;
     721                 :          0 :                                 chosen = msg_ptr;
     722                 :          0 :                                 curr_log_buffer = &buf->buf;
     723                 :            :                         }
     724                 :            :                 }
     725                 :          0 :                 i++;
     726                 :            :         }
     727                 :            : 
     728         [ #  # ]:          0 :         if (msg) {
     729                 :          0 :                 if (CONFIG_LOG_PROCESSING_LATENCY_US > 0) {
     730                 :            :                         int32_t diff = t_min - (timestamp_func() - proc_latency);
     731                 :            : 
     732                 :            :                         if (diff > 0) {
     733                 :            :                                /* Entry is too new. Back off for sometime to allow new
     734                 :            :                                 * remote messages to arrive which may have been captured
     735                 :            :                                 * earlier (but on other platform). Calculate for how
     736                 :            :                                 * long processing shall back off.
     737                 :            :                                 */
     738                 :            :                                 if (timestamp_freq == sys_clock_hw_cycles_per_sec()) {
     739                 :            :                                         *backoff = K_TICKS(diff);
     740                 :            :                                 } else {
     741                 :            :                                         *backoff = K_TICKS((diff * sys_clock_hw_cycles_per_sec()) /
     742                 :            :                                                         timestamp_freq);
     743                 :            :                                 }
     744                 :            : 
     745                 :            :                                 return NULL;
     746                 :            :                         }
     747                 :            :                 }
     748                 :            : 
     749                 :          0 :                 (*chosen).msg = NULL;
     750                 :            :         }
     751                 :            : 
     752         [ #  # ]:          0 :         if (t_min < prev_timestamp) {
     753                 :          0 :                 atomic_inc(&unordered_cnt);
     754                 :            :         }
     755                 :            : 
     756                 :          0 :         prev_timestamp = t_min;
     757                 :            : 
     758                 :          0 :         return msg;
     759                 :            : }
     760                 :            : 
     761                 :          0 : union log_msg_generic *z_log_msg_claim(k_timeout_t *backoff)
     762                 :            : {
     763                 :          0 :         size_t len;
     764                 :            : 
     765                 :          0 :         STRUCT_SECTION_COUNT(log_mpsc_pbuf, &len);
     766                 :            : 
     767                 :            :         /* Use only one buffer if others are not registered. */
     768                 :          0 :         if (IS_ENABLED(CONFIG_LOG_MULTIDOMAIN) && len > 1) {
     769                 :            :                 return z_log_msg_claim_oldest(backoff);
     770                 :            :         }
     771                 :            : 
     772                 :          0 :         return z_log_msg_local_claim();
     773                 :            : }
     774                 :            : 
     775                 :            : static void msg_free(struct mpsc_pbuf_buffer *buffer, const union log_msg_generic *msg)
     776                 :            : {
     777                 :            : #ifdef CONFIG_MPSC_PBUF
     778                 :            :         mpsc_pbuf_free(buffer, &msg->buf);
     779                 :            : #endif
     780                 :            : }
     781                 :            : 
     782                 :          0 : void z_log_msg_free(union log_msg_generic *msg)
     783                 :            : {
     784                 :          0 :         msg_free(curr_log_buffer, msg);
     785                 :          0 : }
     786                 :            : 
     787                 :          0 : static bool msg_pending(struct mpsc_pbuf_buffer *buffer)
     788                 :            : {
     789                 :            : #ifdef CONFIG_MPSC_PBUF
     790                 :            :         return mpsc_pbuf_is_pending(buffer);
     791                 :            : #else
     792                 :          0 :         return false;
     793                 :            : #endif
     794                 :            : }
     795                 :            : 
     796                 :          0 : bool z_log_msg_pending(void)
     797                 :            : {
     798                 :          0 :         size_t len;
     799                 :          0 :         int i = 0;
     800                 :            : 
     801                 :          0 :         STRUCT_SECTION_COUNT(log_mpsc_pbuf, &len);
     802                 :            : 
     803                 :          0 :         if (!IS_ENABLED(CONFIG_LOG_MULTIDOMAIN) || (len == 1)) {
     804                 :          0 :                 return msg_pending(&log_buffer);
     805                 :            :         }
     806                 :            : 
     807                 :            :         STRUCT_SECTION_FOREACH(log_msg_ptr, msg_ptr) {
     808                 :            :                 struct log_mpsc_pbuf *buf;
     809                 :            : 
     810                 :            :                 if (msg_ptr->msg) {
     811                 :            :                         return true;
     812                 :            :                 }
     813                 :            : 
     814                 :            :                 STRUCT_SECTION_GET(log_mpsc_pbuf, i, &buf);
     815                 :            : 
     816                 :            :                 if (msg_pending(&buf->buf)) {
     817                 :            :                         return true;
     818                 :            :                 }
     819                 :            : 
     820                 :            :                 i++;
     821                 :            :         }
     822                 :            : 
     823                 :            :         return false;
     824                 :            : }
     825                 :            : 
     826                 :          0 : void z_log_msg_enqueue(const struct log_link *link, const void *data, size_t len)
     827                 :            : {
     828                 :          0 :         struct log_msg *log_msg = (struct log_msg *)data;
     829                 :          0 :         size_t wlen = DIV_ROUND_UP(ROUND_UP(len, Z_LOG_MSG_ALIGNMENT), sizeof(int));
     830         [ #  # ]:          0 :         struct mpsc_pbuf_buffer *mpsc_pbuffer = link->mpsc_pbuf ? link->mpsc_pbuf : &log_buffer;
     831                 :          0 :         struct log_msg *local_msg = msg_alloc(mpsc_pbuffer, wlen);
     832                 :            : 
     833         [ #  # ]:          0 :         if (!local_msg) {
     834                 :          0 :                 z_log_dropped(false);
     835                 :          0 :                 return;
     836                 :            :         }
     837                 :            : 
     838                 :          0 :         log_msg->hdr.desc.valid = 0;
     839                 :          0 :         log_msg->hdr.desc.busy = 0;
     840                 :          0 :         log_msg->hdr.desc.domain += link->ctrl_blk->domain_offset;
     841                 :          0 :         memcpy((void *)local_msg, data, len);
     842                 :          0 :         msg_commit(mpsc_pbuffer, local_msg);
     843                 :            : }
     844                 :            : 
     845                 :          0 : const char *z_log_get_tag(void)
     846                 :            : {
     847                 :          0 :         return CONFIG_LOG_TAG_MAX_LEN > 0 ? tag : NULL;
     848                 :            : }
     849                 :            : 
     850                 :          0 : int log_set_tag(const char *str)
     851                 :            : {
     852                 :            : #if CONFIG_LOG_TAG_MAX_LEN > 0
     853                 :            :         if (str == NULL) {
     854                 :            :                 return -EINVAL;
     855                 :            :         }
     856                 :            : 
     857                 :            :         size_t len = strlen(str);
     858                 :            :         size_t cpy_len = MIN(len, CONFIG_LOG_TAG_MAX_LEN);
     859                 :            : 
     860                 :            :         memcpy(tag, str, cpy_len);
     861                 :            :         tag[cpy_len] = '\0';
     862                 :            : 
     863                 :            :         if (cpy_len < len) {
     864                 :            :                 tag[cpy_len - 1] = '~';
     865                 :            :                 return -ENOMEM;
     866                 :            :         }
     867                 :            : 
     868                 :            :         return 0;
     869                 :            : #else
     870                 :          0 :         return -ENOTSUP;
     871                 :            : #endif
     872                 :            : }
     873                 :            : 
     874                 :          0 : int log_mem_get_usage(uint32_t *buf_size, uint32_t *usage)
     875                 :            : {
     876         [ #  # ]:          0 :         __ASSERT_NO_MSG(buf_size != NULL);
     877         [ #  # ]:          0 :         __ASSERT_NO_MSG(usage != NULL);
     878                 :            : 
     879                 :          0 :         if (!IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
     880                 :          0 :                 return -EINVAL;
     881                 :            :         }
     882                 :            : 
     883                 :            :         mpsc_pbuf_get_utilization(&log_buffer, buf_size, usage);
     884                 :            : 
     885                 :            :         return 0;
     886                 :            : }
     887                 :            : 
     888                 :          0 : int log_mem_get_max_usage(uint32_t *max)
     889                 :            : {
     890         [ #  # ]:          0 :         __ASSERT_NO_MSG(max != NULL);
     891                 :            : 
     892                 :          0 :         if (!IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
     893                 :          0 :                 return -EINVAL;
     894                 :            :         }
     895                 :            : 
     896                 :            :         return mpsc_pbuf_get_max_utilization(&log_buffer, max);
     897                 :            : }
     898                 :            : 
     899                 :            : static void log_backend_notify_all(enum log_backend_evt event,
     900                 :            :                                    union log_backend_evt_arg *arg)
     901                 :            : {
     902                 :            :         STRUCT_SECTION_FOREACH(log_backend, backend) {
     903                 :            :                 log_backend_notify(backend, event, arg);
     904                 :            :         }
     905                 :            : }
     906                 :            : 
     907                 :            : static void log_process_thread_timer_expiry_fn(struct k_timer *timer)
     908                 :            : {
     909                 :            :         k_sem_give(&log_process_thread_sem);
     910                 :            : }
     911                 :            : 
     912                 :            : static void log_process_thread_func(void *dummy1, void *dummy2, void *dummy3)
     913                 :            : {
     914                 :            :         __ASSERT_NO_MSG(log_backend_count_get() > 0);
     915                 :            :         uint32_t links_active_mask = 0xFFFFFFFF;
     916                 :            :         uint8_t domain_offset = 0;
     917                 :            :         uint32_t activate_mask = z_log_init(false, false);
     918                 :            :         /* If some backends are not activated yet set periodical thread wake up
     919                 :            :          * to poll backends for readiness. Period is set arbitrary.
     920                 :            :          * If all backends are ready periodic wake up is not needed.
     921                 :            :          */
     922                 :            :         k_timeout_t timeout = (activate_mask != 0) ? K_MSEC(50) : K_FOREVER;
     923                 :            :         bool processed_any = false;
     924                 :            :         thread_set(k_current_get());
     925                 :            : 
     926                 :            :         /* Logging thread is periodically waken up until all backends that
     927                 :            :          * should be autostarted are ready.
     928                 :            :          */
     929                 :            :         while (true) {
     930                 :            :                 if (activate_mask) {
     931                 :            :                         activate_mask = activate_foreach_backend(activate_mask);
     932                 :            :                         if (!activate_mask) {
     933                 :            :                                 /* Periodic wake up no longer needed since all
     934                 :            :                                  * backends are ready.
     935                 :            :                                  */
     936                 :            :                                 timeout = K_FOREVER;
     937                 :            :                         }
     938                 :            :                 }
     939                 :            : 
     940                 :            :                 /* Keep trying to activate links until all links are active. */
     941                 :            :                 if (IS_ENABLED(CONFIG_LOG_MULTIDOMAIN) && links_active_mask) {
     942                 :            :                         links_active_mask =
     943                 :            :                                 z_log_links_activate(links_active_mask, &domain_offset);
     944                 :            :                 }
     945                 :            : 
     946                 :            : 
     947                 :            :                 if (log_process() == false) {
     948                 :            :                         if (processed_any) {
     949                 :            :                                 processed_any = false;
     950                 :            :                                 log_backend_notify_all(LOG_BACKEND_EVT_PROCESS_THREAD_DONE, NULL);
     951                 :            :                         }
     952                 :            :                         (void)k_sem_take(&log_process_thread_sem, timeout);
     953                 :            :                 } else {
     954                 :            :                         processed_any = true;
     955                 :            :                 }
     956                 :            :         }
     957                 :            : }
     958                 :            : 
     959                 :            : K_KERNEL_STACK_DEFINE(logging_stack, CONFIG_LOG_PROCESS_THREAD_STACK_SIZE);
     960                 :            : struct k_thread logging_thread;
     961                 :            : 
     962                 :          1 : static int enable_logger(void)
     963                 :            : {
     964                 :          1 :         if (IS_ENABLED(CONFIG_LOG_PROCESS_THREAD)) {
     965                 :            :                 k_timer_init(&log_process_thread_timer,
     966                 :            :                                 log_process_thread_timer_expiry_fn, NULL);
     967                 :            :                 /* start logging thread */
     968                 :            :                 k_thread_create(&logging_thread, logging_stack,
     969                 :            :                                 K_KERNEL_STACK_SIZEOF(logging_stack),
     970                 :            :                                 log_process_thread_func, NULL, NULL, NULL,
     971                 :            :                                 LOG_PROCESS_THREAD_PRIORITY, 0,
     972                 :            :                                 COND_CODE_1(CONFIG_LOG_PROCESS_THREAD,
     973                 :            :                                         K_MSEC(CONFIG_LOG_PROCESS_THREAD_STARTUP_DELAY_MS),
     974                 :            :                                         K_NO_WAIT));
     975                 :            :                 k_thread_name_set(&logging_thread, "logging");
     976                 :            :         } else {
     977                 :          1 :                 (void)z_log_init(false, false);
     978                 :            :         }
     979                 :            : 
     980                 :          1 :         return 0;
     981                 :            : }
     982                 :            : 
     983                 :            : SYS_INIT(enable_logger, POST_KERNEL, CONFIG_LOG_CORE_INIT_PRIORITY);

Generated by: LCOV version 1.14