proc_p.h

Go to the documentation of this file.
00001 
00039 #ifndef KERN_PROC_P_H
00040 #define KERN_PROC_P_H
00041 
00042 #include "cfg/cfg_proc.h"
00043 #include "cfg/cfg_monitor.h"
00044 
00045 #include <cfg/compiler.h>
00046 
00047 #include <cpu/types.h>        /* for cpu_stack_t */
00048 #include <cpu/irq.h>          // IRQ_ASSERT_DISABLED()
00049 
00050 #include <kern/proc.h>   // struct Process
00051 
00052 #ifndef asm_switch_context
00053 
00059 EXTERN_C void asm_switch_context(cpu_stack_t **new_sp, cpu_stack_t **save_sp);
00060 #endif
00061 
00066 #define PF_FREESTACK  BV(0)  
00067 /*\}*/
00068 
00069 
00071 extern REGISTER Process *current_process;
00072 
00078 extern REGISTER List     proc_ready_list;
00079 
00080 #if CONFIG_KERN_PRI
00081 # if CONFIG_KERN_PRI_INHERIT
00082     #define __prio_orig(proc) (proc->orig_pri)
00083     #define __prio_inh(proc) (LIST_EMPTY(&(proc)->inh_list) ? INT_MIN : \
00084                     ((PriNode *)LIST_HEAD(&proc->inh_list))->pri)
00085     #define __prio_proc(proc) (__prio_inh(proc) > __prio_orig(proc) ? \
00086                     __prio_inh(proc) : __prio_orig(proc))
00087 # endif
00088     #define prio_next() (LIST_EMPTY(&proc_ready_list) ? INT_MIN : \
00089                     ((PriNode *)LIST_HEAD(&proc_ready_list))->pri)
00090     #define prio_proc(proc) (proc->link.pri)
00091     #define prio_curr() prio_proc(current_process)
00092 
00093     #define SCHED_ENQUEUE_INTERNAL(proc) \
00094             LIST_ENQUEUE(&proc_ready_list, &(proc)->link)
00095     #define SCHED_ENQUEUE_HEAD_INTERNAL(proc) \
00096             LIST_ENQUEUE_HEAD(&proc_ready_list, &(proc)->link)
00097 #else
00098     #define prio_next() 0
00099     #define prio_proc(proc) 0
00100     #define prio_curr() 0
00101 
00102     #define SCHED_ENQUEUE_INTERNAL(proc) ADDTAIL(&proc_ready_list, &(proc)->link)
00103     #define SCHED_ENQUEUE_HEAD_INTERNAL(proc) ADDHEAD(&proc_ready_list, &(proc)->link)
00104 #endif
00105 
00115 #define SCHED_ENQUEUE(proc)  do { \
00116         IRQ_ASSERT_DISABLED(); \
00117         LIST_ASSERT_VALID(&proc_ready_list); \
00118         SCHED_ENQUEUE_INTERNAL(proc); \
00119     } while (0)
00120 
00121 #define SCHED_ENQUEUE_HEAD(proc)  do { \
00122         IRQ_ASSERT_DISABLED(); \
00123         LIST_ASSERT_VALID(&proc_ready_list); \
00124         SCHED_ENQUEUE_HEAD_INTERNAL(proc); \
00125     } while (0)
00126 
00127 
00128 #if CONFIG_KERN_PRI
00129 
00139 INLINE void sched_reenqueue(struct Process *proc)
00140 {
00141     IRQ_ASSERT_DISABLED();
00142     LIST_ASSERT_VALID(&proc_ready_list);
00143     Node *n;
00144     PriNode *pos = NULL;
00145     FOREACH_NODE(n, &proc_ready_list)
00146     {
00147         if (n == &proc->link.link)
00148         {
00149             pos = (PriNode *)n;
00150             break;
00151         }
00152     }
00153 
00154     // only remove and enqueue again if process is already in the ready list
00155     // otherwise leave it alone
00156     if (pos)
00157     {
00158         REMOVE(&proc->link.link);
00159         LIST_ENQUEUE(&proc_ready_list, &proc->link);
00160     }
00161 }
00162 #endif //CONFIG_KERN_PRI
00163 
00164 /* Process trampoline */
00165 void proc_entry(void);
00166 
00167 /* Schedule another process *without* adding the current one to the ready list. */
00168 void proc_switch(void);
00169 
00170 /* Immediately schedule a particular process bypassing the scheduler. */
00171 void proc_wakeup(Process *proc);
00172 
00173 /* Initialize a scheduler class. */
00174 void proc_schedInit(void);
00175 
00176 #if CONFIG_KERN_MONITOR
00177 
00178     void monitor_init(void);
00179 
00181     void monitor_add(Process *proc, const char *name);
00182 
00184     void monitor_remove(Process *proc);
00185 
00187     void monitor_rename(Process *proc, const char *name);
00188 #endif /* CONFIG_KERN_MONITOR */
00189 
00190 /*
00191  * Quantum related macros are used in the
00192  * timer module and must be empty when
00193  * kernel is disabled.
00194  */
00195 #if (CONFIG_KERN && CONFIG_KERN_PREEMPT)
00196 INLINE int preempt_quantum(void)
00197 {
00198     extern int _proc_quantum;
00199     return _proc_quantum;
00200 }
00201 
00202 INLINE void proc_decQuantum(void)
00203 {
00204     extern int _proc_quantum;
00205     if (_proc_quantum > 0)
00206         _proc_quantum--;
00207 }
00208 
00209 INLINE void preempt_reset_quantum(void)
00210 {
00211     extern int _proc_quantum;
00212     _proc_quantum = CONFIG_KERN_QUANTUM;
00213 }
00214 #else /* !(CONFIG_KERN && CONFIG_KERN_PREEMPT) */
00215 INLINE int preempt_quantum(void)
00216 {
00217     return 0;
00218 }
00219 
00220 INLINE void proc_decQuantum(void)
00221 {
00222 }
00223 
00224 INLINE void preempt_reset_quantum(void)
00225 {
00226 }
00227 #endif /* (CONFIG_KERN && CONFIG_KERN_PREEMPT) */
00228 
00229 #endif /* KERN_PROC_P_H */