BeRTOS
|
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 #define prio_next() (LIST_EMPTY(&proc_ready_list) ? INT_MIN : \ 00082 ((PriNode *)LIST_HEAD(&proc_ready_list))->pri) 00083 #define prio_proc(proc) (proc->link.pri) 00084 #define prio_curr() prio_proc(current_process) 00085 00086 #define SCHED_ENQUEUE_INTERNAL(proc) \ 00087 LIST_ENQUEUE(&proc_ready_list, &(proc)->link) 00088 #define SCHED_ENQUEUE_HEAD_INTERNAL(proc) \ 00089 LIST_ENQUEUE_HEAD(&proc_ready_list, &(proc)->link) 00090 #else 00091 #define prio_next() 0 00092 #define prio_proc(proc) 0 00093 #define prio_curr() 0 00094 00095 #define SCHED_ENQUEUE_INTERNAL(proc) ADDTAIL(&proc_ready_list, &(proc)->link) 00096 #define SCHED_ENQUEUE_HEAD_INTERNAL(proc) ADDHEAD(&proc_ready_list, &(proc)->link) 00097 #endif 00098 00108 #define SCHED_ENQUEUE(proc) do { \ 00109 IRQ_ASSERT_DISABLED(); \ 00110 LIST_ASSERT_VALID(&proc_ready_list); \ 00111 SCHED_ENQUEUE_INTERNAL(proc); \ 00112 } while (0) 00113 00114 #define SCHED_ENQUEUE_HEAD(proc) do { \ 00115 IRQ_ASSERT_DISABLED(); \ 00116 LIST_ASSERT_VALID(&proc_ready_list); \ 00117 SCHED_ENQUEUE_HEAD_INTERNAL(proc); \ 00118 } while (0) 00119 00120 00121 #if CONFIG_KERN_PRI 00122 00132 INLINE void sched_reenqueue(struct Process *proc) 00133 { 00134 IRQ_ASSERT_DISABLED(); 00135 LIST_ASSERT_VALID(&proc_ready_list); 00136 Node *n; 00137 PriNode *pos = NULL; 00138 FOREACH_NODE(n, &proc_ready_list) 00139 { 00140 if (n == &proc->link.link) 00141 { 00142 pos = (PriNode *)n; 00143 break; 00144 } 00145 } 00146 00147 // only remove and enqueue again if process is already in the ready list 00148 // otherwise leave it alone 00149 if (pos) 00150 { 00151 REMOVE(&proc->link.link); 00152 LIST_ENQUEUE(&proc_ready_list, &proc->link); 00153 } 00154 } 00155 #endif //CONFIG_KERN_PRI 00156 00157 /* Process trampoline */ 00158 void proc_entry(void); 00159 00160 /* Schedule another process *without* adding the current one to the ready list. */ 00161 void proc_switch(void); 00162 00163 /* Immediately schedule a particular process bypassing the scheduler. */ 00164 void proc_wakeup(Process *proc); 00165 00166 /* Initialize a scheduler class. */ 00167 void proc_schedInit(void); 00168 00169 #if CONFIG_KERN_MONITOR 00170 00171 void monitor_init(void); 00172 00174 void monitor_add(Process *proc, const char *name); 00175 00177 void monitor_remove(Process *proc); 00178 00180 void monitor_rename(Process *proc, const char *name); 00181 #endif /* CONFIG_KERN_MONITOR */ 00182 00183 /* 00184 * Quantum related macros are used in the 00185 * timer module and must be empty when 00186 * kernel is disabled. 00187 */ 00188 #if (CONFIG_KERN && CONFIG_KERN_PREEMPT) 00189 INLINE int preempt_quantum(void) 00190 { 00191 extern int _proc_quantum; 00192 return _proc_quantum; 00193 } 00194 00195 INLINE void proc_decQuantum(void) 00196 { 00197 extern int _proc_quantum; 00198 if (_proc_quantum > 0) 00199 _proc_quantum--; 00200 } 00201 00202 INLINE void preempt_reset_quantum(void) 00203 { 00204 extern int _proc_quantum; 00205 _proc_quantum = CONFIG_KERN_QUANTUM; 00206 } 00207 #else /* !(CONFIG_KERN && CONFIG_KERN_PREEMPT) */ 00208 INLINE int preempt_quantum(void) 00209 { 00210 return 0; 00211 } 00212 00213 INLINE void proc_decQuantum(void) 00214 { 00215 } 00216 00217 INLINE void preempt_reset_quantum(void) 00218 { 00219 } 00220 #endif /* (CONFIG_KERN && CONFIG_KERN_PREEMPT) */ 00221 00222 #endif /* KERN_PROC_P_H */