Skip to content

Commit ceb5010

Browse files
lyakhlgirdwood
authored andcommitted
dp: extract 2 functions into a separate file
scheduler_dp_recalculate() and dp_thread_fn() will have significant difference between the "proxy" and "native" versions. Extract them into a separate file for easy forking. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent 9eceeb4 commit ceb5010

4 files changed

Lines changed: 215 additions & 174 deletions

File tree

src/schedule/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ endif()
4040

4141
zephyr_library_sources_ifdef(CONFIG_ZEPHYR_DP_SCHEDULER
4242
zephyr_dp_schedule.c
43+
zephyr_dp_schedule_proxy.c
4344
)
4445

4546
zephyr_library_sources_ifdef(CONFIG_ZEPHYR_TWB_SCHEDULER

src/schedule/zephyr_dp_schedule.c

Lines changed: 4 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,15 @@
2323
#include <sof/lib/notifier.h>
2424
#include <ipc4/base_fw.h>
2525

26+
#include "zephyr_dp_schedule.h"
27+
2628
#include <zephyr/kernel/thread.h>
2729

2830
LOG_MODULE_REGISTER(dp_schedule, CONFIG_SOF_LOG_LEVEL);
2931
SOF_DEFINE_REG_UUID(dp_sched);
3032

3133
DECLARE_TR_CTX(dp_tr, SOF_UUID(dp_sched_uuid), LOG_LEVEL_INFO);
3234

33-
struct scheduler_dp_data {
34-
struct list_item tasks; /* list of active dp tasks */
35-
struct task ll_tick_src; /* LL task - source of DP tick */
36-
uint32_t last_ll_tick_timestamp;/* a timestamp as k_cycle_get_32 of last LL tick,
37-
* "NOW" for DP deadline calculation
38-
*/
39-
40-
};
41-
42-
struct task_dp_pdata {
43-
k_tid_t thread_id; /* zephyr thread ID */
44-
struct k_thread *thread; /* pointer to the kernels' thread object */
45-
struct k_thread thread_struct; /* thread object for kernel threads */
46-
uint32_t deadline_clock_ticks; /* dp module deadline in Zephyr ticks */
47-
k_thread_stack_t __sparse_cache *p_stack; /* pointer to thread stack */
48-
size_t stack_size; /* size of the stack in bytes */
49-
struct k_sem *sem; /* pointer to semaphore for task scheduling */
50-
struct k_sem sem_struct; /* semaphore for task scheduling for kernel threads */
51-
struct processing_module *mod; /* the module to be scheduled */
52-
uint32_t ll_cycles_to_start; /* current number of LL cycles till delayed start */
53-
};
54-
5535
#define DP_LOCK_INIT(i, _) Z_SEM_INITIALIZER(dp_lock[i], 1, 1)
5636
#define DP_LOCK_INIT_LIST LISTIFY(CONFIG_MP_MAX_NUM_CPUS, DP_LOCK_INIT, (,))
5737

@@ -66,13 +46,13 @@ STRUCT_SECTION_ITERABLE_ARRAY(k_sem, dp_lock, CONFIG_MP_MAX_NUM_CPUS) = { DP_LOC
6646
*
6747
* TODO: consider using cpu_get_id() instead of supplying core as a parameter.
6848
*/
69-
static inline unsigned int scheduler_dp_lock(uint16_t core)
49+
unsigned int scheduler_dp_lock(uint16_t core)
7050
{
7151
k_sem_take(&dp_lock[core], K_FOREVER);
7252
return core;
7353
}
7454

75-
static inline void scheduler_dp_unlock(unsigned int key)
55+
void scheduler_dp_unlock(unsigned int key)
7656
{
7757
k_sem_give(&dp_lock[key]);
7858
}
@@ -243,86 +223,6 @@ static enum task_state scheduler_dp_ll_tick_dummy(void *data)
243223
* needed 1.2ms for processing - but the example would be too complicated)
244224
*/
245225

246-
/* Go through all DP tasks and recalculate their readness and dedlines
247-
* NOT REENTRANT, should be called with scheduler_dp_lock()
248-
*/
249-
static void scheduler_dp_recalculate(struct scheduler_dp_data *dp_sch, bool is_ll_post_run)
250-
{
251-
struct list_item *tlist;
252-
struct task *curr_task;
253-
struct task_dp_pdata *pdata;
254-
255-
list_for_item(tlist, &dp_sch->tasks) {
256-
curr_task = container_of(tlist, struct task, list);
257-
pdata = curr_task->priv_data;
258-
struct processing_module *mod = pdata->mod;
259-
bool trigger_task = false;
260-
261-
/* decrease number of LL ticks/cycles left till the module reaches its deadline */
262-
if (mod->dp_startup_delay && is_ll_post_run && pdata->ll_cycles_to_start) {
263-
pdata->ll_cycles_to_start--;
264-
if (!pdata->ll_cycles_to_start)
265-
/* delayed start complete, clear startup delay flag.
266-
* see dp_startup_delay comment for details
267-
*/
268-
mod->dp_startup_delay = false;
269-
270-
}
271-
272-
if (curr_task->state == SOF_TASK_STATE_QUEUED) {
273-
bool mod_ready;
274-
275-
mod_ready = module_is_ready_to_process(mod, mod->sources,
276-
mod->num_of_sources,
277-
mod->sinks,
278-
mod->num_of_sinks);
279-
if (mod_ready) {
280-
/* trigger the task */
281-
curr_task->state = SOF_TASK_STATE_RUNNING;
282-
if (mod->dp_startup_delay && !pdata->ll_cycles_to_start) {
283-
/* first time run - use delayed start */
284-
pdata->ll_cycles_to_start =
285-
module_get_lpt(pdata->mod) / LL_TIMER_PERIOD_US;
286-
287-
/* in case LPT < LL cycle - delay at least cycle */
288-
if (!pdata->ll_cycles_to_start)
289-
pdata->ll_cycles_to_start = 1;
290-
}
291-
trigger_task = true;
292-
k_sem_give(pdata->sem);
293-
}
294-
}
295-
if (curr_task->state == SOF_TASK_STATE_RUNNING) {
296-
/* (re) calculate deadline for all running tasks */
297-
/* get module deadline in us*/
298-
uint32_t deadline = module_get_deadline(mod);
299-
300-
/* if a deadline cannot be calculated, use a fixed value relative to its
301-
* first start
302-
*/
303-
if (deadline >= UINT32_MAX / 2 && trigger_task)
304-
deadline = module_get_lpt(mod);
305-
306-
if (deadline < UINT32_MAX) {
307-
/* round down to 1ms */
308-
deadline = deadline / 1000;
309-
310-
/* calculate number of ticks */
311-
deadline = deadline * (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000);
312-
313-
/* add to "NOW", overflows are OK */
314-
deadline = dp_sch->last_ll_tick_timestamp + deadline;
315-
316-
/* set in Zephyr. Note that it may be in past, it does not matter,
317-
* Zephyr still will schedule the thread with earlier deadline
318-
* first
319-
*/
320-
k_thread_absolute_deadline_set(pdata->thread_id, deadline);
321-
}
322-
}
323-
}
324-
}
325-
326226
void scheduler_dp_ll_tick(void *receiver_data, enum notify_id event_type, void *caller_data)
327227
{
328228
(void)receiver_data;
@@ -398,76 +298,6 @@ static int scheduler_dp_task_free(void *data, struct task *task)
398298
return ret;
399299
}
400300

401-
/* Thread function called in component context, on target core */
402-
static void dp_thread_fn(void *p1, void *p2, void *p3)
403-
{
404-
struct task *task = p1;
405-
(void)p2;
406-
(void)p3;
407-
struct task_dp_pdata *task_pdata = task->priv_data;
408-
struct scheduler_dp_data *dp_sch = NULL;
409-
unsigned int lock_key;
410-
enum task_state state;
411-
bool task_stop;
412-
413-
if (!(task->flags & K_USER))
414-
dp_sch = scheduler_get_data(SOF_SCHEDULE_DP);
415-
416-
do {
417-
/*
418-
* the thread is started immediately after creation, it will stop on semaphore
419-
* Semaphore will be released once the task is ready to process
420-
*/
421-
k_sem_take(task_pdata->sem, K_FOREVER);
422-
423-
if (task->state == SOF_TASK_STATE_RUNNING)
424-
state = task_run(task);
425-
else
426-
state = task->state; /* to avoid undefined variable warning */
427-
428-
lock_key = scheduler_dp_lock(task->core);
429-
/*
430-
* check if task is still running, may have been canceled by external call
431-
* if not, set the state returned by run procedure
432-
*/
433-
if (task->state == SOF_TASK_STATE_RUNNING) {
434-
task->state = state;
435-
switch (state) {
436-
case SOF_TASK_STATE_RESCHEDULE:
437-
/* mark to reschedule, schedule time is already calculated */
438-
task->state = SOF_TASK_STATE_QUEUED;
439-
break;
440-
441-
case SOF_TASK_STATE_CANCEL:
442-
case SOF_TASK_STATE_COMPLETED:
443-
/* remove from scheduling */
444-
list_item_del(&task->list);
445-
break;
446-
447-
default:
448-
/* illegal state, serious defect, won't happen */
449-
k_panic();
450-
}
451-
}
452-
453-
/* if true exit the while loop, terminate the thread */
454-
task_stop = task->state == SOF_TASK_STATE_COMPLETED ||
455-
task->state == SOF_TASK_STATE_CANCEL;
456-
/* recalculate all DP tasks readiness and deadlines
457-
* TODO: it should be for all tasks, for all cores
458-
* currently its limited to current core only
459-
*/
460-
if (dp_sch)
461-
scheduler_dp_recalculate(dp_sch, false);
462-
463-
scheduler_dp_unlock(lock_key);
464-
} while (!task_stop);
465-
466-
/* call task_complete */
467-
if (task->state == SOF_TASK_STATE_COMPLETED)
468-
task_complete(task);
469-
}
470-
471301
static int scheduler_dp_task_shedule(void *data, struct task *task, uint64_t start,
472302
uint64_t period)
473303
{

src/schedule/zephyr_dp_schedule.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* SPDX-License-Identifier: BSD-3-Clause */
2+
/*
3+
* Copyright(c) 2023 Intel Corporation. All rights reserved.
4+
*
5+
* Author: Marcin Szkudlinski
6+
*/
7+
8+
#include <rtos/task.h>
9+
#include <sof/audio/module_adapter/module/generic.h>
10+
#include <sof/list.h>
11+
#include <sof/compiler_attributes.h>
12+
13+
#include <stdbool.h>
14+
#include <stdint.h>
15+
16+
struct scheduler_dp_data {
17+
struct list_item tasks; /* list of active dp tasks */
18+
struct task ll_tick_src; /* LL task - source of DP tick */
19+
uint32_t last_ll_tick_timestamp;/* a timestamp as k_cycle_get_32 of last LL tick,
20+
* "NOW" for DP deadline calculation
21+
*/
22+
23+
};
24+
25+
struct task_dp_pdata {
26+
k_tid_t thread_id; /* zephyr thread ID */
27+
struct k_thread *thread; /* pointer to the kernels' thread object */
28+
struct k_thread thread_struct; /* thread object for kernel threads */
29+
uint32_t deadline_clock_ticks; /* dp module deadline in Zephyr ticks */
30+
k_thread_stack_t __sparse_cache *p_stack; /* pointer to thread stack */
31+
size_t stack_size; /* size of the stack in bytes */
32+
struct k_sem *sem; /* pointer to semaphore for task scheduling */
33+
struct k_sem sem_struct; /* semaphore for task scheduling for kernel threads */
34+
struct processing_module *mod; /* the module to be scheduled */
35+
uint32_t ll_cycles_to_start; /* current number of LL cycles till delayed start */
36+
};
37+
38+
void scheduler_dp_recalculate(struct scheduler_dp_data *dp_sch, bool is_ll_post_run);
39+
void dp_thread_fn(void *p1, void *p2, void *p3);
40+
unsigned int scheduler_dp_lock(uint16_t core);
41+
void scheduler_dp_unlock(unsigned int key);

0 commit comments

Comments
 (0)