text: /*
   * Copyright (c) 2019 Nordic Semiconductor
   *
   * SPDX-License-Identifier: Apache-2.0
   */
  
  /**
   * @file
   * @brief Test log immediate
   *
   */
  
  
  #include <tc_util.h>
  #include <stdbool.h>
  #include <zephyr/zephyr.h>
  #include <ztest.h>
  #include <zephyr/logging/log_backend.h>
  #include <zephyr/logging/log_ctrl.h>
  #include <zephyr/logging/log.h>
  
  #define LOG_MODULE_NAME test
  LOG_MODULE_REGISTER(LOG_MODULE_NAME);
  
  #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
  
  #define NUM_THREADS 5
  
  K_THREAD_STACK_ARRAY_DEFINE(stacks, NUM_THREADS, STACK_SIZE);
  static struct k_thread threads[NUM_THREADS];
  static k_tid_t tids[NUM_THREADS];
  
  
  /* Thread entry point, used for multiple threads. Thread is logging some data
   * (data length varies for each thread) and sleeps. Threads have different
   * priorities so on wakeup other thread will be preempted, interrupting logging.
   */
  static void thread_func(void *p1, void *p2, void *p3)
  {
  	intptr_t id = (intptr_t)p1;
  	int buf_len = 8*id + 8;
  	uint8_t *buf = alloca(buf_len);
  
  	while (1) {
  		LOG_INF("test string printed %d %d %p", 1, 2, k_current_get());
  		LOG_HEXDUMP_INF(buf, buf_len, "data:");
  		k_msleep(20+id);
  	}
  }
  
  /*
   * Test create number of threads with different priorities. Each thread logs
   * data and sleeps. This creates environment where multiple threads are
   * preempted during logging (in immediate mode). Test checks that system does
   * not hit any assert or other fault during frequent preemptions.
   */
  static void test_log_immediate_preemption(void)
  {
  	if (!IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) {
  		LOG_INF("CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT not enabled."
  			" Text output will be garbled.");
  	}
  	for (intptr_t i = 0; i < NUM_THREADS; i++) {
  		tids[i] = k_thread_create(&threads[i], stacks[i], STACK_SIZE,
  				thread_func, (void *)i, NULL, NULL,
  				k_thread_priority_get(k_current_get()) + i,
  				0, K_MSEC(10));
  	}
  	k_msleep(3000);
  
  	for (int i = 0; i < NUM_THREADS; i++) {
  		k_thread_abort(tids[i]);
  	}
  	zassert_true(true, "");
  }
  
  /*test case main entry*/
  void test_main(void)
  {
  	ztest_test_suite(test_log_immediate,
  			 ztest_unit_test(test_log_immediate_preemption));
  	ztest_run_test_suite(test_log_immediate);
  }
  