Statistics
| Branch: | Tag: | Revision:

amiro-os / kernel / patches / introduce-thread-hierarchy.patch @ 10fd7ac9

History | View | Annotate | Download (52 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 +244,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 +358,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 +374,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 +424,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 +599,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 +704,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,408 @@ 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
+    test_terminate_threads();
515
+    test_wait_threads();
516
+    test_assert(parents[0] == chThdGetSelfX() &&
517
+                parents[1] == threads_cpy[0] &&
518
+                parents[2] == threads_cpy[0] &&
519
+                parents[3] == threads_cpy[0] &&
520
+                parents[4] == threads_cpy[0] &&
521
+                siblings[0] == threads_cpy[4] &&
522
+                siblings[1] == NULL &&
523
+                siblings[2] == threads_cpy[1] &&
524
+                siblings[3] == threads_cpy[2] &&
525
+                siblings[4] == threads_cpy[3], "invalid children list");
526
+  }
527
+
528
+  /* [3.5.2] Creating 1 parent and 4 child threads with decreasing priority,
529
+   * hierarchy information is tested.*/
530
+  test_set_step(2);
531
+  {
532
+    tprio_t prios[MAX_THREADS];
533
+    thread_t *threads_cpy[MAX_THREADS];
534
+    thread_t *parents[MAX_THREADS];
535
+    thread_t *siblings[MAX_THREADS];
536
+    prios[0] = chThdGetPriorityX()-1;
537
+    prios[1] = chThdGetPriorityX()-2;
538
+    prios[2] = chThdGetPriorityX()-3;
539
+    prios[3] = chThdGetPriorityX()-4;
540
+    prios[4] = chThdGetPriorityX()-5;
541
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
542
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
543
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
544
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
545
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
546
+    threads_cpy[0] = threads[0];
547
+    threads_cpy[1] = threads[1];
548
+    threads_cpy[2] = threads[2];
549
+    threads_cpy[3] = threads[3];
550
+    threads_cpy[4] = threads[4];
551
+    parents[0] = threads[0]->parent;
552
+    parents[1] = threads[1]->parent;
553
+    parents[2] = threads[2]->parent;
554
+    parents[3] = threads[3]->parent;
555
+    parents[4] = threads[4]->parent;
556
+    siblings[0] = threads[0]->children;
557
+    siblings[1] = threads[1]->sibling;
558
+    siblings[2] = threads[2]->sibling;
559
+    siblings[3] = threads[3]->sibling;
560
+    siblings[4] = threads[4]->sibling;
561
+    test_terminate_threads();
562
+    test_wait_threads();
563
+#if CH_CFG_THREADHIERARCHY_ORDERED == TRUE
564
+    test_assert(parents[0] == chThdGetSelfX() &&
565
+                parents[1] == threads_cpy[0] &&
566
+                parents[2] == threads_cpy[0] &&
567
+                parents[3] == threads_cpy[0] &&
568
+                parents[4] == threads_cpy[0] &&
569
+                siblings[0] == threads_cpy[1] &&
570
+                siblings[1] == threads_cpy[2] &&
571
+                siblings[2] == threads_cpy[3] &&
572
+                siblings[3] == threads_cpy[4] &&
573
+                siblings[4] == NULL, "invalid children list");
574
+#else
575
+    test_assert(parents[0] == chThdGetSelfX() &&
576
+                parents[1] == threads_cpy[0] &&
577
+                parents[2] == threads_cpy[0] &&
578
+                parents[3] == threads_cpy[0] &&
579
+                parents[4] == threads_cpy[0] &&
580
+                siblings[0] == threads_cpy[4] &&
581
+                siblings[4] == threads_cpy[3] &&
582
+                siblings[3] == threads_cpy[2] &&
583
+                siblings[2] == threads_cpy[1] &&
584
+                siblings[1] == NULL, "invalid children list");
585
+#endif
586
+  }
587
+
588
+  /* [3.5.3] Creating 1 parent and 4 child threads with identical priority,
589
+   * hierarchy information is tested.*/
590
+  test_set_step(3);
591
+  {
592
+    tprio_t prios[MAX_THREADS];
593
+    thread_t *threads_cpy[MAX_THREADS];
594
+    thread_t *parents[MAX_THREADS];
595
+    thread_t *siblings[MAX_THREADS];
596
+    prios[0] = chThdGetPriorityX()-1;
597
+    prios[1] = chThdGetPriorityX()-2;
598
+    prios[2] = chThdGetPriorityX()-2;
599
+    prios[3] = chThdGetPriorityX()-2;
600
+    prios[4] = chThdGetPriorityX()-2;
601
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
602
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
603
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
604
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
605
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
606
+    threads_cpy[0] = threads[0];
607
+    threads_cpy[1] = threads[1];
608
+    threads_cpy[2] = threads[2];
609
+    threads_cpy[3] = threads[3];
610
+    threads_cpy[4] = threads[4];
611
+    parents[0] = threads[0]->parent;
612
+    parents[1] = threads[1]->parent;
613
+    parents[2] = threads[2]->parent;
614
+    parents[3] = threads[3]->parent;
615
+    parents[4] = threads[4]->parent;
616
+    siblings[0] = threads[0]->children;
617
+    siblings[1] = threads[1]->sibling;
618
+    siblings[2] = threads[2]->sibling;
619
+    siblings[3] = threads[3]->sibling;
620
+    siblings[4] = threads[4]->sibling;
621
+    test_terminate_threads();
622
+    test_wait_threads();
623
+    test_assert(parents[0] == chThdGetSelfX() &&
624
+                parents[1] == threads_cpy[0] &&
625
+                parents[2] == threads_cpy[0] &&
626
+                parents[3] == threads_cpy[0] &&
627
+                parents[4] == threads_cpy[0] &&
628
+                siblings[0] == threads_cpy[4] &&
629
+                siblings[1] == NULL &&
630
+                siblings[2] == threads_cpy[1] &&
631
+                siblings[3] == threads_cpy[2] &&
632
+                siblings[4] == threads_cpy[3] , "invalid children list");
633
+  }
634
+
635
+  /* [3.5.4] Creating 1 parent and 4 child threads with increasing priority
636
+   * which are terminated in a controlled manner, hierarchy information is
637
+   * tested.*/
638
+  test_set_step(4);
639
+  {
640
+    tprio_t prios[MAX_THREADS];
641
+    thread_t *threads_cpy[MAX_THREADS];
642
+    thread_t *parents[MAX_THREADS];
643
+    thread_t *siblings[MAX_THREADS];
644
+    prios[0] = chThdGetPriorityX()-1;
645
+    prios[1] = chThdGetPriorityX()-5;
646
+    prios[2] = chThdGetPriorityX()-4;
647
+    prios[3] = chThdGetPriorityX()-3;
648
+    prios[4] = chThdGetPriorityX()-2;
649
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
650
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
651
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
652
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
653
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
654
+    threads_cpy[0] = threads[0];
655
+    threads_cpy[1] = threads[1];
656
+    threads_cpy[2] = threads[2];
657
+    threads_cpy[3] = threads[3];
658
+    threads_cpy[4] = threads[4];
659
+#if CH_CFG_USE_REGISTRY == TRUE
660
+    chThdAddRef(threads[1]);
661
+    chThdAddRef(threads[4]);
662
+#endif
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
+#if CH_CFG_USE_REGISTRY == TRUE
711
+    chThdAddRef(threads[0]);
712
+#endif
713
+    chThdTerminate(threads[0]);
714
+    chThdWait(threads[0]);
715
+    parents[0] = threads_cpy[0]->parent;
716
+    parents[1] = threads_cpy[1]->parent;
717
+    parents[2] = threads_cpy[2]->parent;
718
+    parents[3] = threads_cpy[3]->parent;
719
+    parents[4] = threads_cpy[4]->parent;
720
+    for (thread_t* sibling = ch.mainthread.children; sibling != NULL; sibling = sibling->sibling) {
721
+      thdmask |= (sibling == threads[0]) ? 1 << 0 : 0;
722
+      thdmask |= (sibling == threads[1]) ? 1 << 1 : 0;
723
+      thdmask |= (sibling == threads[2]) ? 1 << 2 : 0;
724
+      thdmask |= (sibling == threads[3]) ? 1 << 3 : 0;
725
+      thdmask |= (sibling == threads[4]) ? 1 << 4 : 0;
726
+    }
727
+    test_terminate_threads();
728
+    test_wait_threads();
729
+    test_assert(parents[1] == &ch.mainthread &&
730
+                parents[2] == &ch.mainthread &&
731
+                parents[3] == &ch.mainthread &&
732
+                parents[4] == &ch.mainthread &&
733
+                thdmask == ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)), "child thread recovery failed");
734
+  }
735
+
736
+  /* [3.5.6] Creating 1 parent and 4 child threads with increasing priority
737
+   * and then increasing the priority of a low-priority child, hierarchy
738
+   * information is tested.*/
739
+  test_set_step(6);
740
+  {
741
+    tprio_t prios[MAX_THREADS];
742
+    thread_t *threads_cpy[MAX_THREADS];
743
+    tprio_t testprios[2];
744
+    thread_t *siblings[MAX_THREADS];
745
+    prios[0] = chThdGetPriorityX()-1;
746
+    prios[1] = chThdGetPriorityX()-5;
747
+    prios[2] = chThdGetPriorityX()-4;
748
+    prios[3] = chThdGetPriorityX()-3;
749
+    prios[4] = chThdGetPriorityX()-2;
750
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
751
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
752
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
753
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
754
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
755
+    threads_cpy[0] = threads[0];
756
+    threads_cpy[1] = threads[1];
757
+    threads_cpy[2] = threads[2];
758
+    threads_cpy[3] = threads[3];
759
+    threads_cpy[4] = threads[4];
760
+    chThdSleepMilliseconds(10);
761
+    testprios[0] = threads[1]->prio;
762
+    prios[1] = prios[4];
763
+    chThdSleepMilliseconds(10);
764
+    testprios[1] = threads[1]->prio;
765
+    siblings[0] = threads[0]->children;
766
+    siblings[1] = threads[1]->sibling;
767
+    siblings[2] = threads[2]->sibling;
768
+    siblings[3] = threads[3]->sibling;
769
+    siblings[4] = threads[4]->sibling;
770
+    test_terminate_threads();
771
+    test_wait_threads();
772
+#if CH_CFG_THREADHIERARCHY_ORDERED == TRUE
773
+    test_assert(testprios[0] == chThdGetPriorityX()-5 &&
774
+                testprios[1] == prios[4] &&
775
+                siblings[0] == threads_cpy[1] &&
776
+                siblings[1] == threads_cpy[4] &&
777
+                siblings[2] == NULL &&
778
+                siblings[3] == threads_cpy[2] &&
779
+                siblings[4] == threads_cpy[3], "invalid children list");
780
+#else
781
+    test_assert(testprios[0] == chThdGetPriorityX()-5 &&
782
+                testprios[1] == prios[4] &&
783
+                siblings[0] == threads_cpy[4] &&
784
+                siblings[1] == NULL &&
785
+                siblings[2] == threads_cpy[1] &&
786
+                siblings[3] == threads_cpy[2] &&
787
+                siblings[4] == threads_cpy[3], "invalid children list");
788
+#endif
789
+  }
790
+
791
+  /* [3.5.7] Creating 1 parent and 4 child threads with increasing priority
792
+   * and the decreasing the priority of a high-priority child, hierarchy
793
+   * information is tested.*/
794
+  test_set_step(7);
795
+  {
796
+    tprio_t prios[MAX_THREADS];
797
+    thread_t *threads_cpy[MAX_THREADS];
798
+    tprio_t testprios[2];
799
+    thread_t *siblings[MAX_THREADS];
800
+    prios[0] = chThdGetPriorityX()-1;
801
+    prios[1] = chThdGetPriorityX()-5;
802
+    prios[2] = chThdGetPriorityX()-4;
803
+    prios[3] = chThdGetPriorityX()-3;
804
+    prios[4] = chThdGetPriorityX()-2;
805
+    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prios[0], hierarchythread, &prios[0], chThdGetSelfX());
806
+    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prios[1], hierarchythread, &prios[1], threads[0]);
807
+    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prios[2], hierarchythread, &prios[2], threads[0]);
808
+    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prios[3], hierarchythread, &prios[3], threads[0]);
809
+    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prios[4], hierarchythread, &prios[4], threads[0]);
810
+    threads_cpy[0] = threads[0];
811
+    threads_cpy[1] = threads[1];
812
+    threads_cpy[2] = threads[2];
813
+    threads_cpy[3] = threads[3];
814
+    threads_cpy[4] = threads[4];
815
+    chThdSleepMilliseconds(10);
816
+    testprios[0] = threads[4]->prio;
817
+    prios[4] = prios[1];
818
+    chThdSleepMilliseconds(10);
819
+    testprios[1] = threads[4]->prio;
820
+    siblings[0] = threads[0]->children;
821
+    siblings[1] = threads[1]->sibling;
822
+    siblings[2] = threads[2]->sibling;
823
+    siblings[3] = threads[3]->sibling;
824
+    siblings[4] = threads[4]->sibling;
825
+    test_terminate_threads();
826
+    test_wait_threads();
827
+#if CH_CFG_THREADHIERARCHY_ORDERED == TRUE
828
+    test_assert(testprios[0] == chThdGetPriorityX()-2 &&
829
+                testprios[1] == prios[1] &&
830
+                siblings[0] == threads_cpy[3] &&
831
+                siblings[1] == NULL &&
832
+                siblings[2] == threads_cpy[4] &&
833
+                siblings[3] == threads_cpy[2] &&
834
+                siblings[4] == threads_cpy[1], "invalid children list");
835
+#else
836
+    test_assert(testprios[0] == chThdGetPriorityX()-2 &&
837
+                testprios[1] == prios[1] &&
838
+                siblings[0] == threads_cpy[4] &&
839
+                siblings[1] == NULL &&
840
+                siblings[2] == threads_cpy[1] &&
841
+                siblings[3] == threads_cpy[2] &&
842
+                siblings[4] == threads_cpy[3], "invalid children list");
843
+#endif
844
+  }
845
+}
846
+
847
+
848
+static const testcase_t rt_test_003_005 = {
849
+#if CH_CFG_THREADHIERARCHY_ORDERED == TRUE
850
+  "Thread hierarchy with ordered lists",
851
+#else
852
+  "Thread hierarchy with unordered lists",
853
+#endif
854
+  NULL,
855
+  NULL,
856
+  rt_test_003_005_execute
857
+};
858
+#endif /* CH_CFG_USE_THREADHIERARCHY */
859
+
860
 /****************************************************************************
861
  * Exported data.
862
  ****************************************************************************/
863
@@ -338,6 +754,9 @@ const testcase_t * const rt_test_sequence_003_array[] = {
864
   &rt_test_003_003,
865
 #if (CH_CFG_USE_MUTEXES) || defined(__DOXYGEN__)
866
   &rt_test_003_004,
867
+#endif
868
+#if (CH_CFG_USE_THREADHIERARCHY) || defined(__DOXYGEN__)
869
+  &rt_test_003_005,
870
 #endif
871
   NULL
872
 };
873
diff --git a/test/rt/source/test/rt_test_sequence_004.c b/test/rt/source/test/rt_test_sequence_004.c
874
--- a/test/rt/source/test/rt_test_sequence_004.c
875
+++ b/test/rt/source/test/rt_test_sequence_004.c
876
@@ -83,7 +83,7 @@ static void rt_test_004_001_execute(void) {
877
      and the state of the reference are tested.*/
878
   test_set_step(1);
879
   {
880
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread1, "A");
881
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread1, "A");
882
     chSysLock();
883
     msg = chThdSuspendTimeoutS(&tr1, TIME_INFINITE);
884
     chSysUnlock();
885
diff --git a/test/rt/source/test/rt_test_sequence_005.c b/test/rt/source/test/rt_test_sequence_005.c
886
--- a/test/rt/source/test/rt_test_sequence_005.c
887
+++ b/test/rt/source/test/rt_test_sequence_005.c
888
@@ -178,11 +178,11 @@ static void rt_test_005_002_execute(void) {
889
      initialized to zero.*/
890
   test_set_step(1);
891
   {
892
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, thread1, "A");
893
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+1, thread1, "B");
894
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, thread1, "C");
895
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+4, thread1, "D");
896
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+2, thread1, "E");
897
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+5, thread1, "A");
898
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()+1, thread1, "B");
899
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()+3, thread1, "C");
900
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()+4, thread1, "D");
901
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()+2, thread1, "E");
902
   }
903
 
904
   /* [5.2.2] The semaphore is signaled 5 times. The thread activation
905
@@ -248,7 +248,7 @@ static void rt_test_005_003_execute(void) {
906
   /* [5.3.2] Testing non-timeout condition.*/
907
   test_set_step(2);
908
   {
909
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
910
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
911
                                    thread2, 0);
912
     msg = chSemWaitTimeout(&sem1, TIME_MS2I(500));
913
     test_wait_threads();
914
@@ -305,7 +305,7 @@ static void rt_test_005_004_execute(void) {
915
   /* [5.4.1] A thread is created, it goes to wait on the semaphore.*/
916
   test_set_step(1);
917
   {
918
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread1, "A");
919
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread1, "A");
920
   }
921
 
922
   /* [5.4.2] The semaphore counter is increased by two, it is then
923
@@ -366,7 +366,7 @@ static void rt_test_005_005_execute(void) {
924
      non-atomical wait and signal operations on a semaphore.*/
925
   test_set_step(1);
926
   {
927
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread3, 0);
928
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread3, 0);
929
   }
930
 
931
   /* [5.5.2] The function chSemSignalWait() is invoked by specifying
932
@@ -448,7 +448,7 @@ static void rt_test_005_006_execute(void) {
933
   /* [5.6.3] Starting a signaler thread at a lower priority.*/
934
   test_set_step(3);
935
   {
936
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE,
937
+    threads[0] = test_create_thread(wa[0], WA_SIZE,
938
                                    chThdGetPriorityX()-1, thread4, &bsem);
939
   }
940
 
941
diff --git a/test/rt/source/test/rt_test_sequence_006.c b/test/rt/source/test/rt_test_sequence_006.c
942
--- a/test/rt/source/test/rt_test_sequence_006.c
943
+++ b/test/rt/source/test/rt_test_sequence_006.c
944
@@ -276,11 +276,11 @@ static void rt_test_006_001_execute(void) {
945
      priority order.*/
946
   test_set_step(3);
947
   {
948
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread1, "E");
949
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread1, "D");
950
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread1, "C");
951
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread1, "B");
952
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread1, "A");
953
+    threads[0] = test_create_thread(wa[0], WA_SIZE, prio+1, thread1, "E");
954
+    threads[1] = test_create_thread(wa[1], WA_SIZE, prio+2, thread1, "D");
955
+    threads[2] = test_create_thread(wa[2], WA_SIZE, prio+3, thread1, "C");
956
+    threads[3] = test_create_thread(wa[3], WA_SIZE, prio+4, thread1, "B");
957
+    threads[4] = test_create_thread(wa[4], WA_SIZE, prio+5, thread1, "A");
958
   }
959
 
960
   /* [6.1.4] Unlocking the mutex, the threads will wakeup in priority
961
@@ -347,9 +347,9 @@ static void rt_test_006_002_execute(void) {
962
      complete in priority order.*/
963
   test_set_step(2);
964
   {
965
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread2H, 0);
966
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-2, thread2M, 0);
967
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread2L, 0);
968
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-1, thread2H, 0);
969
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-2, thread2M, 0);
970
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread2L, 0);
971
     test_wait_threads();
972
     test_assert_sequence("ABC", "invalid sequence");
973
   }
974
@@ -418,11 +418,11 @@ static void rt_test_006_003_execute(void) {
975
      complete in priority order.*/
976
   test_set_step(2);
977
   {
978
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread3LL, 0);
979
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread3L, 0);
980
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread3M, 0);
981
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread3H, 0);
982
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread3HH, 0);
983
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread3LL, 0);
984
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-4, thread3L, 0);
985
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread3M, 0);
986
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread3H, 0);
987
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread3HH, 0);
988
     test_wait_threads();
989
     test_assert_sequence("ABCDE", "invalid sequence");
990
   }
991
@@ -501,8 +501,8 @@ static void rt_test_006_004_execute(void) {
992
   /* [6.4.2] Spawning threads A and B at priorities P(A) and P(B).*/
993
   test_set_step(2);
994
   {
995
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, pa, thread4A, "A");
996
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, pb, thread4B, "B");
997
+    threads[0] = test_create_thread(wa[0], WA_SIZE, pa, thread4A, "A");
998
+    threads[1] = test_create_thread(wa[1], WA_SIZE, pb, thread4B, "B");
999
   }
1000
 
1001
   /* [6.4.3] Locking the mutex M1 before thread A has a chance to lock
1002
@@ -839,11 +839,11 @@ static void rt_test_006_007_execute(void) {
1003
   test_set_step(1);
1004
   {
1005
     tprio_t prio = chThdGetPriorityX();
1006
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread6, "E");
1007
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread6, "D");
1008
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread6, "C");
1009
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread6, "B");
1010
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread6, "A");
1011
+    threads[0] = test_create_thread(wa[0], WA_SIZE, prio+1, thread6, "E");
1012
+    threads[1] = test_create_thread(wa[1], WA_SIZE, prio+2, thread6, "D");
1013
+    threads[2] = test_create_thread(wa[2], WA_SIZE, prio+3, thread6, "C");
1014
+    threads[3] = test_create_thread(wa[3], WA_SIZE, prio+4, thread6, "B");
1015
+    threads[4] = test_create_thread(wa[4], WA_SIZE, prio+5, thread6, "A");
1016
   }
1017
 
1018
   /* [6.7.2] Atomically signaling the condition variable five times
1019
@@ -908,11 +908,11 @@ static void rt_test_006_008_execute(void) {
1020
   test_set_step(1);
1021
   {
1022
     tprio_t prio = chThdGetPriorityX();
1023
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread6, "E");
1024
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread6, "D");
1025
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread6, "C");
1026
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, prio+4, thread6, "B");
1027
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, prio+5, thread6, "A");
1028
+    threads[0] = test_create_thread(wa[0], WA_SIZE, prio+1, thread6, "E");
1029
+    threads[1] = test_create_thread(wa[1], WA_SIZE, prio+2, thread6, "D");
1030
+    threads[2] = test_create_thread(wa[2], WA_SIZE, prio+3, thread6, "C");
1031
+    threads[3] = test_create_thread(wa[3], WA_SIZE, prio+4, thread6, "B");
1032
+    threads[4] = test_create_thread(wa[4], WA_SIZE, prio+5, thread6, "A");
1033
   }
1034
 
1035
   /* [6.8.2] Broarcasting on the condition variable then waiting for
1036
@@ -986,21 +986,21 @@ static void rt_test_006_009_execute(void) {
1037
      M1 and goes to wait on C1.*/
1038
   test_set_step(2);
1039
   {
1040
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, prio+1, thread8, "A");
1041
+    threads[0] = test_create_thread(wa[0], WA_SIZE, prio+1, thread8, "A");
1042
   }
1043
 
1044
   /* [6.9.3] Thread C is created at priority P(+2), it enqueues on M1
1045
      and boosts TA priority at P(+2).*/
1046
   test_set_step(3);
1047
   {
1048
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, prio+2, thread6, "C");
1049
+    threads[1] = test_create_thread(wa[1], WA_SIZE, prio+2, thread6, "C");
1050
   }
1051
 
1052
   /* [6.9.4] Thread B is created at priority P(+3), it enqueues on M2
1053
      and boosts TA priority at P(+3).*/
1054
   test_set_step(4);
1055
   {
1056
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, prio+3, thread9, "B");
1057
+    threads[2] = test_create_thread(wa[2], WA_SIZE, prio+3, thread9, "B");
1058
   }
1059
 
1060
   /* [6.9.5] Signaling C1: TA wakes up, unlocks M1 and priority goes to
1061
diff --git a/test/rt/source/test/rt_test_sequence_007.c b/test/rt/source/test/rt_test_sequence_007.c
1062
--- a/test/rt/source/test/rt_test_sequence_007.c
1063
+++ b/test/rt/source/test/rt_test_sequence_007.c
1064
@@ -79,7 +79,7 @@ static void rt_test_007_001_execute(void) {
1065
   /* [7.1.1] Starting the messenger thread.*/
1066
   test_set_step(1);
1067
   {
1068
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() + 1,
1069
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() + 1,
1070
                                    msg_thread1, chThdGetSelfX());
1071
   }
1072
 
1073
diff --git a/test/rt/source/test/rt_test_sequence_008.c b/test/rt/source/test/rt_test_sequence_008.c
1074
--- a/test/rt/source/test/rt_test_sequence_008.c
1075
+++ b/test/rt/source/test/rt_test_sequence_008.c
1076
@@ -226,7 +226,7 @@ static void rt_test_008_003_execute(void) {
1077
   test_set_step(3);
1078
   {
1079
     target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
1080
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1081
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1082
                                    evt_thread3, chThdGetSelfX());
1083
   }
1084
 
1085
@@ -300,7 +300,7 @@ static void rt_test_008_004_execute(void) {
1086
   test_set_step(3);
1087
   {
1088
     target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
1089
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1090
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1091
                                    evt_thread3, chThdGetSelfX());
1092
   }
1093
 
1094
@@ -381,7 +381,7 @@ static void rt_test_008_005_execute(void) {
1095
   test_set_step(4);
1096
   {
1097
     target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
1098
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1099
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1100
                                    evt_thread3, chThdGetSelfX());
1101
   }
1102
 
1103
@@ -514,7 +514,7 @@ static void rt_test_008_007_execute(void) {
1104
   test_set_step(2);
1105
   {
1106
     target_time = chTimeAddX(test_wait_tick(), TIME_MS2I(50));
1107
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1108
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
1109
                                    evt_thread7, "A");
1110
   }
1111
 
1112
diff --git a/test/rt/source/test/rt_test_sequence_010.c b/test/rt/source/test/rt_test_sequence_010.c
1113
--- a/test/rt/source/test/rt_test_sequence_010.c
1114
+++ b/test/rt/source/test/rt_test_sequence_010.c
1115
@@ -169,7 +169,7 @@ static void rt_test_010_001_execute(void) {
1116
      the current thread.*/
1117
   test_set_step(1);
1118
   {
1119
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread1, NULL);
1120
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread1, NULL);
1121
   }
1122
 
1123
   /* [10.1.2] The number of messages exchanged is counted in a one
1124
@@ -230,7 +230,7 @@ static void rt_test_010_002_execute(void) {
1125
      than the current thread.*/
1126
   test_set_step(1);
1127
   {
1128
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
1129
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
1130
   }
1131
 
1132
   /* [10.2.2] The number of messages exchanged is counted in a one
1133
@@ -294,17 +294,17 @@ static void rt_test_010_003_execute(void) {
1134
      than the current thread.*/
1135
   test_set_step(1);
1136
   {
1137
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
1138
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
1139
   }
1140
 
1141
   /* [10.3.2] Four threads are started at a lower priority than the
1142
      current thread.*/
1143
   test_set_step(2);
1144
   {
1145
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-2, bmk_thread3, NULL);
1146
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, bmk_thread3, NULL);
1147
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-4, bmk_thread3, NULL);
1148
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-5, bmk_thread3, NULL);
1149
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-2, bmk_thread3, NULL);
1150
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-3, bmk_thread3, NULL);
1151
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()-4, bmk_thread3, NULL);
1152
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()-5, bmk_thread3, NULL);
1153
   }
1154
 
1155
   /* [10.3.3] The number of messages exchanged is counted in a one
1156
@@ -360,7 +360,7 @@ static void rt_test_010_004_execute(void) {
1157
   /* [10.4.1] Starting the target thread at an higher priority level.*/
1158
   test_set_step(1);
1159
   {
1160
-    tp = threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1,
1161
+    tp = threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+1,
1162
                                         bmk_thread4, NULL);
1163
   }
1164
 
1165
@@ -444,7 +444,7 @@ static void rt_test_010_005_execute(void) {
1166
     start = test_wait_tick();
1167
     end = chTimeAddX(start, TIME_MS2I(1000));
1168
     do {
1169
-      chThdWait(chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
1170
+      chThdWait(test_create_thread(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
1171
       n++;
1172
 #if defined(SIMULATOR)
1173
       _sim_check_for_interrupts();
1174
@@ -502,9 +502,9 @@ static void rt_test_010_006_execute(void) {
1175
     end = chTimeAddX(start, TIME_MS2I(1000));
1176
     do {
1177
 #if CH_CFG_USE_REGISTRY
1178
-      chThdRelease(chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
1179
+      chThdRelease(test_create_thread(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
1180
 #else
1181
-      chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL);
1182
+      test_create_thread(wa[0], WA_SIZE, prio, bmk_thread3, NULL);
1183
 #endif
1184
       n++;
1185
 #if defined(SIMULATOR)
1186
@@ -566,11 +566,11 @@ static void rt_test_010_007_execute(void) {
1187
      immediately enqueue on a semaphore.*/
1188
   test_set_step(1);
1189
   {
1190
-    threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, bmk_thread7, NULL);
1191
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+4, bmk_thread7, NULL);
1192
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, bmk_thread7, NULL);
1193
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+2, bmk_thread7, NULL);
1194
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+1, bmk_thread7, NULL);
1195
+    threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()+5, bmk_thread7, NULL);
1196
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()+4, bmk_thread7, NULL);
1197
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()+3, bmk_thread7, NULL);
1198
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()+2, bmk_thread7, NULL);
1199
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()+1, bmk_thread7, NULL);
1200
   }
1201
 
1202
   /* [10.7.2] The semaphore is reset waking up the five threads. The
1203
@@ -645,12 +645,12 @@ static void rt_test_010_008_execute(void) {
1204
   test_set_step(1);
1205
   {
1206
     n = 0;
1207
-    test_wait_tick();threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1208
+    test_wait_tick();threads[0] = test_create_thread(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1209
 
1210
-    threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1211
-    threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1212
-    threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1213
-    threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1214
+    threads[1] = test_create_thread(wa[1], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1215
+    threads[2] = test_create_thread(wa[2], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1216
+    threads[3] = test_create_thread(wa[3], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1217
+    threads[4] = test_create_thread(wa[4], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
1218
   }
1219
 
1220
   /* [10.8.2] Waiting one second then terminating the 5 threads.*/
1221
-- 
1222
2.17.1
1223