proc_p.h

Go to the documentation of this file.
00001 
00040 #ifndef KERN_PROC_P_H
00041 #define KERN_PROC_P_H
00042 
00043 #include "cfg/cfg_proc.h"
00044 #include "cfg/cfg_monitor.h"
00045 
00046 #include <cfg/compiler.h>
00047 
00048 #include <cpu/types.h>        /* for cpu_stack_t */
00049 #include <cpu/irq.h>          // IRQ_ASSERT_DISABLED()
00050 
00051 #include <kern/proc.h>   // struct Process
00052 
00059 EXTERN_C void asm_switch_context(cpu_stack_t **new_sp, cpu_stack_t **save_sp);
00060 
00061 /*
00062  * Save context of old process and switch to new process.
00063   */
00064 INLINE void proc_switchTo(Process *next, Process *prev)
00065 {
00066     cpu_stack_t *dummy;
00067 
00068     if (UNLIKELY(next == prev))
00069         return;
00070     /*
00071      * If there is no old process, we save the old stack pointer into a
00072      * dummy variable that we ignore.  In fact, this happens only when the
00073      * old process has just exited.
00074      */
00075     asm_switch_context(&next->stack, prev ? &prev->stack : &dummy);
00076 }
00077 
00082 #define PF_FREESTACK  BV(0)  
00083 /*\}*/
00084 
00085 
00087 extern REGISTER Process *current_process;
00088 
00094 extern REGISTER List     proc_ready_list;
00095 
00096 #if CONFIG_KERN_PRI
00097     #define prio_next() (LIST_EMPTY(&proc_ready_list) ? INT_MIN : \
00098                     ((PriNode *)LIST_HEAD(&proc_ready_list))->pri)
00099     #define prio_proc(proc) (proc->link.pri)
00100     #define prio_curr() prio_proc(current_process)
00101 
00102     #define SCHED_ENQUEUE_INTERNAL(proc) \
00103             LIST_ENQUEUE(&proc_ready_list, &(proc)->link)
00104     #define SCHED_ENQUEUE_HEAD_INTERNAL(proc) \
00105             LIST_ENQUEUE_HEAD(&proc_ready_list, &(proc)->link)
00106 #else
00107     #define prio_next() 0
00108     #define prio_proc(proc) 0
00109     #define prio_curr() 0
00110 
00111     #define SCHED_ENQUEUE_INTERNAL(proc) ADDTAIL(&proc_ready_list, &(proc)->link)
00112     #define SCHED_ENQUEUE_HEAD_INTERNAL(proc) ADDHEAD(&proc_ready_list, &(proc)->link)
00113 #endif
00114 
00124 #define SCHED_ENQUEUE(proc)  do { \
00125         IRQ_ASSERT_DISABLED(); \
00126         LIST_ASSERT_VALID(&proc_ready_list); \
00127         SCHED_ENQUEUE_INTERNAL(proc); \
00128     } while (0)
00129 
00130 #define SCHED_ENQUEUE_HEAD(proc)  do { \
00131         IRQ_ASSERT_DISABLED(); \
00132         LIST_ASSERT_VALID(&proc_ready_list); \
00133         SCHED_ENQUEUE_HEAD_INTERNAL(proc); \
00134     } while (0)
00135 
00136 
00137 #if CONFIG_KERN_PRI
00138 
00148 INLINE void sched_reenqueue(struct Process *proc)
00149 {
00150     IRQ_ASSERT_DISABLED();
00151     LIST_ASSERT_VALID(&proc_ready_list);
00152     Node *n;
00153     PriNode *pos = NULL;
00154     FOREACH_NODE(n, &proc_ready_list)
00155     {
00156         if (n == &proc->link.link)
00157         {
00158             pos = (PriNode *)n;
00159             break;
00160         }
00161     }
00162 
00163     // only remove and enqueue again if process is already in the ready list
00164     // otherwise leave it alone
00165     if (pos)
00166     {
00167         REMOVE(&proc->link.link);
00168         LIST_ENQUEUE(&proc_ready_list, &proc->link);
00169     }
00170 }
00171 #endif //CONFIG_KERN_PRI
00172 
00173 /* Process trampoline */
00174 void proc_entry(void);
00175 
00176 /* Schedule another process *without* adding the current one to the ready list. */
00177 void proc_switch(void);
00178 
00179 /* Low level scheduling routine. */
00180 void proc_schedule(void);
00181 
00182 /* Low level context switch routine. */
00183 void proc_switchTo(Process *next, Process *prev);
00184 
00185 /* Initialize a scheduler class. */
00186 void proc_schedInit(void);
00187 
00188 #if CONFIG_KERN_MONITOR
00189 
00190     void monitor_init(void);
00191 
00193     void monitor_add(Process *proc, const char *name);
00194 
00196     void monitor_remove(Process *proc);
00197 
00199     void monitor_rename(Process *proc, const char *name);
00200 #endif /* CONFIG_KERN_MONITOR */
00201 
00202 #endif /* KERN_PROC_P_H */