From ae8a609173e4490fd03875f96e388038053b9288 Mon Sep 17 00:00:00 2001 From: arighi Date: Thu, 18 Mar 2010 14:54:41 +0000 Subject: [PATCH] Parametric scheduler approach. Define distinct functions for each implemented scheduler class. This is a first step toward the "plugin-scheduler" approach. In this way we can also get rid of mtask.c. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3240 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/irq.h | 2 +- bertos/kern/coop.c | 8 +++--- bertos/kern/mtask.c | 50 ---------------------------------- bertos/kern/preempt.c | 18 ++++++------ bertos/kern/preempt.h | 4 --- bertos/kern/proc.c | 5 +--- bertos/kern/proc.h | 46 +++++++++++++++++++++++++------ bertos/kern/proc_p.h | 9 ++++-- examples/at91sam7/at91sam7s.mk | 3 +- examples/at91sam7/at91sam7x.mk | 3 +- examples/demo/demo.mk | 3 +- test/get_source_list.sh | 2 +- test/run_tests.sh | 3 +- 13 files changed, 69 insertions(+), 87 deletions(-) delete mode 100644 bertos/kern/mtask.c diff --git a/bertos/cpu/irq.h b/bertos/cpu/irq.h index 4e61f20a..466b524d 100644 --- a/bertos/cpu/irq.h +++ b/bertos/cpu/irq.h @@ -44,7 +44,7 @@ #include "detect.h" #include "types.h" -#include +#include /* proc_needPreempt() / proc_preempt() */ #include /* for uintXX_t */ #include "cfg/cfg_proc.h" /* CONFIG_KERN_PREEMPT */ diff --git a/bertos/kern/coop.c b/bertos/kern/coop.c index be3d6dfd..21731260 100644 --- a/bertos/kern/coop.c +++ b/bertos/kern/coop.c @@ -63,7 +63,7 @@ EXTERN_C void asm_switch_context(cpu_stack_t **new_sp, cpu_stack_t **save_sp); * System scheduler: pass CPU control to the next process in * the ready queue. */ -static void proc_schedule(void) +static void coop_schedule(void) { cpu_flags_t flags; @@ -98,12 +98,12 @@ static void proc_schedule(void) IRQ_RESTORE(flags); } -void proc_switch(void) +void coop_switch(void) { /* Remember old process to save its context later */ Process * const old_process = current_process; - proc_schedule(); + coop_schedule(); /* * Optimization: don't switch contexts when the active @@ -135,7 +135,7 @@ void proc_switch(void) /** * Co-operative context switch */ -void proc_yield(void) +void coop_yield(void) { ATOMIC(SCHED_ENQUEUE(current_process)); proc_switch(); diff --git a/bertos/kern/mtask.c b/bertos/kern/mtask.c deleted file mode 100644 index ee51e838..00000000 --- a/bertos/kern/mtask.c +++ /dev/null @@ -1,50 +0,0 @@ -/** - * \file - * - * - * \brief Choose the multitasking scheduler. - * - * \author Francesco Sacchi - */ - - -#include "cfg/cfg_proc.h" - -/* - * Choose which file to compile depending on - * the multitasking type. - */ -#if CONFIG_KERN_PREEMPT - #include "preempt.c" -#else - #include "coop.c" -#endif - diff --git a/bertos/kern/preempt.c b/bertos/kern/preempt.c index 3037c15c..d3d9badf 100644 --- a/bertos/kern/preempt.c +++ b/bertos/kern/preempt.c @@ -39,7 +39,7 @@ * the time sharing interval. * * When the quantum expires the handler proc_needPreempt() checks if the - * preemption is enabled and in this case proc_schedule() is called, that + * preemption is enabled and in this case preempt_schedule() is called, that * possibly replaces the current running thread with a different one. * * The preemption can be disabled or enabled via proc_forbid() and @@ -126,7 +126,7 @@ int _proc_quantum; /** * Call the scheduler and eventually replace the current running process. */ -static void proc_schedule(void) +static void preempt_schedule(void) { Process *old_process = current_process; @@ -166,7 +166,7 @@ static void proc_schedule(void) /** * Check if we need to schedule another task */ -int proc_needPreempt(void) +int preempt_needPreempt(void) { if (UNLIKELY(current_process == NULL)) return 0; @@ -179,7 +179,7 @@ int proc_needPreempt(void) /** * Preempt the current task. */ -void proc_preempt(void) +void preempt_preempt(void) { IRQ_ASSERT_DISABLED(); ASSERT(current_process); @@ -189,7 +189,7 @@ void proc_preempt(void) /* We are inside a IRQ context, so ATOMIC is not needed here */ if (current_process != idle_proc) SCHED_ENQUEUE(current_process); - proc_schedule(); + preempt_schedule(); } /** @@ -200,18 +200,18 @@ void proc_preempt(void) * \warning This should be considered an internal kernel function, even if it * is allowed, usage from application code is strongly discouraged. */ -void proc_switch(void) +void preempt_switch(void) { ASSERT(proc_preemptAllowed()); IRQ_ASSERT_ENABLED(); - ATOMIC(proc_schedule()); + ATOMIC(preempt_schedule()); } /** * Voluntarily release the CPU. */ -void proc_yield(void) +void preempt_yield(void) { /* * Voluntary preemption while preemption is disabled is considered @@ -224,7 +224,7 @@ void proc_yield(void) ATOMIC( SCHED_ENQUEUE(current_process); - proc_schedule(); + preempt_schedule(); ); } diff --git a/bertos/kern/preempt.h b/bertos/kern/preempt.h index 49e6c437..9688e6c3 100644 --- a/bertos/kern/preempt.h +++ b/bertos/kern/preempt.h @@ -41,10 +41,6 @@ #include #if CONFIG_KERN_PREEMPT - void preempt_init(void); - void proc_preempt(void); - int proc_needPreempt(void); - INLINE void proc_decQuantum(void) { extern int _proc_quantum; diff --git a/bertos/kern/proc.c b/bertos/kern/proc.c index 713c457f..c422e729 100644 --- a/bertos/kern/proc.c +++ b/bertos/kern/proc.c @@ -139,10 +139,7 @@ void proc_init(void) monitor_init(); monitor_add(current_process, "main"); #endif - -#if CONFIG_KERN_PREEMPT - preempt_init(); -#endif + proc_schedInit(); MOD_INIT(proc); } diff --git a/bertos/kern/proc.h b/bertos/kern/proc.h index c78735e8..842566b9 100644 --- a/bertos/kern/proc.h +++ b/bertos/kern/proc.h @@ -37,7 +37,7 @@ * * $WIZ$ module_name = "kernel" * $WIZ$ module_configuration = "bertos/cfg/cfg_proc.h" - * $WIZ$ module_depends = "switch_ctx", "mtask" + * $WIZ$ module_depends = "switch_ctx", "coop", "preempt" * $WIZ$ module_supports = "not atmega103" */ @@ -54,6 +54,7 @@ #if CONFIG_KERN_PREEMPT #include // ASSERT() + #include #endif #include // cpu_stack_t @@ -142,15 +143,44 @@ struct Process *proc_new_with_name(const char *name, void (*entry)(void), iptr_t void proc_exit(void); /** - * Co-operative context switch. - * - * The process that calls this function will release the CPU before its cpu quantum - * expires, the scheduler will run to select the next process that will take control - * of the processor. - * \note This function is available only if CONFIG_KERN is enabled - * \sa cpu_relax(), which is the recommended method to release the cpu. + * Public scheduling class methods. */ void proc_yield(void); +void proc_preempt(void); +int proc_needPreempt(void); + +/** + * Dummy function that defines unimplemented scheduler class methods. + */ +INLINE void __proc_noop(void) +{ +} + +#if CONFIG_KERN_PREEMPT + /** + * Preemptive scheduler public methods. + */ + #define preempt_yield proc_yield + #define preempt_needPreempt proc_needPreempt + #define preempt_preempt proc_preempt + /** + * Preemptive scheduler: private methods. + */ + #define preempt_switch proc_switch + #define preempt_init proc_schedInit +#else + /** + * Co-operative scheduler: public methods. + */ + #define coop_yield proc_yield + #define proc_needPreempt __proc_noop + #define proc_preempt __proc_noop + /** + * Co-operative scheduler: private methods. + */ + #define coop_switch proc_switch + #define proc_schedInit __proc_noop +#endif void proc_rename(struct Process *proc, const char *name); const char *proc_name(struct Process *proc); diff --git a/bertos/kern/proc_p.h b/bertos/kern/proc_p.h index f1b5aa34..5d106242 100644 --- a/bertos/kern/proc_p.h +++ b/bertos/kern/proc_p.h @@ -145,10 +145,15 @@ INLINE void sched_reenqueue(struct Process *proc) } #endif //CONFIG_KERN_PRI -/// Schedule another process *without* adding the current one to the ready list. -void proc_switch(void); +/* Process trampoline */ void proc_entry(void); +/* Schedule another process *without* adding the current one to the ready list. */ +void proc_switch(void); + +/* Initialize a scheduler class. */ +void proc_schedInit(void); + #if CONFIG_KERN_MONITOR /** Initialize the monitor */ void monitor_init(void); diff --git a/examples/at91sam7/at91sam7s.mk b/examples/at91sam7/at91sam7s.mk index 532a326c..c3beda99 100644 --- a/examples/at91sam7/at91sam7s.mk +++ b/examples/at91sam7/at91sam7s.mk @@ -28,7 +28,8 @@ at91sam7s_CSRC = \ bertos/mware/sprintf.c \ bertos/kern/kfile.c \ bertos/kern/proc.c \ - bertos/kern/mtask.c \ + bertos/kern/coop.c \ + bertos/kern/preempt.c \ bertos/kern/idle.c \ bertos/kern/proc_test.c \ bertos/kern/monitor.c \ diff --git a/examples/at91sam7/at91sam7x.mk b/examples/at91sam7/at91sam7x.mk index 2ddbef29..d5d1871c 100644 --- a/examples/at91sam7/at91sam7x.mk +++ b/examples/at91sam7/at91sam7x.mk @@ -29,7 +29,8 @@ at91sam7x_CSRC = \ bertos/struct/heap.c \ bertos/kern/kfile.c \ bertos/kern/proc.c \ - bertos/kern/mtask.c \ + bertos/kern/coop.c \ + bertos/kern/preempt.c \ bertos/kern/idle.c \ bertos/kern/proc_test.c \ bertos/kern/monitor.c \ diff --git a/examples/demo/demo.mk b/examples/demo/demo.mk index 45ccdb36..d74afe13 100644 --- a/examples/demo/demo.mk +++ b/examples/demo/demo.mk @@ -57,7 +57,8 @@ demo_CSRC = \ bertos/mware/sprintf.c \ bertos/struct/heap.c \ bertos/kern/idle.c \ - bertos/kern/mtask.c \ + bertos/kern/coop.c \ + bertos/kern/preempt.c \ bertos/kern/irq.c \ bertos/kern/proc.c \ bertos/kern/proc_test.c \ diff --git a/test/get_source_list.sh b/test/get_source_list.sh index 93c2defd..c17fe74a 100755 --- a/test/get_source_list.sh +++ b/test/get_source_list.sh @@ -51,7 +51,7 @@ if [ $# \< 2 ] ; then fi CPU_TARGET=$1 EXCLUDE_DIRS="$COPY_DIR $CPU_DIR $APP_DIR $OS_DIR $WIZARD_DIR $EMUL_DIR $FAT_DIR $NMEA_DIR" -EXCLUDE_CMD="\.svn -or -name preempt.c -or -name coop.c -prune " +EXCLUDE_CMD="\.svn -prune " for i in $EXCLUDE_DIRS; do EXCLUDE_CMD="$EXCLUDE_CMD -o -path $i -prune "; done diff --git a/test/run_tests.sh b/test/run_tests.sh index 367b98bb..7c6a9d8c 100755 --- a/test/run_tests.sh +++ b/test/run_tests.sh @@ -40,7 +40,8 @@ SRC_LIST=" bertos/kern/proc.c bertos/kern/signal.c bertos/kern/sem.c - bertos/kern/mtask.c + bertos/kern/coop.c + bertos/kern/preempt.c bertos/mware/event.c bertos/mware/formatwr.c bertos/mware/hex.c -- 2.25.1