/*#*
*#* $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.
*#*
extern List StackFreeList;
#endif
-/* The main process (the one that executes main()) */
+/*! The main process (the one that executes main()). */
struct Process MainProcess;
-static void proc_init_struct(Process* proc)
+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
void proc_init(void)
{
- INITLIST(&ProcReadyList);
+ LIST_INIT(&ProcReadyList);
#if CONFIG_KERN_MONITOR
monitor_init();
* \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;
#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;
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
/*!
* 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 <drv/timer.h>