Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/arch/xtensa/include/arch/schedule/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ void task_context_set(void *task_ctx);
* \brief Initializes task context.
* \param[in,out] task Task with context to be initialized.
* \param[in,out] entry Entry point for task execution.
* \param[in,out] data Parameter data for entry point.
*/
int task_context_init(struct task *task, void *entry);
int task_context_init(struct task *task, void *entry, void *data);

/**
* \brief Frees task context.
Expand Down
5 changes: 4 additions & 1 deletion src/arch/xtensa/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ int arch_init(struct sof *sof)
#include <sof/drivers/idc.h>
#include <sof/drivers/interrupt.h>
#include <sof/lib/notifier.h>
#include <sof/schedule/edf_schedule.h>
#include <sof/schedule/ll_schedule.h>
#include <sof/schedule/schedule.h>
#include <sof/schedule/task.h>
#include <sof/spinlock.h>
Expand All @@ -120,7 +122,8 @@ int slave_core_init(struct sof *sof)
platform_interrupt_init();

trace_point(TRACE_BOOT_PLATFORM_SCHED);
scheduler_init(sof);
scheduler_init_edf(sof);
scheduler_init_ll();

/* initialize IDC mechanism */
trace_point(TRACE_BOOT_PLATFORM_IDC);
Expand Down
4 changes: 2 additions & 2 deletions src/arch/xtensa/schedule/schedule.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
#include <sof/schedule/schedule.h>
#include <xtos-structs.h>

struct schedule_data **arch_schedule_get_data(void)
struct schedulers **arch_schedulers_get(void)
{
struct core_context *ctx = (struct core_context *)cpu_read_threadptr();

return &ctx->sch_data;
return &ctx->schedulers;
}
5 changes: 3 additions & 2 deletions src/arch/xtensa/schedule/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void task_context_set(void *task_ctx)
ctx->td.xtos_active_task = task_ctx;
}

int task_context_init(struct task *task, void *entry)
int task_context_init(struct task *task, void *entry, void *data)
{
struct edf_task_pdata *edf_pdata = edf_sch_get_pdata(task);
xtos_task_context *ctx;
Expand Down Expand Up @@ -97,8 +97,9 @@ int task_context_init(struct task *task, void *entry)
*/
sp->ps = PS_WOECALL4_ABI | PS_UM;

/* a6 is first parameter */
/* a6 and a7 are the first parameters */
sp->a6 = (uint32_t)task;
sp->a7 = (uint32_t)data;

ctx->stack_pointer = sp;

Expand Down
4 changes: 2 additions & 2 deletions src/arch/xtensa/xtos/xtos-structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

struct idc;
struct notify;
struct schedule_data;
struct schedulers;
struct task;

struct thread_data {
Expand All @@ -40,7 +40,7 @@ struct xtos_core_data {
struct core_context {
struct thread_data td;
struct task *main_task;
struct schedule_data *sch_data;
struct schedulers *schedulers;
struct notify *notify;
struct idc *idc;
};
Expand Down
9 changes: 1 addition & 8 deletions src/audio/pipeline.c
Original file line number Diff line number Diff line change
Expand Up @@ -958,14 +958,7 @@ void pipeline_schedule_copy(struct pipeline *p, uint64_t start)

void pipeline_schedule_cancel(struct pipeline *p)
{
int err;

/* cancel and wait for pipeline to complete */
err = schedule_task_cancel(&p->pipe_task);
if (err < 0)
trace_pipe_error_with_ids(p, "pipeline_schedule_cancel() "
"error: schedule_task_cancel() "
"failed, err = %d", err);
schedule_task_cancel(&p->pipe_task);
}

static enum task_state pipeline_task(void *arg)
Expand Down
4 changes: 4 additions & 0 deletions src/include/sof/schedule/edf_schedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <user/trace.h>
#include <stdint.h>

struct sof;

/* schedule tracing */
#define trace_edf_sch(format, ...) \
trace_event(TRACE_CLASS_EDF, format, ##__VA_ARGS__)
Expand All @@ -33,4 +35,6 @@ struct edf_task_pdata {
void *ctx;
};

int scheduler_init_edf(struct sof *sof);

#endif /* __SOF_SCHEDULE_EDF_SCHEDULE_H__ */
2 changes: 2 additions & 0 deletions src/include/sof/schedule/ll_schedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ struct ll_task_pdata {
uint64_t period;
};

int scheduler_init_ll(void);

#endif /* __SOF_SCHEDULE_LL_SCHEDULE_H__ */
138 changes: 100 additions & 38 deletions src/include/sof/schedule/schedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,13 @@
#ifndef __SOF_SCHEDULE_SCHEDULE_H__
#define __SOF_SCHEDULE_SCHEDULE_H__

#include <sof/common.h>
#include <sof/list.h>
#include <sof/schedule/task.h>
#include <sof/trace/trace.h>
#include <user/trace.h>
#include <stdint.h>

struct edf_schedule_data;
struct ll_schedule_data;
struct sof;

/* schedule tracing */
#define trace_schedule(format, ...) \
trace_event(TRACE_CLASS_EDF, format, ##__VA_ARGS__)
Expand All @@ -43,75 +40,140 @@ enum {
#define SOF_SCHEDULE_FLAG_IDLE (2 << 0)

struct scheduler_ops {
void (*schedule_task)(struct task *w, uint64_t start,
void (*schedule_task)(void *data, struct task *task, uint64_t start,
uint64_t period);
int (*schedule_task_init)(struct task *task);
void (*schedule_task_running)(struct task *task);
void (*schedule_task_complete)(struct task *task);
void (*reschedule_task)(struct task *task, uint64_t start);
int (*schedule_task_cancel)(struct task *task);
void (*schedule_task_free)(struct task *task);
int (*scheduler_init)(struct sof *sof);
void (*scheduler_free)(void);
void (*scheduler_run)(void);
int (*schedule_task_init)(void *data, struct task *task);
void (*schedule_task_running)(void *data, struct task *task);
void (*schedule_task_complete)(void *data, struct task *task);
void (*reschedule_task)(void *data, struct task *task, uint64_t start);
void (*schedule_task_cancel)(void *data, struct task *task);
void (*schedule_task_free)(void *data, struct task *task);
void (*scheduler_free)(void *data);
void (*scheduler_run)(void *data);
};

struct schedule_data {
struct ll_schedule_data *ll_sch_data;
struct edf_schedule_data *edf_sch_data;
struct list_item list;
int type;
const struct scheduler_ops *ops;
void *data;
};

struct schedulers {
struct list_item list;
};

extern struct scheduler_ops schedule_edf_ops;
extern struct scheduler_ops schedule_ll_ops;
struct schedulers **arch_schedulers_get(void);

static inline void schedule_task_running(struct task *task)
{
if (task->ops->schedule_task_running)
task->ops->schedule_task_running(task);
struct schedulers *schedulers = *arch_schedulers_get();
struct schedule_data *sch;
struct list_item *slist;

list_for_item(slist, &schedulers->list) {
sch = container_of(slist, struct schedule_data, list);
if (task->type == sch->type && sch->ops->schedule_task_running)
sch->ops->schedule_task_running(sch->data, task);
}
}

static inline void schedule_task_complete(struct task *task)
{
if (task->ops->schedule_task_complete)
task->ops->schedule_task_complete(task);
struct schedulers *schedulers = *arch_schedulers_get();
struct schedule_data *sch;
struct list_item *slist;

list_for_item(slist, &schedulers->list) {
sch = container_of(slist, struct schedule_data, list);
if (task->type == sch->type && sch->ops->schedule_task_complete)
sch->ops->schedule_task_complete(sch->data, task);
}
}

static inline void schedule_task(struct task *task, uint64_t start,
uint64_t period)
{
if (task->ops->schedule_task)
task->ops->schedule_task(task, start, period);
struct schedulers *schedulers = *arch_schedulers_get();
struct schedule_data *sch;
struct list_item *slist;

list_for_item(slist, &schedulers->list) {
sch = container_of(slist, struct schedule_data, list);
if (task->type == sch->type && sch->ops->schedule_task)
sch->ops->schedule_task(sch->data, task, start, period);
}
}

static inline void reschedule_task(struct task *task, uint64_t start)
{
if (task->ops->reschedule_task)
task->ops->reschedule_task(task, start);
struct schedulers *schedulers = *arch_schedulers_get();
struct schedule_data *sch;
struct list_item *slist;

list_for_item(slist, &schedulers->list) {
sch = container_of(slist, struct schedule_data, list);
if (task->type == sch->type && sch->ops->reschedule_task)
sch->ops->reschedule_task(sch->data, task, start);
}
}

static inline int schedule_task_cancel(struct task *task)
static inline void schedule_task_cancel(struct task *task)
{
if (task->ops->schedule_task_cancel)
return task->ops->schedule_task_cancel(task);
return 0;
struct schedulers *schedulers = *arch_schedulers_get();
struct schedule_data *sch;
struct list_item *slist;

list_for_item(slist, &schedulers->list) {
sch = container_of(slist, struct schedule_data, list);
if (task->type == sch->type && sch->ops->schedule_task_cancel)
sch->ops->schedule_task_cancel(sch->data, task);
}
}

static inline void schedule_task_free(struct task *task)
{
if (task->ops->schedule_task_free)
task->ops->schedule_task_free(task);
struct schedulers *schedulers = *arch_schedulers_get();
struct schedule_data *sch;
struct list_item *slist;

list_for_item(slist, &schedulers->list) {
sch = container_of(slist, struct schedule_data, list);
if (task->type == sch->type && sch->ops->schedule_task_free)
sch->ops->schedule_task_free(sch->data, task);
}
}

static inline void schedule_free(void)
{
struct schedulers *schedulers = *arch_schedulers_get();
struct schedule_data *sch;
struct list_item *slist;

list_for_item(slist, &schedulers->list) {
sch = container_of(slist, struct schedule_data, list);
if (sch->ops->scheduler_free)
sch->ops->scheduler_free(sch->data);
}
}

struct schedule_data **arch_schedule_get_data(void);
static inline void schedule(void)
{
struct schedulers *schedulers = *arch_schedulers_get();
struct schedule_data *sch;
struct list_item *slist;

list_for_item(slist, &schedulers->list) {
sch = container_of(slist, struct schedule_data, list);
if (sch->ops->scheduler_run)
sch->ops->scheduler_run(sch->data);
}
}

int schedule_task_init(struct task *task, uint16_t type, uint16_t priority,
enum task_state (*func)(void *data), void *data,
uint16_t core, uint32_t flags);

void schedule_free(void);

void schedule(void);

int scheduler_init(struct sof *sof);
void scheduler_init(int type, const struct scheduler_ops *ops, void *data);

#endif /* __SOF_SCHEDULE_SCHEDULE_H__ */
2 changes: 0 additions & 2 deletions src/include/sof/schedule/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <sof/list.h>
#include <stdint.h>

struct scheduler_ops;
struct sof;

#define SOF_TASK_PRI_HIGH 0 /* priority level 0 - high */
Expand Down Expand Up @@ -50,7 +49,6 @@ struct task {
void *data;
enum task_state (*func)(void *data);
struct list_item list;
const struct scheduler_ops *ops;
void *private;
};

Expand Down
6 changes: 4 additions & 2 deletions src/platform/baytrail/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
#include <sof/lib/notifier.h>
#include <sof/lib/shim.h>
#include <sof/platform.h>
#include <sof/schedule/schedule.h>
#include <sof/schedule/edf_schedule.h>
#include <sof/schedule/ll_schedule.h>
#include <sof/sof.h>
#include <sof/trace/dma-trace.h>
#include <sof/trace/trace.h>
Expand Down Expand Up @@ -193,7 +194,8 @@ int platform_init(struct sof *sof)
clock_init();

trace_point(TRACE_BOOT_PLATFORM_SCHED);
scheduler_init(sof);
scheduler_init_edf(sof);
scheduler_init_ll();

/* init the system agent */
trace_point(TRACE_BOOT_PLATFORM_AGENT);
Expand Down
6 changes: 4 additions & 2 deletions src/platform/haswell/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
#include <sof/lib/mailbox.h>
#include <sof/lib/notifier.h>
#include <sof/lib/shim.h>
#include <sof/schedule/schedule.h>
#include <sof/schedule/edf_schedule.h>
#include <sof/schedule/ll_schedule.h>
#include <sof/sof.h>
#include <sof/trace/dma-trace.h>
#include <sof/trace/trace.h>
Expand Down Expand Up @@ -182,7 +183,8 @@ int platform_init(struct sof *sof)
clock_init();

trace_point(TRACE_BOOT_PLATFORM_SCHED);
scheduler_init(sof);
scheduler_init_edf(sof);
scheduler_init_ll();

/* init the system agent */
trace_point(TRACE_BOOT_PLATFORM_AGENT);
Expand Down
6 changes: 4 additions & 2 deletions src/platform/imx8/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
#include <sof/lib/dai.h>
#include <sof/lib/mailbox.h>
#include <sof/platform.h>
#include <sof/schedule/schedule.h>
#include <sof/schedule/edf_schedule.h>
#include <sof/schedule/ll_schedule.h>
#include <sof/sof.h>
#include <ipc/dai.h>
#include <ipc/header.h>
Expand Down Expand Up @@ -149,7 +150,8 @@ int platform_init(struct sof *sof)
struct dai *esai;

clock_init();
scheduler_init(sof);
scheduler_init_edf(sof);
scheduler_init_ll();

platform_timer_start(platform_timer);
sa_init(sof);
Expand Down
Loading