X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fkern%2Fproc.h;h=19bb5efaa23a4ec10338382ff61de286b238cc55;hb=97e93eec653e38a04e94e5191bdbf5ea48edde96;hp=8570d801edf39d017ee985ceb2f20187b2a0b6ab;hpb=32d1445272120a254d77ce8d1af1f527da7a2c17;p=bertos.git diff --git a/bertos/kern/proc.h b/bertos/kern/proc.h index 8570d801..19bb5efa 100644 --- a/bertos/kern/proc.h +++ b/bertos/kern/proc.h @@ -30,14 +30,62 @@ * Copyright 1999, 2000, 2001, 2008 Bernie Innocenti * --> * + * \defgroup kern_proc Process (Threads) management + * \ingroup kern + * \{ + * * \brief BeRTOS Kernel core (Process scheduler). * - * \version $Id$ + * This is the core kernel module. It allows you to create new processes + * (which are called \b threads in other systems) and set the priority of + * each process. + * + * A process needs a work area (called \b stack) to run. To create a process, + * you need to declare a stack area, then create the process. + * You may also pass NULL for the stack area, if you have enabled kernel heap: + * in this case the stack will be automatically allocated. + * + * Example: + * \code + * PROC_DEFINE_STACK(stack1, 200); + * + * void NORETURN proc1_run(void) + * { + * while (1) + * { + * LOG_INFO("I'm alive!\n"); + * timer_delay(1000); + * } + * } + * + * + * int main() + * { + * Process *p1 = proc_new(proc1_run, NULL, stack1, sizeof(stack1)); + * // here the process is already running + * proc_setPri(p1, 2); + * // ... + * } + * \endcode + * + * The Process struct must be regarded as an opaque data type, do not access + * any of its members directly. + * + * The entry point function should be declared as NORETURN, because it will + * remove a warning and enable compiler optimizations. + * + * You can temporarily disable preemption calling proc_forbid(); remember + * to enable it again calling proc_permit(). + * + * \note You should hardly need to manually release the CPU; however you + * can do it using the cpu_relax() function. It is illegal to release + * the CPU with preemption disabled. + * * \author Bernie Innocenti * * $WIZ$ module_name = "kernel" * $WIZ$ module_configuration = "bertos/cfg/cfg_proc.h" - * $WIZ$ module_depends = "switch_ctx", "mtask" + * $WIZ$ module_depends = "switch_ctx" * $WIZ$ module_supports = "not atmega103" */ @@ -47,18 +95,23 @@ #include "cfg/cfg_proc.h" #include "cfg/cfg_signal.h" #include "cfg/cfg_monitor.h" +#include "sem.h" #include // Node, PriNode #include - -#if CONFIG_KERN_PREEMPT - #include // ASSERT() -#endif +#include // ASSERT() #include // cpu_stack_t #include // CPU_SAVED_REGS_CNT +/* The following silents warnings on nightly tests. We need to regenerate + * all the projects before this can be removed. + */ +#ifndef CONFIG_KERN_PRI_INHERIT +#define CONFIG_KERN_PRI_INHERIT 0 +#endif + /* * WARNING: struct Process is considered private, so its definition can change any time * without notice. DO NOT RELY on any field defined here, use only the interface @@ -70,6 +123,12 @@ typedef struct Process { #if CONFIG_KERN_PRI PriNode link; /**< Link Process into scheduler lists */ +# if CONFIG_KERN_PRI_INHERIT + PriNode inh_link; /**< Link Process into priority inheritance lists */ + List inh_list; /**< Priority inheritance list for this Process */ + Semaphore *inh_blocked_by; /**< Semaphore blocking this Process */ + int orig_pri; /**< Process priority without considering inheritance */ +# endif #else Node link; /**< Link Process into scheduler lists */ #endif @@ -77,8 +136,7 @@ typedef struct Process iptr_t user_data; /**< Custom data passed to the process */ #if CONFIG_KERN_SIGNALS - sigmask_t sig_wait; /**< Signals the process is waiting for */ - sigmask_t sig_recv; /**< Received signals */ + Signal sig; #endif #if CONFIG_KERN_HEAP @@ -141,17 +199,25 @@ 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); +#if CONFIG_KERN_PREEMPT +bool proc_needPreempt(void); +void proc_preempt(void); +#else +INLINE bool proc_needPreempt(void) +{ + return false; +} + +INLINE void proc_preempt(void) +{ +} +#endif + void proc_rename(struct Process *proc, const char *name); const char *proc_name(struct Process *proc); const char *proc_currentName(void); @@ -163,7 +229,11 @@ const char *proc_currentName(void); * the returned pointer to the correct type. * \return Pointer to the user data of the current process. */ -iptr_t proc_currentUserData(void); +INLINE iptr_t proc_currentUserData(void) +{ + extern struct Process *current_process; + return current_process->user_data; +} int proc_testSetup(void); int proc_testRun(void); @@ -184,10 +254,20 @@ INLINE struct Process *proc_current(void) #if CONFIG_KERN_PRI void proc_setPri(struct Process *proc, int pri); + + INLINE int proc_pri(struct Process *proc) + { + return proc->link.pri; + } #else INLINE void proc_setPri(UNUSED_ARG(struct Process *,proc), UNUSED_ARG(int, pri)) { } + + INLINE int proc_pri(UNUSED_ARG(struct Process *, proc)) + { + return 0; + } #endif #if CONFIG_KERN_PREEMPT @@ -363,7 +443,7 @@ INLINE struct Process *proc_current(void) */ #define PROC_DEFINE_STACK(name, size) \ cpu_stack_t name[((size) + sizeof(cpu_stack_t) - 1) / sizeof(cpu_stack_t)]; \ - STATIC_ASSERT((size) >= KERN_MINSTACKSIZE) + STATIC_ASSERT((size) >= KERN_MINSTACKSIZE); /* Memory fill codes to help debugging */ #if CONFIG_KERN_MONITOR @@ -388,5 +468,6 @@ INLINE struct Process *proc_current(void) #error No cpu_stack_t size supported! #endif #endif +/** \} */ //defgroup kern_proc #endif /* KERN_PROC_H */