Remove plenty of legacy names marked as OBSOLETE
[bertos.git] / bertos / kern / proc.c
index c3d89b4315d499048b1a859e044dd7c2b6f61305..577f0db43e2d8a6925b55e09229c5461d69a715d 100644 (file)
@@ -44,6 +44,7 @@
 #include "cfg/cfg_arch.h"  /* ARCH_EMUL */
 #include "cfg/cfg_kern.h"
 #include <cfg/module.h>
+#include <cfg/depend.h>    // CONFIG_DEPEND()
 
 #include <cpu/irq.h>
 #include <cpu/types.h>
 
 #include <string.h>           /* memset() */
 
+// Check config dependencies
+CONFIG_DEPEND(CONFIG_KERN_SIGNALS,    CONFIG_KERN_SCHED);
+CONFIG_DEPEND(CONFIG_KERN_SEMAPHORES, CONFIG_KERN_SIGNALS);
+CONFIG_DEPEND(CONFIG_KERN_MONITOR,    CONFIG_KERN_SCHED);
+
 
 /*
  * The scheduer tracks ready processes by enqueuing them in the
@@ -70,11 +76,16 @@ REGISTER Process *CurrentProcess;
 
 #if (ARCH & ARCH_EMUL)
 /*
- * In hosted environments, we must emulate the stack on the real process stack.
+ * In some hosted environments, we must emulate the stack on the real
+ * process stack to satisfy consistency checks in system libraries and
+ * because some ABIs place trampolines on the stack.
  *
  * Access to this list must be protected by PROC_ATOMIC().
  */
-extern List StackFreeList;
+List StackFreeList;
+
+#define NPROC 8
+cpustack_t proc_stacks[NPROC][(64 * 1024) / sizeof(cpustack_t)];
 #endif
 
 /** The main process (the one that executes main()). */
@@ -93,6 +104,10 @@ static void proc_init_struct(Process *proc)
 #if CONFIG_KERN_HEAP
        proc->flags = 0;
 #endif
+
+#if CONFIG_KERN_PRI
+       proc->link.pri = 0;
+#endif
 }
 
 MOD_DEFINE(proc);
@@ -101,6 +116,12 @@ void proc_init(void)
 {
        LIST_INIT(&ProcReadyList);
 
+#if ARCH & ARCH_EMUL
+       LIST_INIT(&StackFreeList);
+       for (int i = 0; i < NPROC; i++)
+               ADDTAIL(&StackFreeList, (Node *)proc_stacks[i]);
+#endif
+
        /*
         * We "promote" the current context into a real process. The only thing we have
         * to do is create a PCB and make it current. We don't need to setup the stack
@@ -121,17 +142,16 @@ void proc_init(void)
        MOD_INIT(proc);
 }
 
-
 /**
  * Create a new process, starting at the provided entry point.
  *
  * \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_t data, size_t stack_size, cpustack_t *stack_base)
+struct Process *proc_new_with_name(UNUSED_ARG(const char *, name), void (*entry)(void), iptr_t data, size_t stack_size, cpustack_t *stack_base)
 {
        Process *proc;
-       const size_t PROC_SIZE_WORDS = ROUND2(sizeof(Process), sizeof(cpustack_t)) / sizeof(cpustack_t);
+       const size_t PROC_SIZE_WORDS = ROUND_UP2(sizeof(Process), sizeof(cpustack_t)) / sizeof(cpustack_t);
 #if CONFIG_KERN_HEAP
        bool free_stack = false;
 #endif
@@ -261,6 +281,43 @@ void proc_rename(struct Process *proc, const char *name)
 #endif
 }
 
+
+#if CONFIG_KERN_PRI
+/**
+ * Change the scheduling priority of a process.
+ *
+ * Process piorities are signed ints, whereas a larger integer value means
+ * higher scheduling priority.  The default priority for new processes is 0.
+ * The idle process runs with the lowest possible priority: INT_MIN.
+ *
+ * A process with a higher priority always preempts lower priority processes.
+ * Processes of equal priority share the CPU time according to a simple
+ * round-robin policy.
+ *
+ * As a general rule to maximize responsiveness, compute-bound processes
+ * should be assigned negative priorities and tight, interactive processes
+ * should be assigned positive priorities.
+ *
+ * To avoid interfering with system background activities such as input
+ * processing, application processes should remain within the range -10
+ * and +10.
+ */
+void proc_setPri(struct Process *proc, int pri)
+{
+               if (proc->link.pri == pri)
+                       return;
+
+               proc->link.pri = pri;
+
+               if (proc != CurrentProcess)
+               {
+                               //proc_forbid();
+                               //TODO: re-enqueue process
+                               //pric_permit();
+               }
+}
+#endif // CONFIG_KERN_PRI
+
 /**
  * Terminate the current process
  */