/* * Copyright (c) 2020 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include "footprint.h" static struct k_work_q workq; static K_THREAD_STACK_DEFINE(workq_stack, STACK_SIZE); struct k_sem sync_sema; #if CONFIG_USERSPACE static struct k_work_user_q user_workq; static K_THREAD_STACK_DEFINE(user_workq_stack, STACK_SIZE); static FP_BMEM struct k_work_user user_work_item; void user_workq_func(struct k_work_user *unused) { ARG_UNUSED(unused); k_sem_give(&sync_sema); } #endif void workq_func(struct k_work *unused) { ARG_UNUSED(unused); k_sem_give(&sync_sema); } void simple_workq_thread(void *arg1, void *arg2, void *arg3) { struct k_work work_item; ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); k_sem_reset(&sync_sema); k_work_init(&work_item, workq_func); k_work_submit_to_queue(&workq, &work_item); k_sem_take(&sync_sema, K_FOREVER); } void delayed_workq_thread(void *arg1, void *arg2, void *arg3) { struct k_work_delayable work_item; ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); k_sem_reset(&sync_sema); k_work_init_delayable(&work_item, workq_func); k_work_reschedule_for_queue(&workq, &work_item, K_NO_WAIT); k_sem_take(&sync_sema, K_FOREVER); } #if CONFIG_USERSPACE void simple_user_workq_thread(void *arg1, void *arg2, void *arg3) { ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); k_sem_reset(&sync_sema); k_work_user_init(&user_work_item, user_workq_func); k_work_user_submit_to_queue(&user_workq, &user_work_item); k_sem_take(&sync_sema, K_FOREVER); } #endif void run_workq(void) { k_tid_t tid; k_sem_init(&sync_sema, 0, 1); k_work_queue_start(&workq, workq_stack, K_THREAD_STACK_SIZEOF(workq_stack), CONFIG_MAIN_THREAD_PRIORITY, NULL); /* Exercise simple workqueue */ tid = k_thread_create(&my_thread, my_stack_area, STACK_SIZE, simple_workq_thread, NULL, NULL, NULL, 0, 0, K_NO_WAIT); k_thread_join(tid, K_FOREVER); /* Exercise delayed workqueue */ tid = k_thread_create(&my_thread, my_stack_area, STACK_SIZE, delayed_workq_thread, NULL, NULL, NULL, 0, 0, K_NO_WAIT); k_thread_join(tid, K_FOREVER); #if CONFIG_USERSPACE k_work_user_queue_start(&user_workq, user_workq_stack, K_THREAD_STACK_SIZEOF(user_workq_stack), CONFIG_MAIN_THREAD_PRIORITY, NULL); /* The work queue thread has been started, but it's OK because * it doesn't need these permissions until something's submitted * to it. */ k_mem_domain_add_thread(&footprint_mem_domain, &user_workq.thread); k_thread_access_grant(&user_workq.thread, &sync_sema); tid = k_thread_create(&my_thread, my_stack_area, STACK_SIZE, simple_user_workq_thread, NULL, NULL, NULL, 0, K_USER, K_FOREVER); k_thread_access_grant(tid, &sync_sema, &user_workq.thread, &user_workq.queue, &user_workq_stack); k_mem_domain_add_thread(&footprint_mem_domain, tid); k_thread_start(tid); k_thread_join(tid, K_FOREVER); #endif }