X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=kern%2Fproc.c;h=e25cb7dd92c2d755ba58a0be4f1f2d94a428a456;hb=00e009957d70dab15575ab310ed83f0b78cc8656;hp=db3cf50dab18236ab964aec533ce10ff0b7925fc;hpb=374f1e0d9aec91280946088b6c6c2f12af849734;p=bertos.git diff --git a/kern/proc.c b/kern/proc.c index db3cf50d..e25cb7dd 100755 --- a/kern/proc.c +++ b/kern/proc.c @@ -17,6 +17,24 @@ /*#* *#* $Log$ + *#* Revision 1.21 2004/11/28 23:20:25 bernie + *#* Remove obsolete INITLIST macro. + *#* + *#* Revision 1.20 2004/11/16 22:37:14 bernie + *#* Replace IPTR with iptr_t. + *#* + *#* Revision 1.19 2004/10/19 11:47:39 bernie + *#* Kill warnings when !CONFIG_PROC_MONITOR. + *#* + *#* Revision 1.18 2004/10/19 08:54:43 bernie + *#* Initialize forbid_cnt; Formatting/comments fixes. + *#* + *#* Revision 1.17 2004/10/19 08:47:13 bernie + *#* proc_rename(), proc_forbid(), proc_permit(): New functions. + *#* + *#* Revision 1.16 2004/10/03 20:39:28 bernie + *#* Import changes from sc/firmware. + *#* *#* Revision 1.15 2004/09/20 03:29:39 bernie *#* C++ fixes. *#* @@ -106,109 +124,23 @@ uint16_t Quantum; extern List StackFreeList; #endif -/* The main process (the one that executes main()) */ +/*! The main process (the one that executes main()). */ struct Process MainProcess; -#if CONFIG_KERN_MONITOR -List MonitorProcs; - -static void monitor_init(void) -{ - INITLIST(&MonitorProcs); -} - -static void monitor_add(Process* proc, const char* name, cpustack_t* stack_base, size_t stack_size) -{ - proc->monitor.name = name; - proc->monitor.stack_base = stack_base; - proc->monitor.stack_size = stack_size; - - ADDTAIL(&MonitorProcs, &proc->monitor.link); -} - -static void monitor_remove(Process* proc) -{ - REMOVE(&proc->monitor.link); -} - -#define MONITOR_NODE_TO_PROCESS(node) \ - (struct Process*)((char*)(node) - offsetof(struct Process, monitor.link)) - -size_t monitor_check_stack(cpustack_t* stack_base, size_t stack_size) +static void proc_init_struct(Process *proc) { - cpustack_t* beg; - cpustack_t* cur; - cpustack_t* end; - size_t sp_free; - - beg = stack_base; - end = stack_base + stack_size / sizeof(cpustack_t) - 1; - - if (CPU_STACK_GROWS_UPWARD) - { - cur = beg; - beg = end; - end = cur; - } - - cur = beg; - while (cur != end) - { - if (*cur != CONFIG_KERN_STACKFILLCODE) - break; - - if (CPU_STACK_GROWS_UPWARD) - cur--; - else - cur++; - } - - sp_free = ABS(cur - beg) * sizeof(cpustack_t); - return sp_free; -} - -#if CONFIG_KERN_MONITOR - -void monitor_debug_stacks(void) -{ - struct Process* p; - int i; - - if (ISLISTEMPTY(&MonitorProcs)) - { - kputs("No stacks registered in the monitor\n"); - return; - } - - kprintf("%-24s %-6s%-8s%-8s%-8s\n", "Process name", "TCB", "SPbase", "SPsize", "SPfree"); - for (i=0;i<56;i++) - kputchar('-'); - kputchar('\n'); - - for (p = MONITOR_NODE_TO_PROCESS(MonitorProcs.head); - p->monitor.link.succ; - p = MONITOR_NODE_TO_PROCESS(p->monitor.link.succ)) - { - size_t free = monitor_check_stack(p->monitor.stack_base, p->monitor.stack_size); - kprintf("%-24s %04x %04x %4x %4x\n", p->monitor.name, (uint16_t)p, (uint16_t)p->monitor.stack_base, (uint16_t)p->monitor.stack_size, (uint16_t)free); - } -} - -#endif /* CONFIG_KERN_MONITOR */ - -#endif - - -static void proc_init_struct(Process* proc) -{ - /* Avoid warning for unused argument */ + /* Avoid warning for unused argument. */ (void)proc; #if CONFIG_KERN_SIGNALS proc->sig_recv = 0; #endif +#if CONFIG_KERN_PREEMPTIVE + proc->forbid_cnt = 0; +#endif + #if CONFIG_KERN_HEAP proc->flags = 0; #endif @@ -217,7 +149,7 @@ static void proc_init_struct(Process* proc) void proc_init(void) { - INITLIST(&ProcReadyList); + LIST_INIT(&ProcReadyList); #if CONFIG_KERN_MONITOR monitor_init(); @@ -241,7 +173,7 @@ void proc_init(void) * \return Process structure of new created process * if successful, NULL otherwise. */ -struct Process *proc_new_with_name(UNUSED(const char*, name), void (*entry)(void), IPTR data, size_t stacksize, cpustack_t *stack_base) +struct Process *proc_new_with_name(UNUSED(const char*, name), void (*entry)(void), iptr_t data, size_t stacksize, cpustack_t *stack_base) { Process *proc; cpuflags_t flags; @@ -252,9 +184,7 @@ struct Process *proc_new_with_name(UNUSED(const char*, name), void (*entry)(void #endif #if (ARCH & ARCH_EMUL) - /* Ignore stack provided by caller - * and use the large enough default instead - */ + /* Ignore stack provided by caller and use the large enough default instead. */ stack_base = (cpustack_t *)StackFreeList.head; REMOVE((Node *)stack_base); stacksize = DEF_STACKSIZE; @@ -329,6 +259,16 @@ struct Process *proc_new_with_name(UNUSED(const char*, name), void (*entry)(void return proc; } +/*! Rename a process */ +void proc_rename(struct Process *proc, const char *name) +{ +#if CONFIG_KERN_MONITOR + monitor_rename(proc, name); +#else + (void)proc; (void)name; +#endif +} + /*! * System scheduler: pass CPU control to the next process in @@ -462,13 +402,52 @@ struct Process *proc_current(void) /*! * Get the pointer to the user data of the current process */ -IPTR proc_current_user_data(void) +iptr_t proc_current_user_data(void) { return CurrentProcess->user_data; } + +#if CONFIG_KERN_PREEMPTIVE + +/*! + * Disable preemptive task switching. + * + * The scheduler maintains a per-process nesting counter. Task switching is + * effectively re-enabled only when the number of calls to proc_permit() + * matches the number of calls to proc_forbid(). + * + * Calling functions that could sleep while task switching is disabled + * is dangerous, although supported. Preemptive task switching is + * resumed while the process is sleeping and disabled again as soon as + * it wakes up again. + * + * \sa proc_permit() + */ +void proc_forbid(void) +{ + /* No need to protect against interrupts here. */ + ++CurrentProcess->forbid_cnt; +} + +/*! + * Re-enable preemptive task switching. + * + * \sa proc_forbid() + */ +void proc_permit(void) +{ + /* No need to protect against interrupts here. */ + --CurrentProcess->forbid_cnt; +} + +#endif /* CONFIG_KERN_PREEMPTIVE */ + + #if 0 /* Simple testcase for the scheduler */ +#include + /*! * Proc scheduling test subthread 1 */