proc.h
Go to the documentation of this file.00001
00044 #ifndef KERN_PROC_H
00045 #define KERN_PROC_H
00046
00047 #include "cfg/cfg_proc.h"
00048 #include "cfg/cfg_signal.h"
00049 #include "cfg/cfg_monitor.h"
00050
00051 #include <struct/list.h>
00052
00053 #include <cfg/compiler.h>
00054
00055 #if CONFIG_KERN_PREEMPT
00056 #include <cfg/debug.h>
00057 #include <kern/preempt.h>
00058 #endif
00059
00060 #include <cpu/types.h>
00061 #include <cpu/frame.h>
00062
00063
00064
00065
00066
00067
00068
00069
00070 typedef struct Process
00071 {
00072 #if CONFIG_KERN_PRI
00073 PriNode link;
00074 #else
00075 Node link;
00076 #endif
00077 cpu_stack_t *stack;
00078 iptr_t user_data;
00080 #if CONFIG_KERN_SIGNALS
00081 sigmask_t sig_wait;
00082 sigmask_t sig_recv;
00083 #endif
00084
00085 #if CONFIG_KERN_HEAP
00086 uint16_t flags;
00087 #endif
00088
00089 #if CONFIG_KERN_HEAP | CONFIG_KERN_MONITOR
00090 cpu_stack_t *stack_base;
00091 size_t stack_size;
00092 #endif
00093
00094
00095 void (*user_entry)(void);
00096
00097 #if CONFIG_KERN_MONITOR
00098 struct ProcMonitor
00099 {
00100 Node link;
00101 const char *name;
00102 } monitor;
00103 #endif
00104
00105 } Process;
00106
00111 void proc_init(void);
00112
00113 struct Process *proc_new_with_name(const char *name, void (*entry)(void), iptr_t data, size_t stacksize, cpu_stack_t *stack);
00114
00115 #if !CONFIG_KERN_MONITOR
00116
00135 #define proc_new(entry,data,size,stack) proc_new_with_name(NULL,(entry),(data),(size),(stack))
00136 #else
00137 #define proc_new(entry,data,size,stack) proc_new_with_name(#entry,(entry),(data),(size),(stack))
00138 #endif
00139
00143 void proc_exit(void);
00144
00148 void proc_yield(void);
00149 void proc_preempt(void);
00150 int proc_needPreempt(void);
00151 void proc_wakeup(Process *proc);
00152
00156 INLINE void __proc_noop(void)
00157 {
00158 }
00159
00160 #if CONFIG_KERN_PREEMPT
00161
00164 #define preempt_yield proc_yield
00165 #define preempt_needPreempt proc_needPreempt
00166 #define preempt_preempt proc_preempt
00167
00170 #define preempt_switch proc_switch
00171 #define preempt_wakeup proc_wakeup
00172 #else
00173
00176 #define coop_yield proc_yield
00177 #define proc_needPreempt __proc_noop
00178 #define proc_preempt __proc_noop
00179
00182 #define coop_switch proc_switch
00183 #define coop_wakeup proc_wakeup
00184 #endif
00185
00186 void proc_rename(struct Process *proc, const char *name);
00187 const char *proc_name(struct Process *proc);
00188 const char *proc_currentName(void);
00189
00197 INLINE iptr_t proc_currentUserData(void)
00198 {
00199 extern struct Process *current_process;
00200 return current_process->user_data;
00201 }
00202
00203 int proc_testSetup(void);
00204 int proc_testRun(void);
00205 int proc_testTearDown(void);
00206
00214 INLINE struct Process *proc_current(void)
00215 {
00216 extern struct Process *current_process;
00217 return current_process;
00218 }
00219
00220 #if CONFIG_KERN_PRI
00221 void proc_setPri(struct Process *proc, int pri);
00222 #else
00223 INLINE void proc_setPri(UNUSED_ARG(struct Process *,proc), UNUSED_ARG(int, pri))
00224 {
00225 }
00226 #endif
00227
00228 #if CONFIG_KERN_PREEMPT
00229
00247 INLINE void proc_forbid(void)
00248 {
00249 extern cpu_atomic_t preempt_count;
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 ++preempt_count;
00274
00275
00276
00277
00278
00279 MEMORY_BARRIER;
00280 }
00281
00287 INLINE void proc_permit(void)
00288 {
00289 extern cpu_atomic_t preempt_count;
00290
00291
00292
00293
00294
00295 MEMORY_BARRIER;
00296
00297 ASSERT(preempt_count > 0);
00298 --preempt_count;
00299
00300
00301
00302
00303 MEMORY_BARRIER;
00304 }
00305
00311 INLINE bool proc_preemptAllowed(void)
00312 {
00313 extern cpu_atomic_t preempt_count;
00314 return (preempt_count == 0);
00315 }
00316 #else
00317 #define proc_forbid()
00318 #define proc_permit()
00319 #define proc_preemptAllowed() (true)
00320 #endif
00321
00323 #define proc_allowed() proc_preemptAllowed()
00324
00328 #define PROC_ATOMIC(CODE) \
00329 do { \
00330 proc_forbid(); \
00331 CODE; \
00332 proc_permit(); \
00333 } while(0)
00334
00353 #if (ARCH & ARCH_EMUL)
00354
00355 #define KERN_MINSTACKSIZE 65536
00356 #else
00357 #if CONFIG_KERN_PREEMPT
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 #define KERN_MINSTACKSIZE \
00371 (sizeof(Process) + CPU_SAVED_REGS_CNT * 2 * sizeof(cpu_stack_t) \
00372 + 32 * sizeof(int) * 2)
00373 #else
00374 #define KERN_MINSTACKSIZE \
00375 (sizeof(Process) + CPU_SAVED_REGS_CNT * 2 * sizeof(cpu_stack_t) \
00376 + 32 * sizeof(int))
00377 #endif
00378
00379 #endif
00380
00381 #ifndef CONFIG_KERN_MINSTACKSIZE
00382
00383 #define CONFIG_KERN_MINSTACKSIZE KERN_MINSTACKSIZE
00384 #else
00385 #warning FIXME: This macro is deprecated, use KERN_MINSTACKSIZE instead
00386 #endif
00387
00399 #define PROC_DEFINE_STACK(name, size) \
00400 cpu_stack_t name[((size) + sizeof(cpu_stack_t) - 1) / sizeof(cpu_stack_t)]; \
00401 STATIC_ASSERT((size) >= KERN_MINSTACKSIZE);
00402
00403
00404 #if CONFIG_KERN_MONITOR
00405 #include <cpu/types.h>
00406 #if (SIZEOF_CPUSTACK_T == 1)
00407
00408 #define CONFIG_KERN_STACKFILLCODE 0xA5
00409 #define CONFIG_KERN_MEMFILLCODE 0xDB
00410 #elif (SIZEOF_CPUSTACK_T == 2)
00411
00412 #define CONFIG_KERN_STACKFILLCODE 0xA5A5
00413 #define CONFIG_KERN_MEMFILLCODE 0xDBDB
00414 #elif (SIZEOF_CPUSTACK_T == 4)
00415
00416 #define CONFIG_KERN_STACKFILLCODE 0xA5A5A5A5UL
00417 #define CONFIG_KERN_MEMFILLCODE 0xDBDBDBDBUL
00418 #elif (SIZEOF_CPUSTACK_T == 8)
00419
00420 #define CONFIG_KERN_STACKFILLCODE 0xA5A5A5A5A5A5A5A5ULL
00421 #define CONFIG_KERN_MEMFILLCODE 0xDBDBDBDBDBDBDBDBULL
00422 #else
00423 #error No cpu_stack_t size supported!
00424 #endif
00425 #endif
00426
00427 #endif