Skip to content

Commit 4067d2f

Browse files
committed
add poll to dp
Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
1 parent 3b12483 commit 4067d2f

File tree

4 files changed

+102
-52
lines changed

4 files changed

+102
-52
lines changed

app/boards/intel_adsp_ace30_ptl.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,4 @@ CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP=y
108108
CONFIG_LOG_TIMESTAMP_64BIT=y
109109

110110
CONFIG_USERSPACE=y
111+
CONFIG_POLL=y

src/audio/module_adapter/library/userspace_proxy.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ uint32_t ptable_size(struct k_mem_domain *domain)
146146
return cnt;
147147
}
148148

149-
void userspace_proxy_handle_request(struct processing_module *mod, struct module_params *params)
149+
void userspace_proxy_handle_request_params(struct processing_module *mod, struct module_params *params)
150150
{
151151
const struct module_interface *ops;
152152

@@ -237,14 +237,30 @@ void userspace_proxy_handle_request(struct processing_module *mod, struct module
237237
}
238238
}
239239

240+
void userspace_proxy_init_poll_event(struct processing_module *mod, struct k_poll_event *event)
241+
{
242+
k_poll_event_init(event, K_POLL_TYPE_MSGQ_DATA_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY,
243+
mod->user_ctx->in_msgq);
244+
}
245+
246+
void userspace_proxy_handle_request(struct processing_module *mod)
247+
{
248+
struct module_params params;
249+
k_msgq_get(mod->user_ctx->in_msgq, &params, K_FOREVER);
250+
251+
userspace_proxy_handle_request_params(mod, &params);
252+
k_msgq_put(mod->user_ctx->out_msgq, &params, K_FOREVER);
253+
254+
}
255+
240256
static void user_worker_handler(struct k_work_user *work_item)
241257
{
242258
struct user_worker_data *wd = CONTAINER_OF(work_item, struct user_worker_data, work_item);
243259
struct module_params *params = (struct module_params *)wd->ipc_params;
244260
while(1) {
245261
k_msgq_get(wd->tmp_in_msgq, params, K_FOREVER);
246262

247-
userspace_proxy_handle_request(params->mod, params);
263+
userspace_proxy_handle_request_params(params->mod, params);
248264
k_msgq_put(wd->tmp_out_msgq, params, K_FOREVER);
249265

250266
k_yield();

src/include/sof/audio/module_adapter/library/userspace_proxy.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ int userspace_proxy_create(struct userspace_context **user_ctx, const struct com
6767
*/
6868
void userspace_proxy_destroy(const struct comp_driver *drv, struct userspace_context *user_ctx);
6969

70+
void userspace_proxy_handle_request(struct processing_module *mod);
71+
72+
void userspace_proxy_init_poll_event(struct processing_module *mod, struct k_poll_event *event);
73+
7074
#else
7175

7276
#define APP_USER_DATA

src/schedule/zephyr_dp_schedule.c

Lines changed: 79 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
#include <zephyr/sys/mutex.h>
2323
#include <sof/lib/notifier.h>
2424
#include <ipc4/base_fw.h>
25+
#include <sof/audio/module_adapter/library/userspace_proxy.h>
2526

2627
#include <zephyr/kernel/thread.h>
28+
#include <zephyr/kernel.h>
2729

2830
LOG_MODULE_REGISTER(dp_schedule, CONFIG_SOF_LOG_LEVEL);
2931
SOF_DEFINE_REG_UUID(dp_sched);
@@ -42,8 +44,8 @@ struct task_dp_pdata {
4244
uint32_t deadline_clock_ticks; /* dp module deadline in Zephyr ticks */
4345
k_thread_stack_t __sparse_cache *p_stack; /* pointer to thread stack */
4446
size_t stack_size; /* size of the stack in bytes */
45-
struct k_sem *sem; /* pointer to semaphore for task scheduling */
46-
struct k_sem sem_struct; /* semaphore for task scheduling for kernel threads */
47+
struct k_poll_signal *signal; /* pointer to signal to wake up the thread */
48+
struct k_poll_signal signal_struct; /* signal to wake up the thread */
4749
struct processing_module *mod; /* the module to be scheduled */
4850
uint32_t ll_cycles_to_start; /* current number of LL cycles till delayed start */
4951
};
@@ -298,7 +300,7 @@ void scheduler_dp_ll_tick(void *receiver_data, enum notify_id event_type, void *
298300

299301
/* trigger the task */
300302
curr_task->state = SOF_TASK_STATE_RUNNING;
301-
k_sem_give(pdata->sem);
303+
k_poll_signal_raise(pdata->signal, 0);
302304
}
303305
}
304306
}
@@ -323,7 +325,7 @@ static int scheduler_dp_task_cancel(void *data, struct task *task)
323325
schedule_task_cancel(&dp_sch->ll_tick_src);
324326

325327
/* if the task is waiting on a semaphore - let it run and self-terminate */
326-
k_sem_give(pdata->sem);
328+
k_poll_signal_raise(pdata->signal, 1);
327329
scheduler_dp_unlock(lock_key);
328330

329331
/* wait till the task has finished, if there was any task created */
@@ -349,8 +351,8 @@ static int scheduler_dp_task_free(void *data, struct task *task)
349351
}
350352

351353
#ifdef CONFIG_USERSPACE
352-
if (pdata->sem != &pdata->sem_struct)
353-
k_object_free(pdata->sem);
354+
if (pdata->signal != &pdata->signal_struct)
355+
k_object_free(pdata->signal);
354356
if (pdata->thread != &pdata->thread_struct)
355357
k_object_free(pdata->thread);
356358
#endif
@@ -370,52 +372,79 @@ static void dp_thread_fn(void *p1, void *p2, void *p3)
370372
(void)p2;
371373
(void)p3;
372374
struct task_dp_pdata *task_pdata = task->priv_data;
375+
struct processing_module *mod = task_pdata->mod;
373376
unsigned int lock_key;
374377
enum task_state state;
375378
bool task_stop;
379+
int ret;
376380

377-
do {
378-
/*
379-
* the thread is started immediately after creation, it will stop on semaphore
380-
* Semaphore will be released once the task is ready to process
381-
*/
382-
k_sem_take(task_pdata->sem, K_FOREVER);
381+
struct k_poll_event events[] = {
382+
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY,
383+
task_pdata->signal),
384+
#ifdef CONFIG_USERSPACE
385+
{}
386+
#endif
387+
};
388+
int events_count = 1;
383389

384-
if (task->state == SOF_TASK_STATE_RUNNING)
385-
state = task_run(task);
386-
else
387-
state = task->state; /* to avoid undefined variable warning */
390+
#ifdef CONFIG_USERSPACE
391+
if (mod->user_ctx) {
392+
userspace_proxy_init_poll_event(mod, &events[1]);
393+
events_count = 2;
394+
}
395+
#endif
388396

389-
lock_key = scheduler_dp_lock(task->core);
390-
/*
397+
do {
398+
/* the thread is started immediately after creation, it will stop on poll.
399+
* Signal will be raised once the task is ready to process
400+
*/
401+
ret = k_poll(events, events_count, K_FOREVER);
402+
if (events[0].state == K_POLL_STATE_SIGNALED) {
403+
events[0].state = K_POLL_STATE_NOT_READY;
404+
k_poll_signal_reset(task_pdata->signal);
405+
406+
if (task->state == SOF_TASK_STATE_RUNNING)
407+
state = task_run(task);
408+
else
409+
state = task->state; /* to avoid undefined variable warning */
410+
411+
lock_key = scheduler_dp_lock(task->core);
412+
/*
391413
* check if task is still running, may have been canceled by external call
392414
* if not, set the state returned by run procedure
393415
*/
394-
if (task->state == SOF_TASK_STATE_RUNNING) {
395-
task->state = state;
396-
switch (state) {
397-
case SOF_TASK_STATE_RESCHEDULE:
398-
/* mark to reschedule, schedule time is already calculated */
399-
task->state = SOF_TASK_STATE_QUEUED;
400-
break;
401-
402-
case SOF_TASK_STATE_CANCEL:
403-
case SOF_TASK_STATE_COMPLETED:
404-
/* remove from scheduling */
405-
list_item_del(&task->list);
406-
break;
407-
408-
default:
409-
/* illegal state, serious defect, won't happen */
410-
k_panic();
416+
if (task->state == SOF_TASK_STATE_RUNNING) {
417+
task->state = state;
418+
switch (state) {
419+
case SOF_TASK_STATE_RESCHEDULE:
420+
/* mark to reschedule, schedule time is already calculated */
421+
task->state = SOF_TASK_STATE_QUEUED;
422+
break;
423+
424+
case SOF_TASK_STATE_CANCEL:
425+
case SOF_TASK_STATE_COMPLETED:
426+
/* remove from scheduling */
427+
list_item_del(&task->list);
428+
break;
429+
430+
default:
431+
/* illegal state, serious defect, won't happen */
432+
k_panic();
433+
}
411434
}
412-
}
413435

414-
/* if true exit the while loop, terminate the thread */
415-
task_stop = task->state == SOF_TASK_STATE_COMPLETED ||
416-
task->state == SOF_TASK_STATE_CANCEL;
436+
/* if true exit the while loop, terminate the thread */
437+
task_stop = task->state == SOF_TASK_STATE_COMPLETED ||
438+
task->state == SOF_TASK_STATE_CANCEL;
417439

418-
scheduler_dp_unlock(lock_key);
440+
scheduler_dp_unlock(lock_key);
441+
}
442+
#ifdef CONFIG_USERSPACE
443+
if (events[1].state == K_POLL_STATE_MSGQ_DATA_AVAILABLE) {
444+
events[1].state = K_POLL_STATE_NOT_READY;
445+
userspace_proxy_handle_request(mod);
446+
}
447+
#endif
419448
} while (!task_stop);
420449

421450
/* call task_complete */
@@ -451,7 +480,7 @@ static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t sta
451480
return -ECHILD;
452481
}
453482

454-
k_thread_access_grant(pdata->thread_id, pdata->sem);
483+
k_thread_access_grant(pdata->thread_id, pdata->signal);
455484
scheduler_dp_grant(pdata->thread_id, cpu_get_id());
456485
/* pin the thread to specific core */
457486
ret = k_thread_cpu_pin(pdata->thread_id, task->core);
@@ -470,8 +499,8 @@ static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t sta
470499
}
471500
#endif /* CONFIG_USERSPACE */
472501

473-
/* start the thread, it should immediately stop at a semaphore, so clean it */
474-
k_sem_init(pdata->sem, 0, 1);
502+
/* start the thread, it should immediately stop at a poll */
503+
k_poll_signal_init(pdata->signal);
475504
k_thread_start(pdata->thread_id);
476505

477506
/* if there's no DP tasks scheduled yet, run ll tick source task */
@@ -587,16 +616,16 @@ int scheduler_dp_task_init(struct task **task,
587616
goto err;
588617
}
589618

590-
/* Point to ksem semaphore for kernel threads synchronization */
591-
/* It will be overwritten for K_USER threads to dynamic ones. */
592-
task_memory->pdata.sem = &task_memory->pdata.sem_struct;
619+
/* Point to local kernel objects. It will be overwritten for K_USER threads to dynamic ones.
620+
*/
621+
task_memory->pdata.signal= &task_memory->pdata.signal_struct;
593622
task_memory->pdata.thread = &task_memory->pdata.thread_struct;
594623

595624
#ifdef CONFIG_USERSPACE
596625
if (options & K_USER) {
597-
task_memory->pdata.sem = k_object_alloc(K_OBJ_SEM);
598-
if (!task_memory->pdata.sem) {
599-
tr_err(&dp_tr, "Semaphore object allocation failed");
626+
task_memory->pdata.signal = k_object_alloc(K_OBJ_POLL_SIGNAL);
627+
if (!task_memory->pdata.signal) {
628+
tr_err(&dp_tr, "Signal object allocation failed");
600629
ret = -ENOMEM;
601630
goto err;
602631
}
@@ -630,7 +659,7 @@ int scheduler_dp_task_init(struct task **task,
630659
tr_err(&dp_tr, "user_stack_free failed!");
631660

632661
/* k_object_free looks for a pointer in the list, any invalid value can be passed */
633-
k_object_free(task_memory->pdata.sem);
662+
k_object_free(task_memory->pdata.signal);
634663
k_object_free(task_memory->pdata.thread);
635664
rfree(task_memory);
636665
return ret;

0 commit comments

Comments
 (0)