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
2830LOG_MODULE_REGISTER (dp_schedule , CONFIG_SOF_LOG_LEVEL );
2931SOF_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