Revision 0a89baf2

View differences:

core/src/aos_system.c
818 818

  
819 819
#if (AMIROOS_CFG_SHELL_ENABLE == true)
820 820
  // start system shell thread
821
#if (CH_CFG_USE_THREADHIERARCHY == TRUE)
822
  aos.shell.thread = chThdCreateStatic(_shell_wa, sizeof(_shell_wa), AMIROOS_CFG_SHELL_THREADPRIO, aosShellThread, &aos.shell, &ch.mainthread);
823
#else
821 824
  aos.shell.thread = chThdCreateStatic(_shell_wa, sizeof(_shell_wa), AMIROOS_CFG_SHELL_THREADPRIO, aosShellThread, &aos.shell);
822 825
#endif
826
#endif
823 827

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

  
170 170
/**
171
 * @brief   Thread hierarchy APIs.
172
 * @details Id enabled then the thread hierarchy APIs are included in the kernel.
173
 *
174
 * @note    The default is @p FALSE.
175
 */
176
#define CH_CFG_USE_THREADHIERARCHY          TRUE
177

  
178
/**
179
 * @brief   Enable ordering of child lists.
180
 * @details Children will be ordered by their priority (descending).
181
 *          If sibliblings have identical priority, they are ordered by age (descending).
182
 */
183
#define CH_CFG_THREADHIERARCHY_ORDERED      TRUE
184

  
185
/**
171 186
 * @brief   Threads synchronization APIs.
172 187
 * @details If enabled then the @p chThdWait() function is included in
173 188
 *          the kernel.

Also available in: Unified diff