source: rtems/testsuites/sptests/spmutex01/init.c @ 300f6a48

5
Last change on this file since 300f6a48 was 300f6a48, checked in by Sebastian Huber <sebastian.huber@…>, on 06/22/16 at 15:09:23

score: Rework thread priority management

Add priority nodes which contribute to the overall thread priority.

The actual priority of a thread is now an aggregation of priority nodes.
The thread priority aggregation for the home scheduler instance of a
thread consists of at least one priority node, which is normally the
real priority of the thread. The locking protocols (e.g. priority
ceiling and priority inheritance), rate-monotonic period objects and the
POSIX sporadic server add, change and remove priority nodes.

A thread changes its priority now immediately, e.g. priority changes are
not deferred until the thread releases its last resource.

Replace the _Thread_Change_priority() function with

  • _Thread_Priority_perform_actions(),
  • _Thread_Priority_add(),
  • _Thread_Priority_remove(),
  • _Thread_Priority_change(), and
  • _Thread_Priority_update().

Update #2412.
Update #2556.

  • Property mode set to 100644
File size: 16.8 KB
Line 
1/*
2 * Copyright (c) 2015, 2016 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <threads.h>
20#include <setjmp.h>
21
22#include <rtems.h>
23#include <rtems/libcsupport.h>
24
25#ifdef RTEMS_POSIX_API
26#include <errno.h>
27#include <pthread.h>
28#endif
29
30#include "tmacros.h"
31
32const char rtems_test_name[] = "SPMUTEX 1";
33
34#define TASK_COUNT 5
35
36#define MTX_COUNT 3
37
38typedef enum {
39  REQ_WAKE_UP_MASTER = RTEMS_EVENT_0,
40  REQ_WAKE_UP_HELPER = RTEMS_EVENT_1,
41  REQ_MTX_0_OBTAIN = RTEMS_EVENT_2,
42  REQ_MTX_0_RELEASE = RTEMS_EVENT_3,
43  REQ_MTX_1_OBTAIN = RTEMS_EVENT_4,
44  REQ_MTX_1_OBTAIN_TIMEOUT = RTEMS_EVENT_5,
45  REQ_MTX_1_RELEASE = RTEMS_EVENT_6,
46  REQ_MTX_2_OBTAIN = RTEMS_EVENT_7,
47  REQ_MTX_2_RELEASE = RTEMS_EVENT_8,
48  REQ_MTX_C11_OBTAIN = RTEMS_EVENT_9,
49  REQ_MTX_C11_RELEASE = RTEMS_EVENT_10,
50  REQ_MTX_POSIX_OBTAIN = RTEMS_EVENT_11,
51  REQ_MTX_POSIX_RELEASE = RTEMS_EVENT_12
52} request_id;
53
54typedef enum {
55  M,
56  A_1,
57  A_2_0,
58  A_2_1,
59  H,
60  NONE
61} task_id;
62
63typedef enum {
64  MTX_0,
65  MTX_1,
66  MTX_2
67} mutex_id;
68
69typedef struct {
70  rtems_id mtx[MTX_COUNT];
71  mtx_t mtx_c11;
72#ifdef RTEMS_POSIX_API
73  pthread_mutex_t mtx_posix;
74#endif
75  rtems_id tasks[TASK_COUNT];
76  int generation[TASK_COUNT];
77  int expected_generation[TASK_COUNT];
78  jmp_buf deadlock_return_context;
79} test_context;
80
81static test_context test_instance;
82
83static void start_task(
84  test_context *ctx,
85  task_id id,
86  rtems_task_entry entry,
87  rtems_task_priority prio
88)
89{
90  rtems_status_code sc;
91
92  sc = rtems_task_create(
93    rtems_build_name('T', 'A', 'S', 'K'),
94    prio,
95    RTEMS_MINIMUM_STACK_SIZE,
96    RTEMS_DEFAULT_MODES,
97    RTEMS_DEFAULT_ATTRIBUTES,
98    &ctx->tasks[id]
99  );
100  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
101
102  sc = rtems_task_start(ctx->tasks[id], entry, id);
103  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
104}
105
106static void send_event(test_context *ctx, task_id id, rtems_event_set events)
107{
108  rtems_status_code sc;
109
110  sc = rtems_event_send(ctx->tasks[id], events);
111  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
112}
113
114static void wait(void)
115{
116  rtems_status_code sc;
117
118  sc = rtems_task_wake_after(4);
119  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
120}
121
122static rtems_event_set wait_for_events(void)
123{
124  rtems_event_set events;
125  rtems_status_code sc;
126
127  sc = rtems_event_receive(
128    RTEMS_ALL_EVENTS,
129    RTEMS_EVENT_ANY | RTEMS_WAIT,
130    RTEMS_NO_TIMEOUT,
131    &events
132  );
133  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
134
135  return events;
136}
137
138static void sync_with_helper(test_context *ctx)
139{
140  rtems_event_set events;
141
142  send_event(ctx, H, REQ_WAKE_UP_HELPER);
143  events = wait_for_events();
144  rtems_test_assert(events == REQ_WAKE_UP_MASTER);
145}
146
147static void request(test_context *ctx, task_id id, request_id req)
148{
149  send_event(ctx, id, req);
150  sync_with_helper(ctx);
151}
152
153static void obtain_timeout(test_context *ctx, mutex_id id)
154{
155  rtems_status_code sc;
156
157  sc = rtems_semaphore_obtain(ctx->mtx[id], RTEMS_WAIT, 2);
158  rtems_test_assert(sc == RTEMS_TIMEOUT);
159}
160
161static void obtain(test_context *ctx, mutex_id id)
162{
163  rtems_status_code sc;
164
165  sc = rtems_semaphore_obtain(ctx->mtx[id], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
166  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
167}
168
169static void deadlock_obtain(test_context *ctx, mutex_id id)
170{
171  rtems_status_code sc;
172
173  sc = rtems_semaphore_obtain(ctx->mtx[id], RTEMS_WAIT, RTEMS_NO_TIMEOUT);
174  rtems_test_assert(sc == RTEMS_INCORRECT_STATE);
175}
176
177static void release(test_context *ctx, mutex_id id)
178{
179  rtems_status_code sc;
180
181  sc = rtems_semaphore_release(ctx->mtx[id]);
182  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
183}
184
185static void obtain_c11(test_context *ctx)
186{
187  int status;
188
189  status = mtx_lock(&ctx->mtx_c11);
190  rtems_test_assert(status == thrd_success);
191}
192
193static void deadlock_obtain_c11(test_context *ctx)
194{
195  if (setjmp(ctx->deadlock_return_context) == 0) {
196    (void) mtx_lock(&ctx->mtx_c11);
197  }
198}
199
200static void release_c11(test_context *ctx)
201{
202  int status;
203
204  status = mtx_unlock(&ctx->mtx_c11);
205  rtems_test_assert(status == thrd_success);
206}
207
208#ifdef RTEMS_POSIX_API
209static void obtain_posix(test_context *ctx)
210{
211  int error;
212
213  error = pthread_mutex_lock(&ctx->mtx_posix);
214  rtems_test_assert(error == 0);
215}
216
217static void deadlock_obtain_posix(test_context *ctx)
218{
219  int error;
220
221  error = pthread_mutex_lock(&ctx->mtx_posix);
222  rtems_test_assert(error == EDEADLK);
223}
224
225static void release_posix(test_context *ctx)
226{
227  int error;
228
229  error = pthread_mutex_unlock(&ctx->mtx_posix);
230  rtems_test_assert(error == 0);
231}
232#endif
233
234static void check_generations(test_context *ctx, task_id a, task_id b)
235{
236  size_t i;
237
238  if (a != NONE) {
239    ++ctx->expected_generation[a];
240  }
241
242  if (b != NONE) {
243    ++ctx->expected_generation[b];
244  }
245
246  for (i = 0; i < TASK_COUNT; ++i) {
247    rtems_test_assert(ctx->generation[i] == ctx->expected_generation[i]);
248  }
249}
250
251static void assert_prio(
252  test_context *ctx,
253  task_id id,
254  rtems_task_priority expected
255)
256{
257  rtems_task_priority actual;
258  rtems_status_code sc;
259
260  sc = rtems_task_set_priority(
261    ctx->tasks[id],
262    RTEMS_CURRENT_PRIORITY,
263    &actual
264  );
265  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
266  rtems_test_assert(expected == actual);
267}
268
269static void change_prio(
270  test_context *ctx,
271  task_id id,
272  rtems_task_priority prio
273)
274{
275  rtems_status_code sc;
276
277  sc = rtems_task_set_priority(
278    ctx->tasks[id],
279    prio,
280    &prio
281  );
282  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
283}
284
285static void helper(rtems_task_argument arg)
286{
287  test_context *ctx = &test_instance;
288
289  while (true) {
290    rtems_event_set events = wait_for_events();
291    rtems_test_assert(events == REQ_WAKE_UP_HELPER);
292    send_event(ctx, M, REQ_WAKE_UP_MASTER);
293  }
294}
295
296static void worker(rtems_task_argument arg)
297{
298  test_context *ctx = &test_instance;
299  task_id id = arg;
300
301  while (true) {
302    rtems_event_set events = wait_for_events();
303
304    if ((events & REQ_MTX_0_OBTAIN) != 0) {
305      obtain(ctx, MTX_0);
306      ++ctx->generation[id];
307    }
308
309    if ((events & REQ_MTX_0_RELEASE) != 0) {
310      release(ctx, MTX_0);
311      ++ctx->generation[id];
312    }
313
314    if ((events & REQ_MTX_1_OBTAIN) != 0) {
315      obtain(ctx, MTX_1);
316      ++ctx->generation[id];
317    }
318
319    if ((events & REQ_MTX_1_OBTAIN_TIMEOUT) != 0) {
320      obtain_timeout(ctx, MTX_1);
321      ++ctx->generation[id];
322    }
323
324    if ((events & REQ_MTX_1_RELEASE) != 0) {
325      release(ctx, MTX_1);
326      ++ctx->generation[id];
327    }
328
329    if ((events & REQ_MTX_2_OBTAIN) != 0) {
330      obtain(ctx, MTX_2);
331      ++ctx->generation[id];
332    }
333
334    if ((events & REQ_MTX_2_RELEASE) != 0) {
335      release(ctx, MTX_2);
336      ++ctx->generation[id];
337    }
338
339    if ((events & REQ_MTX_C11_OBTAIN) != 0) {
340      obtain_c11(ctx);
341      ++ctx->generation[id];
342    }
343
344    if ((events & REQ_MTX_C11_RELEASE) != 0) {
345      release_c11(ctx);
346      ++ctx->generation[id];
347    }
348
349#ifdef RTEMS_POSIX_API
350    if ((events & REQ_MTX_POSIX_OBTAIN) != 0) {
351      obtain_posix(ctx);
352      ++ctx->generation[id];
353    }
354
355    if ((events & REQ_MTX_POSIX_RELEASE) != 0) {
356      release_posix(ctx);
357      ++ctx->generation[id];
358    }
359#endif
360  }
361}
362
363static void set_up(test_context *ctx)
364{
365  rtems_status_code sc;
366  int status;
367  size_t i;
368
369  ctx->tasks[M] = rtems_task_self();
370  start_task(ctx, A_1, worker, 1);
371  start_task(ctx, A_2_0, worker, 2);
372  start_task(ctx, A_2_1, worker, 2);
373  start_task(ctx, H, helper, 3);
374
375  for (i = 0; i < MTX_COUNT; ++i) {
376    sc = rtems_semaphore_create(
377      rtems_build_name(' ', 'M', 'T', 'X'),
378      1,
379      RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
380      0,
381      &ctx->mtx[i]
382    );
383    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
384  }
385
386  status = mtx_init(&ctx->mtx_c11, mtx_plain);
387  rtems_test_assert(status == thrd_success);
388
389#ifdef RTEMS_POSIX_API
390  {
391    int error;
392    pthread_mutexattr_t attr;
393
394    error = pthread_mutexattr_init(&attr);
395    rtems_test_assert(error == 0);
396
397    error = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
398    rtems_test_assert(error == 0);
399
400    error = pthread_mutex_init(&ctx->mtx_posix, &attr);
401    rtems_test_assert(error == 0);
402
403    error = pthread_mutexattr_destroy(&attr);
404    rtems_test_assert(error == 0);
405  }
406#endif
407}
408
409static void test_inherit(test_context *ctx)
410{
411  assert_prio(ctx, M, 3);
412  obtain(ctx, MTX_0);
413  request(ctx, A_1, REQ_MTX_0_OBTAIN);
414  check_generations(ctx, NONE, NONE);
415  assert_prio(ctx, M, 1);
416  change_prio(ctx, A_1, 2);
417  assert_prio(ctx, M, 2);
418  change_prio(ctx, A_1, 3);
419  assert_prio(ctx, M, 3);
420  change_prio(ctx, A_1, 4);
421  assert_prio(ctx, M, 3);
422  change_prio(ctx, A_1, 1);
423  assert_prio(ctx, M, 1);
424  release(ctx, MTX_0);
425  check_generations(ctx, A_1, NONE);
426  assert_prio(ctx, M, 3);
427  request(ctx, A_1, REQ_MTX_0_RELEASE);
428  check_generations(ctx, A_1, NONE);
429}
430
431static void test_inherit_fifo_for_equal_priority(test_context *ctx)
432{
433  assert_prio(ctx, M, 3);
434  obtain(ctx, MTX_0);
435  request(ctx, A_2_0, REQ_MTX_0_OBTAIN);
436  request(ctx, A_1, REQ_MTX_0_OBTAIN);
437  request(ctx, A_2_1, REQ_MTX_0_OBTAIN);
438  check_generations(ctx, NONE, NONE);
439  assert_prio(ctx, M, 1);
440  release(ctx, MTX_0);
441  check_generations(ctx, A_1, NONE);
442  assert_prio(ctx, M, 3);
443  assert_prio(ctx, A_1, 1);
444  request(ctx, A_1, REQ_MTX_0_RELEASE);
445  check_generations(ctx, A_1, A_2_0);
446  request(ctx, A_2_0, REQ_MTX_0_RELEASE);
447  check_generations(ctx, A_2_0, A_2_1);
448  request(ctx, A_2_1, REQ_MTX_0_RELEASE);
449  check_generations(ctx, A_2_1, NONE);
450}
451
452static void test_inherit_nested_vertical(test_context *ctx)
453{
454  assert_prio(ctx, M, 3);
455  obtain(ctx, MTX_0);
456  obtain(ctx, MTX_1);
457  request(ctx, A_1, REQ_MTX_1_OBTAIN);
458  check_generations(ctx, NONE, NONE);
459  assert_prio(ctx, M, 1);
460  release(ctx, MTX_1);
461  check_generations(ctx, A_1, NONE);
462  assert_prio(ctx, M, 3);
463  request(ctx, A_1, REQ_MTX_1_RELEASE);
464  check_generations(ctx, A_1, NONE);
465  release(ctx, MTX_0);
466}
467
468static void test_inherit_nested_vertical_timeout(test_context *ctx)
469{
470  assert_prio(ctx, M, 3);
471  obtain(ctx, MTX_0);
472  obtain(ctx, MTX_1);
473  request(ctx, A_1, REQ_MTX_1_OBTAIN_TIMEOUT);
474  check_generations(ctx, NONE, NONE);
475  assert_prio(ctx, M, 1);
476  wait();
477  check_generations(ctx, A_1, NONE);
478  assert_prio(ctx, M, 3);
479  release(ctx, MTX_1);
480  release(ctx, MTX_0);
481}
482
483static void test_inherit_nested_horizontal(test_context *ctx)
484{
485  assert_prio(ctx, M, 3);
486  obtain(ctx, MTX_0);
487  request(ctx, A_2_0, REQ_MTX_1_OBTAIN);
488  check_generations(ctx, A_2_0, NONE);
489  request(ctx, A_2_0, REQ_MTX_0_OBTAIN);
490  check_generations(ctx, NONE, NONE);
491  assert_prio(ctx, M, 2);
492  request(ctx, A_1, REQ_MTX_1_OBTAIN_TIMEOUT);
493  check_generations(ctx, NONE, NONE);
494  assert_prio(ctx, A_2_0, 1);
495  assert_prio(ctx, M, 1);
496  wait();
497  check_generations(ctx, A_1, NONE);
498  assert_prio(ctx, A_2_0, 2);
499  assert_prio(ctx, M, 2);
500  request(ctx, A_1, REQ_MTX_1_OBTAIN);
501  check_generations(ctx, NONE, NONE);
502  assert_prio(ctx, A_2_0, 1);
503  assert_prio(ctx, M, 1);
504  change_prio(ctx, A_1, 2);
505  assert_prio(ctx, M, 2);
506  change_prio(ctx, A_1, 3);
507  assert_prio(ctx, M, 2);
508  change_prio(ctx, A_2_0, 3);
509  assert_prio(ctx, M, 3);
510  change_prio(ctx, A_2_0, 2);
511  assert_prio(ctx, M, 2);
512  change_prio(ctx, A_1, 1);
513  assert_prio(ctx, M, 1);
514  release(ctx, MTX_0);
515  check_generations(ctx, A_2_0, NONE);
516  assert_prio(ctx, A_2_0, 1);
517  assert_prio(ctx, M, 3);
518  request(ctx, A_2_0, REQ_MTX_0_RELEASE);
519  check_generations(ctx, A_2_0, NONE);
520  assert_prio(ctx, A_2_0, 1);
521  request(ctx, A_2_0, REQ_MTX_1_RELEASE);
522  check_generations(ctx, A_1, A_2_0);
523  assert_prio(ctx, A_2_0, 2);
524  request(ctx, A_1, REQ_MTX_1_RELEASE);
525  check_generations(ctx, A_1, NONE);
526}
527
528static void test_deadlock_two_classic(test_context *ctx)
529{
530  obtain(ctx, MTX_0);
531  request(ctx, A_1, REQ_MTX_1_OBTAIN);
532  check_generations(ctx, A_1, NONE);
533  request(ctx, A_1, REQ_MTX_0_OBTAIN);
534  check_generations(ctx, NONE, NONE);
535  deadlock_obtain(ctx, MTX_1);
536  release(ctx, MTX_0);
537  check_generations(ctx, A_1, NONE);
538  request(ctx, A_1, REQ_MTX_0_RELEASE);
539  check_generations(ctx, A_1, NONE);
540  request(ctx, A_1, REQ_MTX_1_RELEASE);
541  check_generations(ctx, A_1, NONE);
542}
543
544static void test_deadlock_three_classic(test_context *ctx)
545{
546  obtain(ctx, MTX_0);
547  request(ctx, A_1, REQ_MTX_1_OBTAIN);
548  check_generations(ctx, A_1, NONE);
549  request(ctx, A_2_0, REQ_MTX_2_OBTAIN);
550  check_generations(ctx, A_2_0, NONE);
551  request(ctx, A_2_0, REQ_MTX_1_OBTAIN);
552  check_generations(ctx, NONE, NONE);
553  request(ctx, A_1, REQ_MTX_0_OBTAIN);
554  check_generations(ctx, NONE, NONE);
555  deadlock_obtain(ctx, MTX_2);
556  release(ctx, MTX_0);
557  check_generations(ctx, A_1, NONE);
558  request(ctx, A_1, REQ_MTX_0_RELEASE);
559  check_generations(ctx, A_1, NONE);
560  request(ctx, A_1, REQ_MTX_1_RELEASE);
561  check_generations(ctx, A_1, A_2_0);
562  request(ctx, A_2_0, REQ_MTX_2_RELEASE);
563  check_generations(ctx, A_2_0, NONE);
564  request(ctx, A_2_0, REQ_MTX_1_RELEASE);
565  check_generations(ctx, A_2_0, NONE);
566}
567
568static void test_deadlock_c11_and_classic(test_context *ctx)
569{
570  obtain_c11(ctx);
571  request(ctx, A_1, REQ_MTX_0_OBTAIN);
572  check_generations(ctx, A_1, NONE);
573  request(ctx, A_1, REQ_MTX_C11_OBTAIN);
574  check_generations(ctx, NONE, NONE);
575  deadlock_obtain(ctx, MTX_0);
576  release_c11(ctx);
577  check_generations(ctx, A_1, NONE);
578  request(ctx, A_1, REQ_MTX_C11_RELEASE);
579  check_generations(ctx, A_1, NONE);
580  request(ctx, A_1, REQ_MTX_0_RELEASE);
581  check_generations(ctx, A_1, NONE);
582}
583
584static void test_deadlock_classic_and_c11(test_context *ctx)
585{
586  obtain(ctx, MTX_0);
587  request(ctx, A_1, REQ_MTX_C11_OBTAIN);
588  check_generations(ctx, A_1, NONE);
589  request(ctx, A_1, REQ_MTX_0_OBTAIN);
590  check_generations(ctx, NONE, NONE);
591  deadlock_obtain_c11(ctx);
592  release(ctx, MTX_0);
593  check_generations(ctx, A_1, NONE);
594  request(ctx, A_1, REQ_MTX_0_RELEASE);
595  check_generations(ctx, A_1, NONE);
596  request(ctx, A_1, REQ_MTX_C11_RELEASE);
597  check_generations(ctx, A_1, NONE);
598}
599
600static void test_deadlock_posix_and_classic(test_context *ctx)
601{
602#ifdef RTEMS_POSIX_API
603  obtain_posix(ctx);
604  request(ctx, A_1, REQ_MTX_0_OBTAIN);
605  check_generations(ctx, A_1, NONE);
606  request(ctx, A_1, REQ_MTX_POSIX_OBTAIN);
607  check_generations(ctx, NONE, NONE);
608  deadlock_obtain(ctx, MTX_0);
609  release_posix(ctx);
610  check_generations(ctx, A_1, NONE);
611  request(ctx, A_1, REQ_MTX_POSIX_RELEASE);
612  check_generations(ctx, A_1, NONE);
613  request(ctx, A_1, REQ_MTX_0_RELEASE);
614  check_generations(ctx, A_1, NONE);
615#endif
616}
617
618static void test_deadlock_classic_and_posix(test_context *ctx)
619{
620#ifdef RTEMS_POSIX_API
621  obtain(ctx, MTX_0);
622  request(ctx, A_1, REQ_MTX_POSIX_OBTAIN);
623  check_generations(ctx, A_1, NONE);
624  request(ctx, A_1, REQ_MTX_0_OBTAIN);
625  check_generations(ctx, NONE, NONE);
626  deadlock_obtain_posix(ctx);
627  release(ctx, MTX_0);
628  check_generations(ctx, A_1, NONE);
629  request(ctx, A_1, REQ_MTX_0_RELEASE);
630  check_generations(ctx, A_1, NONE);
631  request(ctx, A_1, REQ_MTX_POSIX_RELEASE);
632  check_generations(ctx, A_1, NONE);
633#endif
634}
635
636static void tear_down(test_context *ctx)
637{
638  rtems_status_code sc;
639  size_t i;
640
641  for (i = 1; i < TASK_COUNT; ++i) {
642    sc = rtems_task_delete(ctx->tasks[i]);
643    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
644  }
645
646  for (i = 0; i < MTX_COUNT; ++i) {
647    sc = rtems_semaphore_delete(ctx->mtx[i]);
648    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
649  }
650
651  mtx_destroy(&ctx->mtx_c11);
652
653#ifdef RTEMS_POSIX_API
654  {
655    int error;
656
657    error = pthread_mutex_destroy(&ctx->mtx_posix);
658    rtems_test_assert(error == 0);
659  }
660#endif
661}
662
663static void Init(rtems_task_argument arg)
664{
665  test_context *ctx = &test_instance;
666  rtems_resource_snapshot snapshot;
667
668  TEST_BEGIN();
669  rtems_resource_snapshot_take(&snapshot);
670
671  set_up(ctx);
672  test_inherit(ctx);
673  test_inherit_fifo_for_equal_priority(ctx);
674  test_inherit_nested_vertical(ctx);
675  test_inherit_nested_vertical_timeout(ctx);
676  test_inherit_nested_horizontal(ctx);
677  test_deadlock_two_classic(ctx);
678  test_deadlock_three_classic(ctx);
679  test_deadlock_c11_and_classic(ctx);
680  test_deadlock_classic_and_c11(ctx);
681  test_deadlock_posix_and_classic(ctx);
682  test_deadlock_classic_and_posix(ctx);
683  tear_down(ctx);
684
685  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
686  TEST_END();
687  rtems_test_exit(0);
688}
689
690static void fatal_extension(
691  rtems_fatal_source source,
692  bool is_internal,
693  rtems_fatal_code error
694)
695{
696
697  if (
698    source == INTERNAL_ERROR_CORE
699      && !is_internal
700      && error == INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK
701  ) {
702    test_context *ctx = &test_instance;
703
704    longjmp(ctx->deadlock_return_context, 1);
705  }
706}
707
708#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
709#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
710
711#define CONFIGURE_MAXIMUM_TASKS TASK_COUNT
712
713#define CONFIGURE_MAXIMUM_SEMAPHORES 3
714
715#ifdef RTEMS_POSIX_API
716#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 1
717#endif
718
719#define CONFIGURE_INITIAL_EXTENSIONS \
720  { .fatal = fatal_extension }, \
721  RTEMS_TEST_INITIAL_EXTENSION
722
723#define CONFIGURE_INIT_TASK_PRIORITY 3
724
725#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
726
727#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
728
729#define CONFIGURE_INIT
730
731#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.