Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:48

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2014, 2016 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include "tmacros.h"
0033 
0034 const char rtems_test_name[] = "SPSEM 3";
0035 
0036 typedef struct {
0037   rtems_id low;
0038   rtems_id mid;
0039   rtems_id high;
0040   rtems_id inversion;
0041   rtems_id sem_a;
0042   rtems_id sem_b;
0043 } test_context;
0044 
0045 static test_context test_instance;
0046 
0047 static void assert_prio(rtems_id task_id, rtems_task_priority expected_prio)
0048 {
0049   rtems_status_code sc;
0050   rtems_task_priority prio;
0051 
0052   sc = rtems_task_set_priority(task_id, RTEMS_CURRENT_PRIORITY, &prio);
0053   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0054   rtems_test_assert(prio == expected_prio);
0055 }
0056 
0057 static void create_task(rtems_id *id, rtems_task_priority prio)
0058 {
0059   rtems_status_code sc;
0060 
0061   sc = rtems_task_create(
0062     rtems_build_name('T', 'A', 'S', 'K'),
0063     prio,
0064     RTEMS_MINIMUM_STACK_SIZE,
0065     RTEMS_DEFAULT_MODES,
0066     RTEMS_DEFAULT_ATTRIBUTES,
0067     id
0068   );
0069   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0070 }
0071 
0072 static void start_task(rtems_id id, rtems_task_entry entry)
0073 {
0074   rtems_status_code sc;
0075 
0076   sc = rtems_task_start(id, entry, 0);
0077   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0078 }
0079 
0080 static void create_sema(rtems_id *id)
0081 {
0082   rtems_status_code sc;
0083 
0084   sc = rtems_semaphore_create(
0085     rtems_build_name('S', 'E', 'M', 'A'),
0086     1,
0087     RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
0088     0,
0089     id
0090   );
0091   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0092 }
0093 
0094 static void obtain_sema(rtems_id id)
0095 {
0096   rtems_status_code sc;
0097 
0098   sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0099   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0100 }
0101 
0102 static void inversion_task(rtems_task_argument arg)
0103 {
0104   rtems_test_assert(0);
0105 }
0106 
0107 static void mid_task(rtems_task_argument arg)
0108 {
0109   test_context *ctx = &test_instance;
0110 
0111   obtain_sema(ctx->sem_b);
0112   obtain_sema(ctx->sem_a);
0113 }
0114 
0115 static void high_task(rtems_task_argument arg)
0116 {
0117   test_context *ctx = &test_instance;
0118 
0119   start_task(ctx->inversion, inversion_task);
0120   obtain_sema(ctx->sem_b);
0121 }
0122 
0123 static void Init(rtems_task_argument arg)
0124 {
0125   test_context *ctx = &test_instance;
0126 
0127   TEST_BEGIN();
0128 
0129   ctx->low = rtems_task_self();
0130 
0131   create_task(&ctx->mid, 3);
0132   create_task(&ctx->high, 1);
0133   create_task(&ctx->inversion, 2);
0134   create_sema(&ctx->sem_a);
0135   create_sema(&ctx->sem_b);
0136 
0137   obtain_sema(ctx->sem_a);
0138   start_task(ctx->mid, mid_task);
0139   start_task(ctx->high, high_task);
0140 
0141   /*
0142    * Here we see that the priority of the high priority task blocked on
0143    * semaphore B propagated to the low priority task owning semaphore A
0144    * on which the owner of semaphore B depends.
0145    */
0146   assert_prio(ctx->low, 1);
0147   assert_prio(ctx->mid, 1);
0148   assert_prio(ctx->high, 1);
0149   assert_prio(ctx->inversion, 2);
0150 
0151   TEST_END();
0152   rtems_test_exit(0);
0153 }
0154 
0155 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0156 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0157 
0158 #define CONFIGURE_MAXIMUM_TASKS 4
0159 #define CONFIGURE_MAXIMUM_SEMAPHORES 2
0160 
0161 #define CONFIGURE_INIT_TASK_PRIORITY 4
0162 #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
0163 
0164 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0165 
0166 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0167 
0168 #define CONFIGURE_INIT
0169 
0170 #include <rtems/confdefs.h>