|
| 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 | +#ifndef __SOF_SCHEDULE_DP_SCHEDULE_H__ |
| 9 | +#define __SOF_SCHEDULE_DP_SCHEDULE_H__ |
| 10 | + |
| 11 | +#include <rtos/task.h> |
| 12 | +#include <sof/trace/trace.h> |
| 13 | +#include <user/trace.h> |
| 14 | +#include <stdint.h> |
| 15 | + |
| 16 | +/** |
| 17 | + * |
| 18 | + * DP scheduler is a scheduler that creates a separate preemptible Zephyr thread for each SOF task |
| 19 | + * There's only one instance of DP in the system, however, threads can be assigned and pinned |
| 20 | + * to any core in the system for its execution, there's no SMP processing. |
| 21 | + * |
| 22 | + * The task execution may be delayed and task may be re-scheduled periodically |
| 23 | + * NOTE: delayed start and rescheduling takes place in sync with LL scheduler, meaning the |
| 24 | + * DP scheduler is triggered as the last task of LL running on a primary core. |
| 25 | + * That implies a limitation: LL scheduler MUST be running on primary core in order to have |
| 26 | + * this feature working. |
| 27 | + * It is fine, because rescheduling is a feature used for data processing when a pipeline is |
| 28 | + * running. |
| 29 | + * |
| 30 | + * Other possible usage of DP scheduler is to schedule task with DP_SCHEDULER_RUN_TASK_IMMEDIATELY |
| 31 | + * as start parameter. It will force the task to work without any delays and async to LL. |
| 32 | + * This kind of scheduling may be used for staring regular zephyr tasks using SOF api |
| 33 | + * |
| 34 | + * Task run() may return: |
| 35 | + * SOF_TASK_STATE_RESCHEDULE - the task will be rescheduled as specified in scheduler period |
| 36 | + * note that task won't ever be rescheduled if LL is not running |
| 37 | + * SOF_TASK_STATE_COMPLETED - the task will be removed from scheduling, |
| 38 | + * calling schedule_task will add the task to processing again |
| 39 | + * task_complete() will be called |
| 40 | + * SOF_TASK_STATE_CANCEL - the task will be removed from scheduling, |
| 41 | + * calling schedule_task will add the task to processing again |
| 42 | + * task_complete() won't be called |
| 43 | + * other statuses - assert will go off |
| 44 | + * |
| 45 | + * NOTE: task - means a SOF task |
| 46 | + * thread - means a Zephyr preemptible thread |
| 47 | + * |
| 48 | + * TODO - EDF: |
| 49 | + * Threads run on the same priority, lower than thread running LL tasks. Zephyr EDF mechanism |
| 50 | + * is used for decision which thread/task is to be scheduled next. The DP scheduler calculates |
| 51 | + * the task deadline and set it in Zephyr thread properties, the final scheduling decision is made |
| 52 | + * by Zephyr. |
| 53 | + * |
| 54 | + * Each time tick the scheduler iterates through the list of all active tasks and calculates |
| 55 | + * a deadline based on |
| 56 | + * - knowledge how the modules are bound |
| 57 | + * - declared time required by a task to complete processing |
| 58 | + * - the deadline of the last module |
| 59 | + * |
| 60 | + */ |
| 61 | + |
| 62 | +/** \brief tell the scheduler to run the task immediately, even if LL tick is not yet running */ |
| 63 | +#define SCHEDULER_DP_RUN_TASK_IMMEDIATELY ((uint64_t)-1) |
| 64 | + |
| 65 | +/** |
| 66 | + * \brief Init the Data Processing scheduler |
| 67 | + */ |
| 68 | +int scheduler_dp_init(void); |
| 69 | + |
| 70 | +/** |
| 71 | + * \brief Set the Data Processing scheduler to be accessible at secondary cores |
| 72 | + */ |
| 73 | +int scheduler_dp_init_secondary_core(void); |
| 74 | + |
| 75 | +/** |
| 76 | + * \brief initialize a DP task and add it to scheduling |
| 77 | + * |
| 78 | + * \param[out] task pointer, pointer to allocated task structure will be return |
| 79 | + * \param[in] uid pointer to UUID of the task |
| 80 | + * \param[in] ops pointer to task functions |
| 81 | + * \param[in] data pointer to the thread private data |
| 82 | + * \param[in] core CPU the thread should run on |
| 83 | + * \param[in] stack_size size of stack for a zephyr task |
| 84 | + * \param[in] task_priority priority of the zephyr task |
| 85 | + */ |
| 86 | +int scheduler_dp_task_init(struct task **task, |
| 87 | + const struct sof_uuid_entry *uid, |
| 88 | + const struct task_ops *ops, |
| 89 | + void *data, |
| 90 | + uint16_t core, |
| 91 | + size_t stack_size, |
| 92 | + uint32_t task_priority); |
| 93 | + |
| 94 | +#endif /* __SOF_SCHEDULE_DP_SCHEDULE_H__ */ |
0 commit comments