Statistics
| Branch: | Tag: | Revision:

amiro-os / kernel / patches / introduce-thread-hierarchy.patch @ 39e164a2

History | View | Annotate | Download (51.975 KB)

1 0a89baf2 Thomas Schöpping
diff --git a/os/rt/include/chschd.h b/os/rt/include/chschd.h
2
--- a/os/rt/include/chschd.h
3
+++ b/os/rt/include/chschd.h
4 732a4657 Thomas Schöpping
@@ -176,6 +176,23 @@ struct ch_thread {
5
    * @brief   References to this thread.
6 0a89baf2 Thomas Schöpping
    */
7
   trefs_t               refs;
8 732a4657 Thomas Schöpping
+#endif
9 0a89baf2 Thomas Schöpping
+#if (CH_CFG_USE_THREADHIERARCHY == TRUE) || defined(__DOXYGEN__)
10
+  /**
11
+   * @brief   Pointer to the parent thread.
12
+   * @note    NULL only for the main thread.
13
+   */
14
+  thread_t              *parent;
15
+  /**
16
+   * @brief   Pointer to the first child thread.
17
+   * @note    NULL if there are no child threads.
18
+   */
19
+  thread_t              *children;
20
+  /**
21
+   * @brief   Pointer to the next sibling thread.
22
+   * @brief   NULL if there are no more child threads.
23
+   */
24
+  thread_t              *sibling;
25 732a4657 Thomas Schöpping
 #endif
26 0a89baf2 Thomas Schöpping
   /**
27
    * @brief   Number of ticks remaining to this thread.
28
diff --git a/os/rt/include/chthreads.h b/os/rt/include/chthreads.h
29
--- a/os/rt/include/chthreads.h
30
+++ b/os/rt/include/chthreads.h
31 732a4657 Thomas Schöpping
@@ -79,6 +79,12 @@ typedef struct {
32 0a89baf2 Thomas Schöpping
    * @brief   Thread argument.
33
    */
34
   void              *arg;
35 732a4657 Thomas Schöpping
+#if (CH_CFG_USE_THREADHIERARCHY) == TRUE || defined(__DOXYGEN__)
36 0a89baf2 Thomas Schöpping
+  /**
37
+   * @brief   Pointer to the parent thread.
38
+   */
39
+  thread_t          *parent;
40 732a4657 Thomas Schöpping
+#endif
41 0a89baf2 Thomas Schöpping
 } thread_descriptor_t;
42
 
43
 /*===========================================================================*/
44 732a4657 Thomas Schöpping
@@ -220,7 +226,11 @@ typedef struct {
45 0a89baf2 Thomas Schöpping
 #ifdef __cplusplus
46
 extern "C" {
47
 #endif
48 732a4657 Thomas Schöpping
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
49 0a89baf2 Thomas Schöpping
+   thread_t *_thread_init(thread_t *tp, thread_t* parent, const char *name, tprio_t prio);
50 732a4657 Thomas Schöpping
+#else
51
    thread_t *_thread_init(thread_t *tp, const char *name, tprio_t prio);
52
+#endif
53 0a89baf2 Thomas Schöpping
 #if CH_DBG_FILL_THREADS == TRUE
54
   void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v);
55
 #endif
56 732a4657 Thomas Schöpping
@@ -228,8 +238,13 @@ extern "C" {
57 0a89baf2 Thomas Schöpping
   thread_t *chThdCreateSuspended(const thread_descriptor_t *tdp);
58
   thread_t *chThdCreateI(const thread_descriptor_t *tdp);
59
   thread_t *chThdCreate(const thread_descriptor_t *tdp);
60
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
61
+  thread_t *chThdCreateStatic(void *wsp, size_t size,
62
+                              tprio_t prio, tfunc_t pf, void *arg, thread_t *parent);
63
+#else
64
   thread_t *chThdCreateStatic(void *wsp, size_t size,
65
                               tprio_t prio, tfunc_t pf, void *arg);
66
+#endif
67
   thread_t *chThdStart(thread_t *tp);
68
 #if CH_CFG_USE_REGISTRY == TRUE
69
   thread_t *chThdAddRef(thread_t *tp);
70
diff --git a/os/rt/src/chsys.c b/os/rt/src/chsys.c
71
--- a/os/rt/src/chsys.c
72
+++ b/os/rt/src/chsys.c
73 732a4657 Thomas Schöpping
@@ -126,14 +126,26 @@ void chSysInit(void) {
74 0a89baf2 Thomas Schöpping
 #if CH_CFG_NO_IDLE_THREAD == FALSE
75
   /* Now this instructions flow becomes the main thread.*/
76
 #if CH_CFG_USE_REGISTRY == TRUE
77 732a4657 Thomas Schöpping
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
78 0a89baf2 Thomas Schöpping
+  currp = _thread_init(&ch.mainthread, NULL, (const char *)&ch_debug, NORMALPRIO);
79 732a4657 Thomas Schöpping
+#else
80
   currp = _thread_init(&ch.mainthread, (const char *)&ch_debug, NORMALPRIO);
81
+#endif
82
+#else
83
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
84 0a89baf2 Thomas Schöpping
+  currp = _thread_init(&ch.mainthread, NULL, "main", NORMALPRIO);
85 732a4657 Thomas Schöpping
 #else
86
   currp = _thread_init(&ch.mainthread, "main", NORMALPRIO);
87 0a89baf2 Thomas Schöpping
 #endif
88 732a4657 Thomas Schöpping
+#endif
89 0a89baf2 Thomas Schöpping
 #else
90
   /* Now this instructions flow becomes the idle thread.*/
91 732a4657 Thomas Schöpping
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
92 0a89baf2 Thomas Schöpping
+  currp = _thread_init(&ch.mainthread, NULL, "idle", IDLEPRIO);
93 732a4657 Thomas Schöpping
+#else
94
   currp = _thread_init(&ch.mainthread, "idle", IDLEPRIO);
95 0a89baf2 Thomas Schöpping
 #endif
96 732a4657 Thomas Schöpping
+#endif
97 0a89baf2 Thomas Schöpping
 
98
 #if CH_DBG_ENABLE_STACK_CHECK == TRUE
99 732a4657 Thomas Schöpping
   {
100
@@ -172,6 +184,9 @@ void chSysInit(void) {
101 0a89baf2 Thomas Schöpping
       THD_WORKING_AREA_END(ch_idle_thread_wa),
102
       IDLEPRIO,
103
       _idle_thread,
104 732a4657 Thomas Schöpping
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
105 0a89baf2 Thomas Schöpping
+      NULL,
106 732a4657 Thomas Schöpping
+#endif
107 0a89baf2 Thomas Schöpping
       NULL
108
     };
109
 
110
diff --git a/os/rt/src/chthreads.c b/os/rt/src/chthreads.c
111
--- a/os/rt/src/chthreads.c
112
+++ b/os/rt/src/chthreads.c
113 732a4657 Thomas Schöpping
@@ -70,22 +70,67 @@
114 0a89baf2 Thomas Schöpping
 /* Module local functions.                                                   */
115
 /*===========================================================================*/
116
 
117
+#if CH_CFG_USE_THREADHIERARCHY == TRUE || defined(__DOXYGEN__)
118
+/**
119
+ * @brief   Insert a thread to the list of children of another thread.
120
+ * @details If @p CH_CFG_THREADHIERARCHY_ORDERED is @p TRUE, children are ordered by their priorities (high to low).
121
+ *          Children with identical priority are ordered by 'age' (youngest first).
122
+ *
123
+ * @param[in] parent  Pointer to the parent thread (must not be NULL).
124
+ * @param[in] child   Pointer to the child thread (must not be NULL).
125
+ */
126
+inline void _thread_addChild(thread_t *parent, thread_t *child) {
127
+#if CH_CFG_THREADHIERARCHY_ORDERED == TRUE
128
+  thread_t *sibling = parent->children;
129
+  child->parent = parent;
130
+#if CH_CFG_USE_MUTEXES == TRUE
131
+  if (sibling == NULL || sibling->realprio <= child->realprio) {
132
+#else
133
+  if (sibling == NULL || sibling->prio <= child->prio) {
134
+#endif
135
+    child->sibling = sibling;
136
+    parent->children = child;
137
+  } else {
138
+#if CH_CFG_USE_MUTEXES == TRUE
139
+    while (sibling->sibling != NULL && sibling->sibling->realprio > child->realprio) {
140
+#else
141
+    while (sibling->sibling != NULL && sibling->sibling->prio > child->prio) {
142
+#endif
143
+      sibling = sibling->sibling;
144
+    }
145
+    child->sibling = sibling->sibling;
146
+    sibling->sibling = child;
147
+  }
148
+#else
149
+  child->parent = parent;
150
+  child->sibling = parent->children;
151
+  parent->children = child;
152
+#endif
153
+  return;
154
+}
155
+#endif
156
+
157
 /*===========================================================================*/
158
 /* Module exported functions.                                                */
159
 /*===========================================================================*/
160 732a4657 Thomas Schöpping
 
161
+#if CH_CFG_USE_THREADHIERARCHY == TRUE || defined(__DOXYGEN__)
162
 /**
163
  * @brief   Initializes a thread structure.
164 0a89baf2 Thomas Schöpping
  * @note    This is an internal functions, do not use it in application code.
165
  *
166
  * @param[in] tp        pointer to the thread
167
+ * @param[in] parent    pointer to the parent thread
168
  * @param[in] name      thread name
169
  * @param[in] prio      the priority level for the new thread
170
  * @return              The same thread pointer passed as parameter.
171
  *
172
  * @notapi
173
  */
174
+thread_t *_thread_init(thread_t *tp, thread_t *parent,  const char *name, tprio_t prio) {
175 732a4657 Thomas Schöpping
+#else
176
 thread_t *_thread_init(thread_t *tp, const char *name, tprio_t prio) {
177
+#endif
178 0a89baf2 Thomas Schöpping
 
179
   tp->prio      = prio;
180
   tp->state     = CH_STATE_WTSTART;
181 732a4657 Thomas Schöpping
@@ -110,6 +155,17 @@ thread_t *_thread_init(thread_t *tp, const char *name, tprio_t prio) {
182 0a89baf2 Thomas Schöpping
 #else
183
   (void)name;
184
 #endif
185
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
186
+  if (parent != NULL) {
187
+    _thread_addChild(parent, tp);
188
+  } else {
189
+    tp->parent = parent;
190
+    tp->sibling = NULL;
191
+  }
192
+  tp->children = NULL;
193
+#else
194
+  (void)parent;
195
+#endif
196
 #if CH_CFG_USE_WAITEXIT == TRUE
197
   list_init(&tp->waiting);
198
 #endif
199 732a4657 Thomas Schöpping
@@ -190,7 +246,11 @@ thread_t *chThdCreateSuspendedI(const thread_descriptor_t *tdp) {
200 0a89baf2 Thomas Schöpping
   PORT_SETUP_CONTEXT(tp, tdp->wbase, tp, tdp->funcp, tdp->arg);
201
 
202
   /* The driver object is initialized but not started.*/
203 732a4657 Thomas Schöpping
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
204 0a89baf2 Thomas Schöpping
+  return _thread_init(tp, tdp->parent, tdp->name, tdp->prio);
205 732a4657 Thomas Schöpping
+#else
206
   return _thread_init(tp, tdp->name, tdp->prio);
207
+#endif
208
 }
209
 
210
 /**
211
@@ -300,6 +360,7 @@ thread_t *chThdCreate(const thread_descriptor_t *tdp) {
212
   return tp;
213 0a89baf2 Thomas Schöpping
 }
214
 
215 732a4657 Thomas Schöpping
+#if CH_CFG_USE_THREADHIERARCHY == TRUE || defined(__DOXYGEN__)
216 0a89baf2 Thomas Schöpping
 /**
217 732a4657 Thomas Schöpping
  * @brief   Creates a new thread into a static memory area.
218
  * @post    The created thread has a reference counter set to one, it is
219
@@ -315,13 +376,20 @@ thread_t *chThdCreate(const thread_descriptor_t *tdp) {
220 0a89baf2 Thomas Schöpping
  * @param[in] pf        the thread function
221
  * @param[in] arg       an argument passed to the thread function. It can be
222
  *                      @p NULL.
223
+ * @param[in] parent    pointer to a parent thread. Parameter only available if
224
+ *                      @p CH_CFG_USE_THREADHIERARCHY is @p TRUE. It can be
225
+ *                      @p NULL.
226
  * @return              The pointer to the @p thread_t structure allocated for
227
  *                      the thread into the working space area.
228
  *
229
  * @api
230
  */
231
+thread_t *chThdCreateStatic(void *wsp, size_t size,
232
+                            tprio_t prio, tfunc_t pf, void *arg, thread_t *parent) {
233
+#else
234
 thread_t *chThdCreateStatic(void *wsp, size_t size,
235
                             tprio_t prio, tfunc_t pf, void *arg) {
236
+#endif
237
   thread_t *tp;
238
 
239
   chDbgCheck((wsp != NULL) &&
240 732a4657 Thomas Schöpping
@@ -358,7 +426,11 @@ thread_t *chThdCreateStatic(void *wsp, size_t size,
241 0a89baf2 Thomas Schöpping
   /* Setting up the port-dependent part of the working area.*/
242
   PORT_SETUP_CONTEXT(tp, wsp, tp, pf, arg);
243
 
244
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
245
+  tp = _thread_init(tp, parent, "noname", prio);
246
+#else
247 732a4657 Thomas Schöpping
   tp = _thread_init(tp, "noname", prio);
248 0a89baf2 Thomas Schöpping
+#endif
249
 
250
   /* Starting the thread immediately.*/
251
   chSchWakeupS(tp, MSG_OK);
252 732a4657 Thomas Schöpping
@@ -529,6 +601,30 @@ void chThdExitS(msg_t msg) {
253 0a89baf2 Thomas Schöpping
 #endif
254
 #endif
255
 
256
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
257
+  thread_t *child;
258
+  /* Remove from parent's list of children. */
259
+  if (tp->parent != NULL) {
260
+    if (tp->parent->children == tp) {
261
+      tp->parent->children = tp->sibling;
262
+    } else {
263
+      child = tp->parent->children;
264
+      while (child->sibling != tp) {
265
+        child = child->sibling;
266
+      }
267
+      child->sibling = tp->sibling;
268
+    }
269
+    tp->parent = NULL;
270
+  }
271
+  tp->sibling = NULL;
272
+  /* Move any child threads to the main thread. */
273
+  while (tp->children != NULL) {
274
+    child = tp->children;
275
+    tp->children = child->sibling;
276
+    _thread_addChild(&ch.mainthread, child);
277
+  }
278
+#endif
279
+
280
   /* Going into final state.*/
281
   chSchGoSleepS(CH_STATE_FINAL);
282
 
283 732a4657 Thomas Schöpping
@@ -610,6 +706,43 @@ tprio_t chThdSetPriority(tprio_t newprio) {
284
 #else
285 0a89baf2 Thomas Schöpping
   oldprio = currp->prio;
286
   currp->prio = newprio;
287 732a4657 Thomas Schöpping
+#endif
288 0a89baf2 Thomas Schöpping
+#if (CH_CFG_USE_THREADHIERARCHY == TRUE) && (CH_CFG_THREADHIERARCHY_ORDERED == TRUE)
289
+  /* Reorder sibling list. */
290
+  if (currp->parent != NULL && newprio != oldprio) {
291
+    thread_t *sibling, *oldsibling;
292
+    if (newprio > oldprio) {
293
+      oldsibling = currp->sibling;
294
+      _thread_addChild(currp->parent, currp);
295
+      sibling = currp->sibling;
296
+      if (sibling != NULL) {
297
+        while (sibling->sibling != currp) {
298
+          sibling = sibling->sibling;
299
+        }
300
+        sibling->sibling = oldsibling;
301
+      }
302
+    } else /*if (newprio < oldprio)*/ {
303
+      sibling = currp->parent->children;
304
+      if (sibling == currp) {
305
+        currp->parent->children = currp->sibling;
306
+        _thread_addChild(currp->parent, currp);
307
+      } else {
308
+        while (sibling->sibling != currp) {
309
+          sibling = sibling->sibling;
310
+        }
311
+        sibling->sibling = currp->sibling;
312
+#if CH_CFG_USE_MUTEXES == TRUE
313
+        while (sibling->sibling != NULL && sibling->sibling->realprio > currp->realprio) {
314
+#else
315
+        while (sibling->sibling != NULL && sibling->sibling->prio > currp->prio) {
316
+#endif
317
+          sibling = sibling->sibling;
318
+        }
319
+        currp->sibling = sibling->sibling;
320
+        sibling->sibling = currp;
321
+      }
322
+    }
323
+  }
324 732a4657 Thomas Schöpping
 #endif
325 0a89baf2 Thomas Schöpping
   chSchRescheduleS();
326
   chSysUnlock();
327
diff --git a/test/rt/source/test/rt_test_root.c b/test/rt/source/test/rt_test_root.c
328
--- a/test/rt/source/test/rt_test_root.c
329
+++ b/test/rt/source/test/rt_test_root.c
330
@@ -106,6 +106,14 @@ void * ROMCONST wa[5] = {test_buffer + (WA_SIZE * 0),
331
                          test_buffer + (WA_SIZE * 3),
332
                          test_buffer + (WA_SIZE * 4)};
333
 
334
+thread_t *test_create_thread(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) {
335
+#if CH_CFG_USE_THREADHIERARCHY == TRUE
336
+  return chThdCreateStatic(wsp, size, prio, pf, arg, chThdGetSelfX());
337
+#else
338
+  return chThdCreateStatic(wsp, size, prio, pf, arg);
339
+#endif
340
+}
341
+
342
 /*
343
  * Sets a termination request in all the test-spawned threads.
344
  */
345
diff --git a/test/rt/source/test/rt_test_root.h b/test/rt/source/test/rt_test_root.h
346
--- a/test/rt/source/test/rt_test_root.h
347
+++ b/test/rt/source/test/rt_test_root.h
348
@@ -88,6 +88,7 @@ extern thread_t *threads[MAX_THREADS];
349
 extern void * ROMCONST wa[5];
350
 
351
 void test_print_port_info(void);
352
+thread_t *test_create_thread(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg);
353
 void test_terminate_threads(void);
354
 void test_wait_threads(void);
355
 systime_t test_wait_tick(void);
356
diff --git a/test/rt/source/test/rt_test_sequence_001.c b/test/rt/source/test/rt_test_sequence_001.c
357
--- a/test/rt/source/test/rt_test_sequence_001.c
358
+++ b/test/rt/source/test/rt_test_sequence_001.c
359
@@ -193,6 +193,12 @@ static void rt_test_001_003_execute(void) {
360
     test_print("--- CH_CFG_USE_REGISTRY:                ");
361
     test_printn(CH_CFG_USE_REGISTRY);
362
     test_println("");
363
+    test_print("--- CH_CFG_USE_THREADHIERARCHY:         ");
364
+    test_printn(CH_CFG_USE_THREADHIERARCHY);
365
+    test_println("");
366
+    test_print("--- CH_CFG_THREADHIERARCHY_ORDERED:     ");
367
+    test_printn(CH_CFG_THREADHIERARCHY_ORDERED);
368
+    test_println("");
369
     test_print("--- CH_CFG_USE_WAITEXIT:                ");
370
     test_printn(CH_CFG_USE_WAITEXIT);
371
     test_println("");
372
@@ -207,7 +213,7 @@ static void rt_test_001_003_execute(void) {
373
     test_println("");
374 732a4657 Thomas Schöpping
     test_print("--- CH_CFG_USE_MUTEXES_RECURSIVE:       ");
375 0a89baf2 Thomas Schöpping
     test_printn(CH_CFG_USE_MUTEXES_RECURSIVE);
376
-    test_println("");   
377
+    test_println("");
378
     test_print("--- CH_CFG_USE_CONDVARS:                ");
379
     test_printn(CH_CFG_USE_CONDVARS);
380
     test_println("");
381
diff --git a/test/rt/source/test/rt_test_sequence_003.c b/test/rt/source/test/rt_test_sequence_003.c
382
--- a/test/rt/source/test/rt_test_sequence_003.c
383
+++ b/test/rt/source/test/rt_test_sequence_003.c
384
@@ -46,6 +46,20 @@ static THD_FUNCTION(thread, p) {
385
   test_emit_token(*(char *)p);
386
 }
387
 
388
+#if (CH_CFG_USE_THREADHIERARCHY)
389
+static THD_FUNCTION(hierarchythread, p) {
390
+
391
+  do {
392
+    if (*(tprio_t *)p != chThdGetPriorityX()) {
393
+      chThdSetPriority(*(tprio_t *)p);
394
+    }
395
+    chThdSleepMilliseconds(10);
396
+  } while (!chThdShouldTerminateX());
397
+
398
+  chThdExit(MSG_OK);
399
+}
400
+#endif
401
+
402
 /****************************************************************************
403
  * Test cases.
404
  ****************************************************************************/
405
@@ -166,11 +180,11 @@ static void rt_test_003_002_execute(void) {
406
      sequence is tested.*/
407
   test_set_step(1);
408
   {
409
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
410
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread, "D");
411
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
412
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
413
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
414
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
415
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread, "D");
416
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
417
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
418
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
419
     test_wait_threads();
420
     test_assert_sequence("ABCDE", "invalid sequence");
421
   }
422
@@ -179,11 +193,11 @@ static void rt_test_003_002_execute(void) {
423
      sequence is tested.*/
424
   test_set_step(2);
425
   {
426
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
427
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
428
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
429
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread, "D");
430
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
431
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
432
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
433
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
434
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread, "D");
435
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
436
     test_wait_threads();
437
     test_assert_sequence("ABCDE", "invalid sequence");
438
   }
439
@@ -192,11 +206,11 @@ static void rt_test_003_002_execute(void) {
440
      sequence is tested.*/
441
   test_set_step(3);
442
   {
443
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread, "D");
444
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
445
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
446
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
447
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
448
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread, "D");
449
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
450
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
451
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
452
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
453
     test_wait_threads();
454
     test_assert_sequence("ABCDE", "invalid sequence");
455
   }
456
@@ -325,6 +339,405 @@ static const testcase_t rt_test_003_004 = {
457
 };
458
 #endif /* CH_CFG_USE_MUTEXES */
459
 
460
+#if (CH_CFG_USE_THREADHIERARCHY) || defined(__DOXYGEN__)
461
+/**
462
+ * @page rt_test_003_005 [3.5] Thread hierarach with (un)ordered lists.
463
+ *
464
+ * <h2>Description</h2>
465
+ * Todo
466
+ *
467
+ * <h2>Conditions</h2>
468
+ * This test is only executed if the following preprocessor condition
469
+ * evaluates to true:
470
+ * - CH_CFG_USE_THREADHIERARCHY
471
+ * This test comprises additional tests if the following preprocessor
472
+ * condition evaluates to true:
473
+ * - CH_CFG_THREADHIERARCHY_ORDERED
474
+ * .
475
+ *
476
+ * <h2>Test Steps</h2>
477
+ * Todo
478
+ * .
479
+ */
480
+
481
+static void rt_test_003_005_execute(void) {
482
+
483
+  /* [3.5.1] Creating 1 parent and 4 child threads with increasing priority,
484
+   * hierarchy information is tested */
485
+  test_set_step(1);
486
+  {
487
+    tprio_t prios[MAX_THREADS];
488
+    thread_t *threads_cpy[MAX_THREADS];
489
+    thread_t *parents[MAX_THREADS];
490
+    thread_t *siblings[MAX_THREADS];
491
+    prios[0] = chThdGetPriorityX()-1;
492
+    prios[1] = chThdGetPriorityX()-5;
493
+    prios[2] = chThdGetPriorityX()-4;
494
+    prios[3] = chThdGetPriorityX()-3;
495
+    prios[4] = chThdGetPriorityX()-2;
496
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
497
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
498
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
499
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
500
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
501
+    threads_cpy[0] = threads[0];
502
+    threads_cpy[1] = threads[1];
503
+    threads_cpy[2] = threads[2];
504
+    threads_cpy[3] = threads[3];
505
+    threads_cpy[4] = threads[4];
506
+    parents[0] = threads[0]->parent;
507
+    parents[1] = threads[1]->parent;
508
+    parents[2] = threads[2]->parent;
509
+    parents[3] = threads[3]->parent;
510
+    parents[4] = threads[4]->parent;
511
+    siblings[0] = threads[0]->children;
512
+    siblings[1] = threads[1]->sibling;
513
+    siblings[2] = threads[2]->sibling;
514
+    siblings[3] = threads[3]->sibling;
515
+    siblings[4] = threads[4]->sibling;
516
+    chThdTerminate(threads[0]);
517
+    chThdTerminate(threads[1]);
518
+    chThdTerminate(threads[2]);
519
+    chThdTerminate(threads[3]);
520
+    chThdTerminate(threads[4]);
521
+    test_wait_threads();
522
+    test_assert(parents[0] == chThdGetSelfX() &&
523
+                parents[1] == threads_cpy[0] &&
524
+                parents[2] == threads_cpy[0] &&
525
+                parents[3] == threads_cpy[0] &&
526
+                parents[4] == threads_cpy[0] &&
527
+                siblings[0] == threads_cpy[4] &&
528
+                siblings[1] == NULL &&
529
+                siblings[2] == threads_cpy[1] &&
530
+                siblings[3] == threads_cpy[2] &&
531
+                siblings[4] == threads_cpy[3], "invalid children list");
532
+  }
533
+
534
+  /* [3.5.2] Creating 1 parent and 4 child threads with decreasing priority,
535
+   * hierarchy information is tested.*/
536
+  test_set_step(2);
537
+  {
538
+    tprio_t prios[MAX_THREADS];
539
+    thread_t *threads_cpy[MAX_THREADS];
540
+    thread_t *parents[MAX_THREADS];
541
+    thread_t *siblings[MAX_THREADS];
542
+    prios[0] = chThdGetPriorityX()-1;
543
+    prios[1] = chThdGetPriorityX()-2;
544
+    prios[2] = chThdGetPriorityX()-3;
545
+    prios[3] = chThdGetPriorityX()-4;
546
+    prios[4] = chThdGetPriorityX()-5;
547
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
548
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
549
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
550
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
551
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
552
+    threads_cpy[0] = threads[0];
553
+    threads_cpy[1] = threads[1];
554
+    threads_cpy[2] = threads[2];
555
+    threads_cpy[3] = threads[3];
556
+    threads_cpy[4] = threads[4];
557
+    parents[0] = threads[0]->parent;
558
+    parents[1] = threads[1]->parent;
559
+    parents[2] = threads[2]->parent;
560
+    parents[3] = threads[3]->parent;
561
+    parents[4] = threads[4]->parent;
562
+    siblings[0] = threads[0]->children;
563
+    siblings[1] = threads[1]->sibling;
564
+    siblings[2] = threads[2]->sibling;
565
+    siblings[3] = threads[3]->sibling;
566
+    siblings[4] = threads[4]->sibling;
567
+    test_terminate_threads();
568
+    test_wait_threads();
569
+#if CH_CFG_THREADHIERARCHY_ORDERED == TRUE
570
+    test_assert(parents[0] == chThdGetSelfX() &&
571
+                parents[1] == threads_cpy[0] &&
572
+                parents[2] == threads_cpy[0] &&
573
+                parents[3] == threads_cpy[0] &&
574
+                parents[4] == threads_cpy[0] &&
575
+                siblings[0] == threads_cpy[1] &&
576
+                siblings[1] == threads_cpy[2] &&
577
+                siblings[2] == threads_cpy[3] &&
578
+                siblings[3] == threads_cpy[4] &&
579
+                siblings[4] == NULL, "invalid children list");
580
+#else
581
+    test_assert(parents[0] == chThdGetSelfX() &&
582
+                parents[1] == threads_cpy[0] &&
583
+                parents[2] == threads_cpy[0] &&
584
+                parents[3] == threads_cpy[0] &&
585
+                parents[4] == threads_cpy[0] &&
586
+                siblings[0] == threads_cpy[4] &&
587
+                siblings[4] == threads_cpy[3] &&
588
+                siblings[3] == threads_cpy[2] &&
589
+                siblings[2] == threads_cpy[1] &&
590
+                siblings[1] == NULL, "invalid children list");
591
+#endif
592
+  }
593
+
594
+  /* [3.5.3] Creating 1 parent and 4 child threads with identical priority,
595
+   * hierarchy information is tested.*/
596
+  test_set_step(3);
597
+  {
598
+    tprio_t prios[MAX_THREADS];
599
+    thread_t *threads_cpy[MAX_THREADS];
600
+    thread_t *parents[MAX_THREADS];
601
+    thread_t *siblings[MAX_THREADS];
602
+    prios[0] = chThdGetPriorityX()-1;
603
+    prios[1] = chThdGetPriorityX()-2;
604
+    prios[2] = chThdGetPriorityX()-2;
605
+    prios[3] = chThdGetPriorityX()-2;
606
+    prios[4] = chThdGetPriorityX()-2;
607
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
608
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
609
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
610
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
611
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
612
+    threads_cpy[0] = threads[0];
613
+    threads_cpy[1] = threads[1];
614
+    threads_cpy[2] = threads[2];
615
+    threads_cpy[3] = threads[3];
616
+    threads_cpy[4] = threads[4];
617
+    parents[0] = threads[0]->parent;
618
+    parents[1] = threads[1]->parent;
619
+    parents[2] = threads[2]->parent;
620
+    parents[3] = threads[3]->parent;
621
+    parents[4] = threads[4]->parent;
622
+    siblings[0] = threads[0]->children;
623
+    siblings[1] = threads[1]->sibling;
624
+    siblings[2] = threads[2]->sibling;
625
+    siblings[3] = threads[3]->sibling;
626
+    siblings[4] = threads[4]->sibling;
627
+    test_terminate_threads();
628
+    test_wait_threads();
629
+    test_assert(parents[0] == chThdGetSelfX() &&
630
+                parents[1] == threads_cpy[0] &&
631
+                parents[2] == threads_cpy[0] &&
632
+                parents[3] == threads_cpy[0] &&
633
+                parents[4] == threads_cpy[0] &&
634
+                siblings[0] == threads_cpy[4] &&
635
+                siblings[1] == NULL &&
636
+                siblings[2] == threads_cpy[1] &&
637
+                siblings[3] == threads_cpy[2] &&
638
+                siblings[4] == threads_cpy[3] , "invalid children list");
639
+  }
640
+
641
+  /* [3.5.4] Creating 1 parent and 4 child threads with increasing priority
642
+   * which are terminated in a controlled manner, hierarchy information is
643
+   * tested.*/
644
+  test_set_step(4);
645
+  {
646
+    tprio_t prios[MAX_THREADS];
647
+    thread_t *threads_cpy[MAX_THREADS];
648
+    thread_t *parents[MAX_THREADS];
649
+    thread_t *siblings[MAX_THREADS];
650
+    prios[0] = chThdGetPriorityX()-1;
651
+    prios[1] = chThdGetPriorityX()-5;
652
+    prios[2] = chThdGetPriorityX()-4;
653
+    prios[3] = chThdGetPriorityX()-3;
654
+    prios[4] = chThdGetPriorityX()-2;
655
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
656
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
657
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
658
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
659
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
660
+    threads_cpy[0] = threads[0];
661
+    threads_cpy[1] = threads[1];
662
+    threads_cpy[2] = threads[2];
663
+    threads_cpy[3] = threads[3];
664
+    threads_cpy[4] = threads[4];
665
+    chThdTerminate(threads[1]);
666
+    chThdTerminate(threads[4]);
667
+    chThdWait(threads[1]);
668
+    chThdWait(threads[4]);
669
+    parents[0] = threads[0]->parent;
670
+    parents[1] = threads[1]->parent;
671
+    parents[2] = threads[2]->parent;
672
+    parents[3] = threads[3]->parent;
673
+    parents[4] = threads[4]->parent;
674
+    siblings[0] = threads[0]->children;
675
+    siblings[1] = threads[1]->sibling;
676
+    siblings[2] = threads[2]->sibling;
677
+    siblings[3] = threads[3]->sibling;
678
+    siblings[4] = threads[4]->sibling;
679
+    test_terminate_threads();
680
+    test_wait_threads();
681
+    test_assert(parents[0] == chThdGetSelfX() &&
682
+                parents[2] == threads_cpy[0] &&
683
+                parents[3] == threads_cpy[0] &&
684
+                siblings[0] == threads_cpy[3] &&
685
+                siblings[2] == NULL &&
686
+                siblings[3] == threads_cpy[2], "invalid children list");
687
+  }
688
+
689
+  /* [3.5.5] Creating 1 parent and 4 child threads and then terminating the
690
+   * parent, hierarchy information is tested.*/
691
+  test_set_step(5);
692
+  {
693
+    tprio_t prios[MAX_THREADS];
694
+    thread_t *threads_cpy[MAX_THREADS];
695
+    thread_t *parents[MAX_THREADS];
696
+    uint8_t thdmask = 0;
697
+    prios[0] = chThdGetPriorityX()-1;
698
+    prios[1] = chThdGetPriorityX()-1;
699
+    prios[2] = chThdGetPriorityX()-1;
700
+    prios[3] = chThdGetPriorityX()-1;
701
+    prios[4] = chThdGetPriorityX()-1;
702
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
703
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
704
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
705
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
706
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
707
+    threads_cpy[0] = threads[0];
708
+    threads_cpy[1] = threads[1];
709
+    threads_cpy[2] = threads[2];
710
+    threads_cpy[3] = threads[3];
711
+    threads_cpy[4] = threads[4];
712
+    chThdTerminate(threads[0]);
713
+    chThdWait(threads[0]);
714
+    parents[0] = threads_cpy[0]->parent;
715
+    parents[1] = threads_cpy[1]->parent;
716
+    parents[2] = threads_cpy[2]->parent;
717
+    parents[3] = threads_cpy[3]->parent;
718
+    parents[4] = threads_cpy[4]->parent;
719
+    for (thread_t* sibling = ch.mainthread.children; sibling != NULL; sibling = sibling->sibling) {
720
+      thdmask |= (sibling == threads[0]) ? 1 << 0 : 0;
721
+      thdmask |= (sibling == threads[1]) ? 1 << 1 : 0;
722
+      thdmask |= (sibling == threads[2]) ? 1 << 2 : 0;
723
+      thdmask |= (sibling == threads[3]) ? 1 << 3 : 0;
724
+      thdmask |= (sibling == threads[4]) ? 1 << 4 : 0;
725
+    }
726
+    test_terminate_threads();
727
+    test_wait_threads();
728
+    test_assert(parents[1] == &ch.mainthread &&
729
+                parents[2] == &ch.mainthread &&
730
+                parents[3] == &ch.mainthread &&
731
+                parents[4] == &ch.mainthread &&
732
+                thdmask == ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)), "child thread recovery failed");
733
+  }
734
+
735
+  /* [3.5.6] Creating 1 parent and 4 child threads with increasing priority
736
+   * and then increasing the priority of a low-priority child, hierarchy
737
+   * information is tested.*/
738
+  test_set_step(6);
739
+  {
740
+    tprio_t prios[MAX_THREADS];
741
+    thread_t *threads_cpy[MAX_THREADS];
742
+    tprio_t testprios[2];
743
+    thread_t *siblings[MAX_THREADS];
744
+    prios[0] = chThdGetPriorityX()-1;
745
+    prios[1] = chThdGetPriorityX()-5;
746
+    prios[2] = chThdGetPriorityX()-4;
747
+    prios[3] = chThdGetPriorityX()-3;
748
+    prios[4] = chThdGetPriorityX()-2;
749
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
750
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
751
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
752
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
753
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
754
+    threads_cpy[0] = threads[0];
755
+    threads_cpy[1] = threads[1];
756
+    threads_cpy[2] = threads[2];
757
+    threads_cpy[3] = threads[3];
758
+    threads_cpy[4] = threads[4];
759
+    chThdSleepMilliseconds(10);
760
+    testprios[0] = threads[1]->prio;
761
+    prios[1] = prios[4];
762
+    chThdSleepMilliseconds(10);
763
+    testprios[1] = threads[1]->prio;
764
+    siblings[0] = threads[0]->children;
765
+    siblings[1] = threads[1]->sibling;
766
+    siblings[2] = threads[2]->sibling;
767
+    siblings[3] = threads[3]->sibling;
768
+    siblings[4] = threads[4]->sibling;
769
+    test_terminate_threads();
770
+    test_wait_threads();
771
+#if CH_CFG_THREADHIERARCHY_ORDERED == TRUE
772
+    test_assert(testprios[0] == chThdGetPriorityX()-5 &&
773
+                testprios[1] == prios[4] &&
774
+                siblings[0] == threads_cpy[1] &&
775
+                siblings[1] == threads_cpy[4] &&
776
+                siblings[2] == NULL &&
777
+                siblings[3] == threads_cpy[2] &&
778
+                siblings[4] == threads_cpy[3], "invalid children list");
779
+#else
780
+    test_assert(testprios[0] == chThdGetPriorityX()-5 &&
781
+                testprios[1] == prios[4] &&
782
+                siblings[0] == threads_cpy[4] &&
783
+                siblings[1] == NULL &&
784
+                siblings[2] == threads_cpy[1] &&
785
+                siblings[3] == threads_cpy[2] &&
786
+                siblings[4] == threads_cpy[3], "invalid children list");
787
+#endif
788
+  }
789
+
790
+  /* [3.5.7] Creating 1 parent and 4 child threads with increasing priority
791
+   * and the decreasing the priority of a high-priority child, hierarchy
792
+   * information is tested.*/
793
+  test_set_step(7);
794
+  {
795
+    tprio_t prios[MAX_THREADS];
796
+    thread_t *threads_cpy[MAX_THREADS];
797
+    tprio_t testprios[2];
798
+    thread_t *siblings[MAX_THREADS];
799
+    prios[0] = chThdGetPriorityX()-1;
800
+    prios[1] = chThdGetPriorityX()-5;
801
+    prios[2] = chThdGetPriorityX()-4;
802
+    prios[3] = chThdGetPriorityX()-3;
803
+    prios[4] = chThdGetPriorityX()-2;
804
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
805
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
806
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
807
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
808
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
809
+    threads_cpy[0] = threads[0];
810
+    threads_cpy[1] = threads[1];
811
+    threads_cpy[2] = threads[2];
812
+    threads_cpy[3] = threads[3];
813
+    threads_cpy[4] = threads[4];
814
+    chThdSleepMilliseconds(10);
815
+    testprios[0] = threads[4]->prio;
816
+    prios[4] = prios[1];
817
+    chThdSleepMilliseconds(10);
818
+    testprios[1] = threads[4]->prio;
819
+    siblings[0] = threads[0]->children;
820
+    siblings[1] = threads[1]->sibling;
821
+    siblings[2] = threads[2]->sibling;
822
+    siblings[3] = threads[3]->sibling;
823
+    siblings[4] = threads[4]->sibling;
824
+    test_terminate_threads();
825
+    test_wait_threads();
826
+#if CH_CFG_THREADHIERARCHY_ORDERED == TRUE
827
+    test_assert(testprios[0] == chThdGetPriorityX()-2 &&
828
+                testprios[1] == prios[1] &&
829
+                siblings[0] == threads_cpy[3] &&
830
+                siblings[1] == NULL &&
831
+                siblings[2] == threads_cpy[4] &&
832
+                siblings[3] == threads_cpy[2] &&
833
+                siblings[4] == threads_cpy[1], "invalid children list");
834
+#else
835
+    test_assert(testprios[0] == chThdGetPriorityX()-2 &&
836
+                testprios[1] == prios[1] &&
837
+                siblings[0] == threads_cpy[4] &&
838
+                siblings[1] == NULL &&
839
+                siblings[2] == threads_cpy[1] &&
840
+                siblings[3] == threads_cpy[2] &&
841
+                siblings[4] == threads_cpy[3], "invalid children list");
842
+#endif
843
+  }
844
+}
845
+
846
+
847
+static const testcase_t rt_test_003_005 = {
848
+#if CH_CFG_THREADHIERARCHY_ORDERED == TRUE
849
+  "Thread hierarchy with ordered lists",
850
+#else
851
+  "Thread hierarchy with unordered lists",
852
+#endif
853
+  NULL,
854
+  NULL,
855
+  rt_test_003_005_execute
856
+};
857
+#endif /* CH_CFG_USE_THREADHIERARCHY */
858
+
859
 /****************************************************************************
860
  * Exported data.
861
  ****************************************************************************/
862 732a4657 Thomas Schöpping
@@ -338,6 +751,9 @@ const testcase_t * const rt_test_sequence_003_array[] = {
863
   &rt_test_003_003,
864 0a89baf2 Thomas Schöpping
 #if (CH_CFG_USE_MUTEXES) || defined(__DOXYGEN__)
865
   &rt_test_003_004,
866 732a4657 Thomas Schöpping
+#endif
867 0a89baf2 Thomas Schöpping
+#if (CH_CFG_USE_THREADHIERARCHY) || defined(__DOXYGEN__)
868
+  &rt_test_003_005,
869 732a4657 Thomas Schöpping
 #endif
870 0a89baf2 Thomas Schöpping
   NULL
871
 };
872
diff --git a/test/rt/source/test/rt_test_sequence_004.c b/test/rt/source/test/rt_test_sequence_004.c
873
--- a/test/rt/source/test/rt_test_sequence_004.c
874
+++ b/test/rt/source/test/rt_test_sequence_004.c
875
@@ -83,7 +83,7 @@ static void rt_test_004_001_execute(void) {
876
      and the state of the reference are tested.*/
877
   test_set_step(1);
878
   {
879
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread1, "A");
880
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread1, "A");
881
     chSysLock();
882
     msg = chThdSuspendTimeoutS(&tr1, TIME_INFINITE);
883
     chSysUnlock();
884
diff --git a/test/rt/source/test/rt_test_sequence_005.c b/test/rt/source/test/rt_test_sequence_005.c
885
--- a/test/rt/source/test/rt_test_sequence_005.c
886
+++ b/test/rt/source/test/rt_test_sequence_005.c
887
@@ -178,11 +178,11 @@ static void rt_test_005_002_execute(void) {
888
      initialized to zero.*/
889
   test_set_step(1);
890
   {
891
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, thread1, "A");
892
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+1, thread1, "B");
893
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, thread1, "C");
894
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+4, thread1, "D");
895
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+2, thread1, "E");
896
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+5, thread1, "A");
897
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()+1, thread1, "B");
898
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()+3, thread1, "C");
899
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()+4, thread1, "D");
900
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()+2, thread1, "E");
901
   }
902
 
903
   /* [5.2.2] The semaphore is signaled 5 times. The thread activation
904
@@ -248,7 +248,7 @@ static void rt_test_005_003_execute(void) {
905
   /* [5.3.2] Testing non-timeout condition.*/
906
   test_set_step(2);
907
   {
908
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
909
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
910
                                    thread2, 0);
911
     msg = chSemWaitTimeout(&sem1, TIME_MS2I(500));
912
     test_wait_threads();
913
@@ -305,7 +305,7 @@ static void rt_test_005_004_execute(void) {
914
   /* [5.4.1] A thread is created, it goes to wait on the semaphore.*/
915
   test_set_step(1);
916
   {
917
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread1, "A");
918
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread1, "A");
919
   }
920
 
921
   /* [5.4.2] The semaphore counter is increased by two, it is then
922
@@ -366,7 +366,7 @@ static void rt_test_005_005_execute(void) {
923
      non-atomical wait and signal operations on a semaphore.*/
924
   test_set_step(1);
925
   {
926
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread3, 0);
927
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread3, 0);
928
   }
929
 
930
   /* [5.5.2] The function chSemSignalWait() is invoked by specifying
931
@@ -448,7 +448,7 @@ static void rt_test_005_006_execute(void) {
932
   /* [5.6.3] Starting a signaler thread at a lower priority.*/
933
   test_set_step(3);
934
   {
935
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE,
936
+    threads[0] = test_create_thread(wa[0], WA_SIZE,
937
                                    chThdGetPriorityX()-1, thread4, &bsem);
938
   }
939
 
940
diff --git a/test/rt/source/test/rt_test_sequence_006.c b/test/rt/source/test/rt_test_sequence_006.c
941
--- a/test/rt/source/test/rt_test_sequence_006.c
942
+++ b/test/rt/source/test/rt_test_sequence_006.c
943
@@ -276,11 +276,11 @@ static void rt_test_006_001_execute(void) {
944
      priority order.*/
945
   test_set_step(3);
946
   {
947
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread1, "E");
948
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread1, "D");
949
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread1, "C");
950
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread1, "B");
951
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread1, "A");
952
+    threads[0] = test_create_thread(wa[0], WA_SIZE, prio+1, thread1, "E");
953
+    threads[1] = test_create_thread(wa[1], WA_SIZE, prio+2, thread1, "D");
954
+    threads[2] = test_create_thread(wa[2], WA_SIZE, prio+3, thread1, "C");
955
+    threads[3] = test_create_thread(wa[3], WA_SIZE, prio+4, thread1, "B");
956
+    threads[4] = test_create_thread(wa[4], WA_SIZE, prio+5, thread1, "A");
957
   }
958
 
959
   /* [6.1.4] Unlocking the mutex, the threads will wakeup in priority
960
@@ -347,9 +347,9 @@ static void rt_test_006_002_execute(void) {
961
      complete in priority order.*/
962
   test_set_step(2);
963
   {
964
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread2H, 0);
965
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-2, thread2M, 0);
966
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread2L, 0);
967
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread2H, 0);
968
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-2, thread2M, 0);
969
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread2L, 0);
970
     test_wait_threads();
971
     test_assert_sequence("ABC", "invalid sequence");
972
   }
973
@@ -418,11 +418,11 @@ static void rt_test_006_003_execute(void) {
974
      complete in priority order.*/
975
   test_set_step(2);
976
   {
977
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread3LL, 0);
978
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread3L, 0);
979
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread3M, 0);
980
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread3H, 0);
981
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread3HH, 0);
982
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread3LL, 0);
983
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread3L, 0);
984
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread3M, 0);
985
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread3H, 0);
986
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread3HH, 0);
987
     test_wait_threads();
988
     test_assert_sequence("ABCDE", "invalid sequence");
989
   }
990
@@ -501,8 +501,8 @@ static void rt_test_006_004_execute(void) {
991
   /* [6.4.2] Spawning threads A and B at priorities P(A) and P(B).*/
992
   test_set_step(2);
993
   {
994
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, pa, thread4A, "A");
995
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, pb, thread4B, "B");
996
+    threads[0] = test_create_thread(wa[0], WA_SIZE, pa, thread4A, "A");
997
+    threads[1] = test_create_thread(wa[1], WA_SIZE, pb, thread4B, "B");
998
   }
999
 
1000
   /* [6.4.3] Locking the mutex M1 before thread A has a chance to lock
1001
@@ -839,11 +839,11 @@ static void rt_test_006_007_execute(void) {
1002
   test_set_step(1);
1003
   {
1004
     tprio_t prio = chThdGetPriorityX();
1005
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread6, "E");
1006
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread6, "D");
1007
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread6, "C");
1008
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread6, "B");
1009
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread6, "A");
1010
+    threads[0] = test_create_thread(wa[0], WA_SIZE, prio+1, thread6, "E");
1011
+    threads[1] = test_create_thread(wa[1], WA_SIZE, prio+2, thread6, "D");
1012
+    threads[2] = test_create_thread(wa[2], WA_SIZE, prio+3, thread6, "C");
1013
+    threads[3] = test_create_thread(wa[3], WA_SIZE, prio+4, thread6, "B");
1014
+    threads[4] = test_create_thread(wa[4], WA_SIZE, prio+5, thread6, "A");
1015
   }
1016
 
1017
   /* [6.7.2] Atomically signaling the condition variable five times
1018
@@ -908,11 +908,11 @@ static void rt_test_006_008_execute(void) {
1019
   test_set_step(1);
1020
   {
1021
     tprio_t prio = chThdGetPriorityX();
1022
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread6, "E");
1023
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread6, "D");
1024
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread6, "C");
1025
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread6, "B");
1026
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread6, "A");
1027
+    threads[0] = test_create_thread(wa[0], WA_SIZE, prio+1, thread6, "E");
1028
+    threads[1] = test_create_thread(wa[1], WA_SIZE, prio+2, thread6, "D");
1029
+    threads[2] = test_create_thread(wa[2], WA_SIZE, prio+3, thread6, "C");
1030
+    threads[3] = test_create_thread(wa[3], WA_SIZE, prio+4, thread6, "B");
1031
+    threads[4] = test_create_thread(wa[4], WA_SIZE, prio+5, thread6, "A");
1032
   }
1033
 
1034
   /* [6.8.2] Broarcasting on the condition variable then waiting for
1035
@@ -986,21 +986,21 @@ static void rt_test_006_009_execute(void) {
1036
      M1 and goes to wait on C1.*/
1037
   test_set_step(2);
1038
   {
1039
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread8, "A");
1040
+    threads[0] = test_create_thread(wa[0], WA_SIZE, prio+1, thread8, "A");
1041
   }
1042
 
1043
   /* [6.9.3] Thread C is created at priority P(+2), it enqueues on M1
1044
      and boosts TA priority at P(+2).*/
1045
   test_set_step(3);
1046
   {
1047
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread6, "C");
1048
+    threads[1] = test_create_thread(wa[1], WA_SIZE, prio+2, thread6, "C");
1049
   }
1050
 
1051
   /* [6.9.4] Thread B is created at priority P(+3), it enqueues on M2
1052
      and boosts TA priority at P(+3).*/
1053
   test_set_step(4);
1054
   {
1055
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread9, "B");
1056
+    threads[2] = test_create_thread(wa[2], WA_SIZE, prio+3, thread9, "B");
1057
   }
1058
 
1059
   /* [6.9.5] Signaling C1: TA wakes up, unlocks M1 and priority goes to
1060
diff --git a/test/rt/source/test/rt_test_sequence_007.c b/test/rt/source/test/rt_test_sequence_007.c
1061
--- a/test/rt/source/test/rt_test_sequence_007.c
1062
+++ b/test/rt/source/test/rt_test_sequence_007.c
1063
@@ -79,7 +79,7 @@ static void rt_test_007_001_execute(void) {
1064
   /* [7.1.1] Starting the messenger thread.*/
1065
   test_set_step(1);
1066
   {
1067
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() + 1,
1068
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() + 1,
1069
                                    msg_thread1, chThdGetSelfX());
1070
   }
1071
 
1072
diff --git a/test/rt/source/test/rt_test_sequence_008.c b/test/rt/source/test/rt_test_sequence_008.c
1073
--- a/test/rt/source/test/rt_test_sequence_008.c
1074
+++ b/test/rt/source/test/rt_test_sequence_008.c
1075
@@ -226,7 +226,7 @@ static void rt_test_008_003_execute(void) {
1076
   test_set_step(3);
1077
   {
1078
     target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
1079
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1080
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1081
                                    evt_thread3, chThdGetSelfX());
1082
   }
1083
 
1084
@@ -300,7 +300,7 @@ static void rt_test_008_004_execute(void) {
1085
   test_set_step(3);
1086
   {
1087
     target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
1088
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1089
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1090
                                    evt_thread3, chThdGetSelfX());
1091
   }
1092
 
1093
@@ -381,7 +381,7 @@ static void rt_test_008_005_execute(void) {
1094
   test_set_step(4);
1095
   {
1096
     target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
1097
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1098
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1099
                                    evt_thread3, chThdGetSelfX());
1100
   }
1101
 
1102
@@ -514,7 +514,7 @@ static void rt_test_008_007_execute(void) {
1103
   test_set_step(2);
1104
   {
1105
     target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
1106
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1107
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1108
                                    evt_thread7, "A");
1109
   }
1110
 
1111
diff --git a/test/rt/source/test/rt_test_sequence_010.c b/test/rt/source/test/rt_test_sequence_010.c
1112
--- a/test/rt/source/test/rt_test_sequence_010.c
1113
+++ b/test/rt/source/test/rt_test_sequence_010.c
1114
@@ -169,7 +169,7 @@ static void rt_test_010_001_execute(void) {
1115
      the current thread.*/
1116
   test_set_step(1);
1117
   {
1118
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread1, NULL);
1119
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread1, NULL);
1120
   }
1121
 
1122
   /* [10.1.2] The number of messages exchanged is counted in a one
1123
@@ -230,7 +230,7 @@ static void rt_test_010_002_execute(void) {
1124
      than the current thread.*/
1125
   test_set_step(1);
1126
   {
1127
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
1128
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
1129
   }
1130
 
1131
   /* [10.2.2] The number of messages exchanged is counted in a one
1132
@@ -294,17 +294,17 @@ static void rt_test_010_003_execute(void) {
1133
      than the current thread.*/
1134
   test_set_step(1);
1135
   {
1136
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
1137
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
1138
   }
1139
 
1140
   /* [10.3.2] Four threads are started at a lower priority than the
1141
      current thread.*/
1142
   test_set_step(2);
1143
   {
1144
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-2, bmk_thread3, NULL);
1145
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, bmk_thread3, NULL);
1146
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-4, bmk_thread3, NULL);
1147
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-5, bmk_thread3, NULL);
1148
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-2, bmk_thread3, NULL);
1149
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-3, bmk_thread3, NULL);
1150
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()-4, bmk_thread3, NULL);
1151
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()-5, bmk_thread3, NULL);
1152
   }
1153
 
1154
   /* [10.3.3] The number of messages exchanged is counted in a one
1155
@@ -360,7 +360,7 @@ static void rt_test_010_004_execute(void) {
1156
   /* [10.4.1] Starting the target thread at an higher priority level.*/
1157
   test_set_step(1);
1158
   {
1159
-    tp = threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1,
1160
+    tp = threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+1,
1161
                                         bmk_thread4, NULL);
1162
   }
1163
 
1164
@@ -444,7 +444,7 @@ static void rt_test_010_005_execute(void) {
1165
     start = test_wait_tick();
1166
     end = chTimeAddX(start, TIME_MS2I(1000));
1167
     do {
1168
-      chThdWait(chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
1169
+      chThdWait(test_create_thread(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
1170
       n++;
1171
 #if defined(SIMULATOR)
1172
       _sim_check_for_interrupts();
1173
@@ -502,9 +502,9 @@ static void rt_test_010_006_execute(void) {
1174
     end = chTimeAddX(start, TIME_MS2I(1000));
1175
     do {
1176
 #if CH_CFG_USE_REGISTRY
1177
-      chThdRelease(chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
1178
+      chThdRelease(test_create_thread(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
1179
 #else
1180
-      chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL);
1181
+      test_create_thread(wa[0], WA_SIZE, prio, bmk_thread3, NULL);
1182
 #endif
1183
       n++;
1184
 #if defined(SIMULATOR)
1185
@@ -566,11 +566,11 @@ static void rt_test_010_007_execute(void) {
1186
      immediately enqueue on a semaphore.*/
1187
   test_set_step(1);
1188
   {
1189
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, bmk_thread7, NULL);
1190
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+4, bmk_thread7, NULL);
1191
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, bmk_thread7, NULL);
1192
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+2, bmk_thread7, NULL);
1193
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+1, bmk_thread7, NULL);
1194
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+5, bmk_thread7, NULL);
1195
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()+4, bmk_thread7, NULL);
1196
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()+3, bmk_thread7, NULL);
1197
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()+2, bmk_thread7, NULL);
1198
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()+1, bmk_thread7, NULL);
1199
   }
1200
 
1201
   /* [10.7.2] The semaphore is reset waking up the five threads. The
1202
@@ -645,12 +645,12 @@ static void rt_test_010_008_execute(void) {
1203
   test_set_step(1);
1204
   {
1205
     n = 0;
1206
-    test_wait_tick();threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1207
+    test_wait_tick();threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1208
 
1209
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1210
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1211
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1212
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1213
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1214
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1215
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1216
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1217
   }
1218
 
1219
   /* [10.8.2] Waiting one second then terminating the 5 threads.*/