void test_priority_preemptible(void) { int old_prio = k_thread_priority_get(k_current_get()); /* set current thread to a non-negative priority */ last_prio = 2; k_thread_priority_set(k_current_get(), last_prio); int spawn_prio = last_prio - 1; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry, NULL, NULL, NULL, spawn_prio, 0, 0); /* checkpoint: thread is preempted by higher thread */ zassert_true(last_prio == spawn_prio, NULL); k_sleep(100); k_thread_abort(tid); spawn_prio = last_prio + 1; tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry, NULL, NULL, NULL, spawn_prio, 0, 0); /* checkpoint: thread is not preempted by lower thread */ zassert_false(last_prio == spawn_prio, NULL); k_thread_abort(tid); /* restore environment */ k_thread_priority_set(k_current_get(), old_prio); }
static void threads_suspend_resume(int prio) { int old_prio = k_thread_priority_get(k_current_get()); /* set current thread */ last_prio = prio; k_thread_priority_set(k_current_get(), last_prio); /* spawn thread with lower priority */ int spawn_prio = last_prio + 1; k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, thread_entry, NULL, NULL, NULL, spawn_prio, 0, 0); /* checkpoint: suspend current thread */ k_thread_suspend(tid); k_sleep(100); /* checkpoint: spawned thread shouldn't be executed after suspend */ assert_false(last_prio == spawn_prio, NULL); k_thread_resume(tid); k_sleep(100); /* checkpoint: spawned thread should be executed after resume */ assert_true(last_prio == spawn_prio, NULL); k_thread_abort(tid); /* restore environment */ k_thread_priority_set(k_current_get(), old_prio); }
/** * * @brief Fatal error handler * * This routine implements the corrective action to be taken when the system * detects a fatal error. * * This sample implementation attempts to abort the current thread and allow * the system to continue executing, which may permit the system to continue * functioning with degraded capabilities. * * System designers may wish to enhance or substitute this sample * implementation to take other actions, such as logging error (or debug) * information to a persistent repository and/or rebooting the system. * * @param reason fatal error reason * @param pEsf pointer to exception stack frame * * @return This function does not return. */ void __weak z_SysFatalErrorHandler(unsigned int reason, const NANO_ESF *pEsf) { ARG_UNUSED(pEsf); #if !defined(CONFIG_SIMPLE_FATAL_ERROR_HANDLER) #ifdef CONFIG_STACK_SENTINEL if (reason == _NANO_ERR_STACK_CHK_FAIL) { goto hang_system; } #endif if (reason == _NANO_ERR_KERNEL_PANIC) { goto hang_system; } if (k_is_in_isr() || z_is_thread_essential()) { printk("Fatal fault in %s! Spinning...\n", k_is_in_isr() ? "ISR" : "essential thread"); goto hang_system; } printk("Fatal fault in thread %p! Aborting.\n", _current); k_thread_abort(_current); return; hang_system: #else ARG_UNUSED(reason); #endif for (;;) { k_cpu_idle(); } CODE_UNREACHABLE; }
/*test cases*/ void test_msgq_purge_when_put(void) { struct k_msgq msgq; int ret; k_msgq_init(&msgq, tbuffer, MSG_SIZE, MSGQ_LEN); /*fill the queue to full*/ for (int i = 0; i < MSGQ_LEN; i++) { ret = k_msgq_put(&msgq, (void *)&data[i], K_NO_WAIT); zassert_equal(ret, 0, NULL); } /*create another thread waiting to put msg*/ k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, tThread_entry, &msgq, NULL, NULL, K_PRIO_PREEMPT(0), 0, 0); k_sleep(TIMEOUT >> 1); /**TESTPOINT: msgq purge while another thread waiting to put msg*/ k_msgq_purge(&msgq); k_sleep(TIMEOUT >> 1); k_thread_abort(tid); /*verify msg put after purge*/ for (int i = 0; i < MSGQ_LEN; i++) { ret = k_msgq_put(&msgq, (void *)&data[i], K_NO_WAIT); zassert_equal(ret, 0, NULL); } }
/* * Common thread entry point function (used by all threads) * * This routine invokes the actual thread entry point function and passes * it three arguments. It also handles graceful termination of the thread * if the entry point function ever returns. * * This routine does not return, and is marked as such so the compiler won't * generate preamble code that is only used by functions that actually return. */ FUNC_NORETURN void _thread_entry(void (*entry)(void *, void *, void *), void *p1, void *p2, void *p3) { entry(p1, p2, p3); #ifdef CONFIG_MULTITHREADING if (_is_thread_essential()) { _NanoFatalErrorHandler(_NANO_ERR_INVALID_TASK_EXIT, &_default_esf); } k_thread_abort(_current); #else for (;;) { k_cpu_idle(); } #endif /* * Compiler can't tell that k_thread_abort() won't return and issues a * warning unless we tell it that control never gets this far. */ CODE_UNREACHABLE; }
void thread_sem0_test(void *p1, void *p2, void *p3) { k_sem_take(&sem_bench, 10);/* To sync threads */ k_sem_give(&sem_bench); sem_count++; k_thread_abort(sem0_tid); }
static void thread_entry_abort(void *p1, void *p2, void *p3) { /**TESTPOINT: abort current thread*/ execute_flag = 1; k_thread_abort(k_current_get()); /*unreachable*/ execute_flag = 2; zassert_true(1 == 0, NULL); }
static void tsema_thread_thread(struct k_sem *psem) { /**TESTPOINT: thread-thread sync via sema*/ k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, tThread_entry, psem, NULL, NULL, K_PRIO_PREEMPT(0), 0, 0); zassert_false(k_sem_take(psem, K_FOREVER), NULL); /*clean the spawn thread avoid side effect in next TC*/ k_thread_abort(tid); }
void test_threads_abort_self(void) { execute_flag = 0; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_abort, NULL, NULL, NULL, 0, 0, 0); k_sleep(100); /**TESTPOINT: spawned thread executed but abort itself*/ zassert_true(execute_flag == 1, NULL); k_thread_abort(tid); }
static void thread_alert(void) { handler_executed = 0; /**TESTPOINT: thread-thread sync via alert*/ k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, tThread_entry, NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, 0); alert_send(); k_sleep(TIMEOUT); k_thread_abort(tid); }
/*test cases*/ void test_sched_is_preempt_thread(void) { k_sem_init(&end_sema, 0, 1); /*create preempt thread*/ k_tid_t tid = k_thread_spawn(tstack, STACK_SIZE, tpreempt_ctx, NULL, NULL, NULL, K_PRIO_PREEMPT(1), 0, 0); k_sem_take(&end_sema, K_FOREVER); k_thread_abort(tid); /*create coop thread*/ tid = k_thread_spawn(tstack, STACK_SIZE, tcoop_ctx, NULL, NULL, NULL, K_PRIO_COOP(1), 0, 0); k_sem_take(&end_sema, K_FOREVER); k_thread_abort(tid); /*invoke isr*/ irq_offload(tIsr, NULL); }
void test_pipe_get_put(void) { /**TESTPOINT: test API sequence: [get, put]*/ k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, tThread_block_put, &kpipe, NULL, NULL, K_PRIO_PREEMPT(0), 0, 0); /*get will be executed previor to put*/ tpipe_get(&kpipe); k_sem_take(&end_sema, K_FOREVER); k_thread_abort(tid); }
void test_threads_abort_others(void) { execute_flag = 0; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry, NULL, NULL, NULL, 0, 0, 0); k_thread_abort(tid); k_sleep(100); /**TESTPOINT: check not-started thread is aborted*/ zassert_true(execute_flag == 0, NULL); tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry, NULL, NULL, NULL, 0, 0, 0); k_sleep(50); k_thread_abort(tid); /**TESTPOINT: check running thread is aborted*/ zassert_true(execute_flag == 1, NULL); k_sleep(1000); zassert_true(execute_flag == 1, NULL); }
void test_pipe_block_put(void) { /**TESTPOINT: test k_pipe_block_put without semaphore*/ k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, tThread_block_put, &kpipe, NULL, NULL, K_PRIO_PREEMPT(0), 0, 0); k_sleep(10); tpipe_get(&kpipe); k_sem_take(&end_sema, K_FOREVER); k_thread_abort(tid); }
void test_pipe_block_put_sema(void) { struct k_sem sync_sema; k_sem_init(&sync_sema, 0, 1); /**TESTPOINT: test k_pipe_block_put with semaphore*/ k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, tThread_block_put, &pipe, &sync_sema, NULL, K_PRIO_PREEMPT(0), 0, 0); k_sleep(10); tpipe_get(&pipe); k_sem_take(&end_sema, K_FOREVER); k_thread_abort(tid); }
static void tmutex_test_lock(struct k_mutex *pmutex, void (*entry_fn)(void *, void *, void *)) { k_mutex_init(pmutex); k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, entry_fn, pmutex, NULL, NULL, K_PRIO_PREEMPT(0), 0, 0); k_mutex_lock(pmutex, K_FOREVER); TC_PRINT("access resource from main thread\n"); /* wait for spawn thread to take action */ k_sleep(TIMEOUT); /* teardown */ k_thread_abort(tid); }
static void tstack_thread_thread(struct k_stack *pstack) { k_sem_init(&end_sema, 0, 1); /**TESTPOINT: thread-thread data passing via stack*/ k_tid_t tid = k_thread_spawn(threadstack, STACK_SIZE, tThread_entry, pstack, NULL, NULL, K_PRIO_PREEMPT(0), 0, 0); tstack_push(pstack); k_sem_take(&end_sema, K_FOREVER); k_sem_take(&end_sema, K_FOREVER); tstack_pop(pstack); /* clear the spawn thread to avoid side effect */ k_thread_abort(tid); }
static void tpipe_thread_thread(struct k_pipe *ppipe) { k_sem_init(&end_sema, 0, 1); /**TESTPOINT: thread-thread data passing via pipe*/ k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, tThread_entry, ppipe, NULL, NULL, K_PRIO_PREEMPT(0), 0, 0); tpipe_put(ppipe); k_sem_take(&end_sema, K_FOREVER); k_sem_take(&end_sema, K_FOREVER); tpipe_get(ppipe); /* clear the spawned thread avoid side effect */ k_thread_abort(tid); }
/*test cases*/ void test_threads_cancel_undelayed(void) { int cur_prio = k_thread_priority_get(k_current_get()); /* spawn thread with lower priority */ int spawn_prio = cur_prio + 1; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry, NULL, NULL, NULL, spawn_prio, 0, 0); /**TESTPOINT: check cancel retcode when thread is not delayed*/ int cancel_ret = k_thread_cancel(tid); zassert_equal(cancel_ret, -EINVAL, NULL); k_thread_abort(tid); }
static void https_shutdown(struct http_client_ctx *ctx) { if (!ctx->https.tid) { return; } /* Empty the fifo just in case there is any received packets * still there. */ while (1) { struct rx_fifo_block *rx_data; rx_data = k_fifo_get(&ctx->https.mbedtls.ssl_ctx.rx_fifo, K_NO_WAIT); if (!rx_data) { break; } net_pkt_unref(rx_data->pkt); k_mem_pool_free(&rx_data->block); } k_fifo_cancel_wait(&ctx->https.mbedtls.ssl_ctx.rx_fifo); /* Let the ssl_rx() run if there is anything there waiting */ k_yield(); mbedtls_ssl_close_notify(&ctx->https.mbedtls.ssl); mbedtls_ssl_free(&ctx->https.mbedtls.ssl); mbedtls_ssl_config_free(&ctx->https.mbedtls.conf); mbedtls_ctr_drbg_free(&ctx->https.mbedtls.ctr_drbg); mbedtls_entropy_free(&ctx->https.mbedtls.entropy); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_free(&ctx->https.mbedtls.ca_cert); #endif tcp_disconnect(ctx); NET_DBG("HTTPS thread %p stopped for %p", ctx->https.tid, ctx); k_thread_abort(ctx->https.tid); ctx->https.tid = 0; }
/* test cases*/ void test_mslab_threadsafe(void) { k_tid_t tid[THREAD_NUM]; k_mem_slab_init(&mslab2, tslab, BLK_SIZE2, BLK_NUM); k_sem_init(&sync_sema, 0, THREAD_NUM); /* create multiple threads to invoke same memory slab APIs*/ for (int i = 0; i < THREAD_NUM; i++) { tid[i] = k_thread_create(&tdata[i], tstack[i], STACK_SIZE, tmslab_api, NULL, NULL, NULL, K_PRIO_PREEMPT(1), 0, 0); } /* TESTPOINT: all threads complete and exit the entry function*/ for (int i = 0; i < THREAD_NUM; i++) { k_sem_take(&sync_sema, K_FOREVER); } /* test case tear down*/ for (int i = 0; i < THREAD_NUM; i++) { k_thread_abort(tid[i]); } }
/*test cases*/ void test_priority_cooperative(void) { int old_prio = k_thread_priority_get(k_current_get()); /* set current thread to a negative priority */ last_prio = -1; k_thread_priority_set(k_current_get(), last_prio); /* spawn thread with higher priority */ int spawn_prio = last_prio - 1; k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry, NULL, NULL, NULL, spawn_prio, 0, 0); /* checkpoint: current thread shouldn't preempted by higher thread */ zassert_true(last_prio == k_thread_priority_get(k_current_get()), NULL); k_sleep(100); /* checkpoint: spawned thread get executed */ zassert_true(last_prio == spawn_prio, NULL); k_thread_abort(tid); /* restore environment */ k_thread_priority_set(k_current_get(), old_prio); }