Merge from trunk.
[bertos.git] / bertos / kern / proc_test.c
index ebb160627a6c35ff31d8e15e6b5a1aac3c941ea8..b2319faafdb18d09333af17745e5212004db1061 100644 (file)
  * $test$: echo "#define CONFIG_KERN_PRI 1" >> $cfgdir/cfg_proc.h
  * $test$: echo  "#undef CONFIG_KERN_PREEMPT" >> $cfgdir/cfg_proc.h
  * $test$: echo "#define CONFIG_KERN_PREEMPT 1" >> $cfgdir/cfg_proc.h
+ * $test$: echo  "#undef CONFIG_KERN_HEAP" >> $cfgdir/cfg_proc.h
+ * $test$: echo "#define CONFIG_KERN_HEAP 1" >> $cfgdir/cfg_proc.h
+ * $test$: echo  "#undef CONFIG_KERN_HEAP_SIZE" >> $cfgdir/cfg_proc.h
+ * $test$: echo "#define CONFIG_KERN_HEAP_SIZE 2097152L" >> $cfgdir/cfg_proc.h
  * $test$: cp bertos/cfg/cfg_monitor.h $cfgdir/
  * $test$: sed -i "s/CONFIG_KERN_MONITOR 0/CONFIG_KERN_MONITOR 1/" $cfgdir/cfg_monitor.h
  * $test$: cp bertos/cfg/cfg_signal.h $cfgdir/
@@ -84,22 +88,51 @@ static char name[TASKS][32];
 
 static unsigned int done[TASKS];
 
-#define WORKER_STACK_SIZE KERN_MINSTACKSIZE * 3
+static cpu_atomic_t barrier[TASKS];
+static cpu_atomic_t main_barrier;
 
 /* Base time delay for processes using timer_delay() */
 #define DELAY  5
 
 // Define process stacks for test.
-static PROC_DEFINE_STACK(worker_stack, TASKS * WORKER_STACK_SIZE);
+#define WORKER_STACK_SIZE KERN_MINSTACKSIZE * 3
+
+#if CONFIG_KERN_HEAP
+#define WORKER_STACK(id)        NULL
+#else /* !CONFIG_KERN_HEAP */
+static cpu_stack_t worker_stack[TASKS][(WORKER_STACK_SIZE +
+                       sizeof(cpu_stack_t) - 1) / sizeof(cpu_stack_t)];
+#define WORKER_STACK(id)        (&worker_stack[id][0])
+#endif /* CONFIG_KERN_HEAP */
 
 static int prime_numbers[] =
 {
        1, 3, 5, 7, 11, 13, 17, 19,
        23, 29, 31, 37, 41, 43, 47, 53,
 };
-
 STATIC_ASSERT(TASKS <= countof(prime_numbers));
 
+#if CONFIG_KERN_PREEMPT
+/* Time to run each preemptible thread (in seconds) */
+#define TIME   10
+
+static unsigned long preempt_counter[TASKS];
+static unsigned int preempt_done[TASKS];
+#endif
+
+static void cleanup(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));
+#endif /* CONFIG_KERN_PREEMPT */
+       memset(done, 0, sizeof(done));
+       memset(barrier, 0, sizeof(barrier));
+       main_barrier = 0;
+}
+
 static void worker(void)
 {
        ssize_t pid = (ssize_t)proc_currentUserData();
@@ -107,6 +140,10 @@ static void worker(void)
        unsigned int my_count = 0;
        int i;
 
+       barrier[pid - 1] = 1;
+       /* Synchronize on the main barrier */
+       while (!main_barrier)
+               proc_yield();
        for (i = 0; i < tot; i++)
        {
                my_count++;
@@ -122,6 +159,7 @@ static int worker_test(void)
        ssize_t i;
 
        // Init the test processes
+       cleanup();
        kputs("Run Proc test..\n");
        for (i = 0; i < TASKS; i++)
        {
@@ -129,9 +167,20 @@ static int worker_test(void)
                snprintf(&name[i][0], sizeof(name[i]), "worker_%zd", i + 1);
                name[i][sizeof(name[i]) - 1] = '\0';
                proc_new_with_name(name[i], worker, (iptr_t)(i + 1),
-                               WORKER_STACK_SIZE,
-                               (cpu_stack_t *)((size_t)&worker_stack + WORKER_STACK_SIZE * i));
+                               WORKER_STACK_SIZE, WORKER_STACK(i));
+       }
+       /* Synchronize on start */
+       while (1)
+       {
+               for (i = 0; i < TASKS; i++)
+                       if (!barrier[i])
+                               break;
+               if (i == TASKS)
+                       break;
+               proc_yield();
        }
+       main_barrier = 1;
+       MEMORY_BARRIER;
        kputs("> Main: Processes started\n");
        while (1)
        {
@@ -150,19 +199,10 @@ static int worker_test(void)
 }
 
 #if CONFIG_KERN_PREEMPT
-/* Time to run each preemptible thread (in seconds) */
-#define TIME   10
-
-static cpu_atomic_t barrier[TASKS];
-static cpu_atomic_t main_barrier;
-
-static unsigned int preempt_counter[TASKS];
-static unsigned int preempt_done[TASKS];
-
 static void preempt_worker(void)
 {
        ssize_t pid = (ssize_t)proc_currentUserData();
-       unsigned int *my_count = &preempt_counter[pid - 1];
+       unsigned long *my_count = &preempt_counter[pid - 1];
        ticks_t start, stop;
        int i;
 
@@ -181,7 +221,7 @@ static void preempt_worker(void)
                if (UNLIKELY(*my_count == (unsigned int)~0))
                        *my_count = 1;
        }
-       PROC_ATOMIC(kprintf("> %s[%zd] completed: (counter = %d)\n",
+       PROC_ATOMIC(kprintf("> %s[%zd] completed: (counter = %lu)\n",
                                __func__, pid, *my_count));
        for (i = 0; i < TASKS; i++)
                if (!preempt_counter[i])
@@ -198,6 +238,7 @@ static int preempt_worker_test(void)
        ssize_t i;
 
        // Init the test processes
+       cleanup();
        kputs("Run Preemption test..\n");
        for (i = 0; i < TASKS; i++)
        {
@@ -206,8 +247,7 @@ static int preempt_worker_test(void)
                                "preempt_worker_%zd", i + 1);
                name[i][sizeof(name[i]) - 1] = '\0';
                proc_new_with_name(name[i], preempt_worker, (iptr_t)(i + 1),
-                               WORKER_STACK_SIZE,
-                               (cpu_stack_t *)((size_t)&worker_stack + WORKER_STACK_SIZE * i));
+                               WORKER_STACK_SIZE, WORKER_STACK(i));
        }
        kputs("> Main: Processes created\n");
        /* Synchronize on start */
@@ -251,29 +291,23 @@ static int preempt_worker_test(void)
 
 #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); \
+       sig_send(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);        \
+                                       WORKER_STACK_SIZE,              \
+                                       WORKER_STACK(num));             \
        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)
@@ -337,16 +371,6 @@ out:
  */
 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