Statistics
| Branch: | Tag: | Revision:

amiro-os / kernel / patches / introduce-thread-hierarchy.patch @ 232ccea6

History | View | Annotate | Download (51.951 KB)

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