+ // Init the test processes
+ kputs("Run Preemption test..\n");
+ for (i = 0; i < TASKS; i++)
+ {
+ sprintf(&preempt_name[i][0], "preempt_worker_%ld", i + 1);
+ proc_new_with_name(preempt_name[i], preempt_worker, (iptr_t)(i + 1),
+ WORKER_STACK_SIZE, &preempt_worker_stack[i][0]);
+ }
+ kputs("> Main: Processes created\n");
+ /* Synchronize on start */
+ while (1)
+ {
+ for (i = 0; i < TASKS; i++)
+ if (!barrier[i])
+ break;
+ if (i == TASKS)
+ break;
+ proc_yield();
+ }
+ /* Now all threads have been created, start them all */
+ main_barrier = 1;
+ MEMORY_BARRIER;
+ kputs("> Main: Processes started\n");
+ while (1)
+ {
+ for (i = 0; i < TASKS; i++)
+ {
+ if (!preempt_done[i])
+ break;
+ else if (preempt_done[i] == TEST_FAIL)
+ {
+ kputs("> Main: process test finished..fail!\n");
+ return -1;
+ }
+ }
+ if (i == TASKS)
+ break;
+ monitor_report();
+ timer_delay(1000);
+ }
+ for (i = 0; i < TASKS; i++)
+ score += preempt_counter[i];
+ kputs("> Main: process test finished..ok!\n");
+ kprintf("> Score: %lu\n", score);
+ return 0;
+}
+#endif /* CONFIG_KERN_PREEMPT */
+
+#if CONFIG_KERN_SIGNALS & CONFIG_KERN_PRI
+
+#define PROC_PRI_TEST_STACK(num) PROC_DEFINE_STACK(proc_test##num##_stack, KERN_MINSTACKSIZE);
+
+// Define params to test priority
+#define PROC_PRI_TEST(num) static void proc_pri_test##num(void) \
+{ \
+ struct Process *main_proc = (struct Process *) proc_currentUserData(); \
+ kputs("> Process: " #num "\n"); \
+ sig_signal(main_proc, SIG_USER##num); \
+}
+
+// Default priority is 0
+#define PROC_PRI_TEST_INIT(num, proc) \
+do { \
+ struct Process *p = proc_new(proc_pri_test##num, (proc), \
+ sizeof(proc_test##num##_stack), \
+ proc_test##num##_stack); \
+ proc_setPri(p, num + 1); \
+} while (0)
+
+PROC_PRI_TEST_STACK(0)
+PROC_PRI_TEST_STACK(1)
+PROC_PRI_TEST_STACK(2)
+
+PROC_PRI_TEST(0)
+PROC_PRI_TEST(1)
+PROC_PRI_TEST(2)
+
+static int prio_worker_test(void)
+{
+ struct Process *curr = proc_current();
+ int orig_pri = curr->link.pri;
+ int ret = 0;
+
+ // test process priority
+ // main process must have the higher priority to check signals received
+ proc_setPri(proc_current(), 10);
+
+ kputs("Run Priority test..\n");
+ // the order in which the processes are created is important!
+ PROC_PRI_TEST_INIT(0, curr);
+ PROC_PRI_TEST_INIT(1, curr);
+ PROC_PRI_TEST_INIT(2, curr);
+
+ // signals must be: USER2, 1, 0 in order
+ sigmask_t signals = sig_wait(SIG_USER0 | SIG_USER1 | SIG_USER2);
+ if (!(signals & SIG_USER2))
+ {
+ ret = -1;
+ goto out;
+ }
+ signals = sig_wait(SIG_USER0 | SIG_USER1 | SIG_USER2);
+ if (!(signals & SIG_USER1))
+ {
+ ret = -1;
+ goto out;
+ }
+ signals = sig_wait(SIG_USER0 | SIG_USER1 | SIG_USER2);
+ if (!(signals & SIG_USER0))
+ {
+ ret = -1;
+ goto out;
+ }
+ // All processes must have quit by now, but just in case...
+ signals = sig_waitTimeout(SIG_USER0 | SIG_USER1 | SIG_USER2, 200);
+ if (signals & (SIG_USER0 | SIG_USER1 | SIG_USER2))
+ {
+ ret = -1;
+ goto out;
+ }
+ if (signals & SIG_TIMEOUT)
+ {
+ kputs("Priority test successfull.\n");
+ }
+out:
+ proc_setPri(proc_current(), orig_pri);
+ if (ret != 0)
+ kputs("Priority test failed.\n");
+ return ret;
+}
+#endif /* CONFIG_KERN_SIGNALS & CONFIG_KERN_PRI */
+
+/**
+ * Process scheduling test
+ */
+int proc_testRun(void)
+{
+#if CONFIG_KERN_PREEMPT
+ // Clear shared data (this is needed when this testcase is embedded in
+ // the demo application).
+ memset(preempt_counter, 0, sizeof(preempt_counter));
+ memset(preempt_done, 0, sizeof(preempt_done));
+ memset(barrier, 0, sizeof(barrier));
+ main_barrier = 0;
+#endif /* CONFIG_KERN_PREEMPT */
+ memset(done, 0, sizeof(done));
+
+ /* Start tests */
+ worker_test();
+#if CONFIG_KERN_PREEMPT
+ preempt_worker_test();
+#endif /* CONFIG_KERN_PREEMPT */
+#if CONFIG_KERN_SIGNALS & CONFIG_KERN_PRI
+ prio_worker_test();
+#endif /* CONFIG_KERN_SIGNALS & CONFIG_KERN_PRI */
+ return 0;