mirror of https://github.com/thesofproject/sof.git
task: add priority driven task management
Provide a method for tasks to be performed on a priority basis using the interrupts levels to preempt lower priority tasks. The scheduler will use the to schedule work at different priorities. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
This commit is contained in:
parent
535201458f
commit
2d2cd78be1
|
@ -32,7 +32,8 @@ reef_SOURCES = \
|
|||
_vectors.S \
|
||||
init.c \
|
||||
wait.S \
|
||||
timer.c
|
||||
timer.c \
|
||||
task.c
|
||||
|
||||
reef_CFLAGS = \
|
||||
$(ARCH_INCDIR) \
|
||||
|
@ -49,9 +50,9 @@ reef_LDADD = \
|
|||
../../init/libinit.a \
|
||||
../../platform/$(PLATFORM)/libplatform.a \
|
||||
../../tasks/libtasks.a \
|
||||
../../audio/libaudio.a \
|
||||
../../lib/libcore.a \
|
||||
../../ipc/libipc.a \
|
||||
../../audio/libaudio.a \
|
||||
../../drivers/libdrivers.a \
|
||||
libreset.a \
|
||||
xtos/libxtos.a \
|
||||
|
|
|
@ -8,4 +8,5 @@ noinst_HEADERS = \
|
|||
arch/interrupt.h \
|
||||
arch/reef.h \
|
||||
arch/spinlock.h \
|
||||
arch/timer.h
|
||||
arch/timer.h \
|
||||
arch/task.h
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the Intel Corporation nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_TASK_H_
|
||||
#define __ARCH_TASK_H_
|
||||
|
||||
struct task;
|
||||
|
||||
void arch_run_task(struct task *task);
|
||||
|
||||
int arch_init_tasks(void);
|
||||
|
||||
#endif
|
|
@ -34,6 +34,7 @@
|
|||
#include <reef/interrupt.h>
|
||||
#include <platform/interrupt.h>
|
||||
#include <reef/mailbox.h>
|
||||
#include <arch/task.h>
|
||||
#include <reef/debug.h>
|
||||
#include <reef/init.h>
|
||||
#include <stdint.h>
|
||||
|
@ -152,6 +153,7 @@ static void register_exceptions(void)
|
|||
int arch_init(struct reef *reef)
|
||||
{
|
||||
register_exceptions();
|
||||
arch_init_tasks();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the Intel Corporation nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <reef/schedule.h>
|
||||
#include <reef/interrupt.h>
|
||||
#include <platform/platform.h>
|
||||
#include <reef/debug.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
static struct task *_irq_low_task = NULL;
|
||||
static struct task *_irq_med_task = NULL;
|
||||
static struct task *_irq_high_task = NULL;
|
||||
|
||||
static inline uint32_t task_get_irq(struct task *task)
|
||||
{
|
||||
uint32_t irq;
|
||||
|
||||
switch (task->priority) {
|
||||
case TASK_PRI_MED + 1 ... TASK_PRI_LOW:
|
||||
irq = PLATFORM_IRQ_TASK_LOW;
|
||||
break;
|
||||
case TASK_PRI_HIGH ... TASK_PRI_MED - 1:
|
||||
irq = PLATFORM_IRQ_TASK_HIGH;
|
||||
break;
|
||||
case TASK_PRI_MED:
|
||||
default:
|
||||
irq = PLATFORM_IRQ_TASK_MED;
|
||||
break;
|
||||
}
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
static inline void task_set_data(struct task *task)
|
||||
{
|
||||
switch (task->priority) {
|
||||
case TASK_PRI_MED + 1 ... TASK_PRI_LOW:
|
||||
_irq_low_task = task;
|
||||
break;
|
||||
case TASK_PRI_HIGH ... TASK_PRI_MED - 1:
|
||||
_irq_high_task = task;
|
||||
break;
|
||||
case TASK_PRI_MED:
|
||||
default:
|
||||
_irq_med_task = task;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void _irq_low(void *arg)
|
||||
{
|
||||
struct task *task = *(struct task **)arg;
|
||||
uint32_t irq;
|
||||
|
||||
if (task->func)
|
||||
task->func(task->data);
|
||||
|
||||
schedule_task_complete(task);
|
||||
irq = task_get_irq(task);
|
||||
interrupt_clear(irq);
|
||||
}
|
||||
|
||||
static void _irq_med(void *arg)
|
||||
{
|
||||
struct task *task = *(struct task **)arg;
|
||||
uint32_t irq;
|
||||
|
||||
if (task->func)
|
||||
task->func(task->data);
|
||||
|
||||
schedule_task_complete(task);
|
||||
irq = task_get_irq(task);
|
||||
interrupt_clear(irq);
|
||||
}
|
||||
|
||||
static void _irq_high(void *arg)
|
||||
{
|
||||
struct task *task = *(struct task **)arg;
|
||||
uint32_t irq;
|
||||
|
||||
if (task->func)
|
||||
task->func(task->data);
|
||||
|
||||
schedule_task_complete(task);
|
||||
irq = task_get_irq(task);
|
||||
interrupt_clear(irq);
|
||||
}
|
||||
|
||||
/* architecture specific method of running task */
|
||||
void arch_run_task(struct task *task)
|
||||
{
|
||||
uint32_t irq;
|
||||
|
||||
task_set_data(task);
|
||||
irq = task_get_irq(task);
|
||||
interrupt_set(irq);
|
||||
}
|
||||
|
||||
int arch_init_tasks(void)
|
||||
{
|
||||
interrupt_register(PLATFORM_IRQ_TASK_LOW, _irq_low, &_irq_low_task);
|
||||
interrupt_enable(PLATFORM_IRQ_TASK_LOW);
|
||||
|
||||
interrupt_register(PLATFORM_IRQ_TASK_MED, _irq_med, &_irq_med_task);
|
||||
interrupt_enable(PLATFORM_IRQ_TASK_MED);
|
||||
|
||||
interrupt_register(PLATFORM_IRQ_TASK_HIGH, _irq_high, &_irq_high_task);
|
||||
interrupt_enable(PLATFORM_IRQ_TASK_HIGH);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -52,6 +52,10 @@ struct reef;
|
|||
/* pipeline IRQ */
|
||||
#define PLATFORM_PIPELINE_IRQ IRQ_NUM_SOFTWARE4
|
||||
|
||||
#define PLATFORM_IRQ_TASK_HIGH IRQ_NUM_SOFTWARE4
|
||||
#define PLATFORM_IRQ_TASK_MED IRQ_NUM_SOFTWARE3
|
||||
#define PLATFORM_IRQ_TASK_LOW IRQ_NUM_SOFTWARE2
|
||||
|
||||
/* DMA treats PHY addresses as host address unless within DSP region */
|
||||
#define PLATFORM_HOST_DMA_MASK 0xFF000000
|
||||
|
||||
|
|
Loading…
Reference in New Issue