14#define SLOT_EMPTY 0x00
19 LOG2_INFO(
"workqueue",
"worker thread running on core %d",
24 if (!__atomic_load_n(&
core->workqueue_count,
26 __asm__
volatile(
"pause");
30 for (
uint16_t i = 0; i < VOXIA_MAX_WORKQUEUE_EACH_CORE; i++) {
50 if (__atomic_load_n(&dep->
in_use,
53 dependency_done =
false;
58 (void)dependency_invalid;
69 "core %d slot %d: function pointer "
76 __atomic_fetch_sub(&
core->workqueue_count, 1,
86 static uint8_t next_core_hint = 1;
88 for (
uint8_t attempt = 0; attempt < VOXIA_MAX_CORE; attempt++) {
90 ((__atomic_fetch_add(&next_core_hint, 1,
92 (VOXIA_MAX_CORE - 1)) +
96 if (!cpu_info || cpu_info->status !=
Active) {
102 if (__atomic_load_n(&
core->workqueue_count, __ATOMIC_ACQUIRE) >=
103 VOXIA_MAX_WORKQUEUE_EACH_CORE) {
110 if (
core->workqueue_count >= VOXIA_MAX_WORKQUEUE_EACH_CORE) {
115 for (
uint16_t i = 0; i < VOXIA_MAX_WORKQUEUE_EACH_CORE; i++) {
118 if (__atomic_compare_exchange_n(
119 &
core->workqueue[i].in_use, &expected,
123 core->workqueue[i].function = (
void*)task;
124 core->workqueue[i].data = arg;
127 __atomic_fetch_add(&
core->workqueue_count, 1,
131 return &
core->workqueue[i];
138 LOG_ERROR(
"workqueue",
"no available slot in any active worker core");
146 if (cpu_info->status !=
Active) {
struct cpu_core * vxGetCpuInfo(uint8_t apicid)
uint8_t vxGetNumberOfCores()
each_core_data * get_current_core_data(void)
each_core_data * vxGetCoreDataByCoreID(uint8_t core_id)
void serial2_printf(const char *fmt,...)
void * kalloc(size_t size)
page_t paging_get_highest_page_map(void)
void attach_to_scheduler(thread_t *new_thread)
#define LOG_ERROR(mod, fmt,...)
#define LOG2_ERROR(mod, fmt,...)
#define LOG2_INFO(mod, fmt,...)
void spin_acquire(spinlock_t *lock)
void spin_release(spinlock_t *lock)
struct vector_workqueue_ptr_t * dependency
thread_t * create_thread(volatile uintptr_t *page, uintptr_t entry, uintptr_t stack, uint16_t core_affinity, uint8_t priority, uint16_t flags)
workqueue_t * vxAddWorkqueueTask(void(*task)(void *), void *arg, struct vector_workqueue_ptr_t *dependency)
static void workqueue_process()
struct workqueue * workqueue_ptr_t
struct workqueue workqueue_t