Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*  Test1
0004  *
0005  *  This test uses creates a number of tasks so the capture engine
0006  *  can show a trace.
0007  *
0008  *  Input parameters:  NONE
0009  *
0010  *  Output parameters:  NONE
0011  *
0012  *  COPYRIGHT (c) 1989-1997.
0013  *  On-Line Applications Research Corporation (OAR).
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions
0017  * are met:
0018  * 1. Redistributions of source code must retain the above copyright
0019  *    notice, this list of conditions and the following disclaimer.
0020  * 2. Redistributions in binary form must reproduce the above copyright
0021  *    notice, this list of conditions and the following disclaimer in the
0022  *    documentation and/or other materials provided with the distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034  * POSSIBILITY OF SUCH DAMAGE.
0035  */
0036 
0037 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040 
0041 #include "system.h"
0042 #include <stdio.h>
0043 #include <stdlib.h>
0044 
0045 #include <rtems.h>
0046 #include <rtems/monitor.h>
0047 
0048 static volatile int capture_CT1a_deleted;
0049 static volatile int capture_CT1b_deleted;
0050 static volatile int capture_CT1c_deleted;
0051 
0052 static void
0053 capture_wait (uint32_t period)
0054 {
0055   rtems_task_wake_after (RTEMS_MICROSECONDS_TO_TICKS (period * 1000));
0056 }
0057 
0058 /*
0059  * CT1a: Claim the mutex and then wait a while then wake
0060  *       up and release the mutex. While this task waits with
0061  *       the mutex another higher priority task is started that
0062  *       just loops using all the processing time. It is not until
0063  *       another even higher priority thread blocks on the mutex
0064  *       does this task get raised to that priority and so
0065  *       releases the mutex. This will allow us to capture the
0066  *       action of priority inversion.
0067  */
0068 static void
0069 capture_CT1a (rtems_task_argument arg)
0070 {
0071   rtems_id mutex = (rtems_id) arg;
0072   rtems_status_code sc;
0073 
0074   sc = rtems_semaphore_obtain (mutex, RTEMS_WAIT, 0);
0075 
0076   if (sc != RTEMS_SUCCESSFUL)
0077     printf ("error: CT1a: mutex obtain: %s\n", rtems_status_text (sc));
0078 
0079   capture_wait (2500);
0080 
0081   sc = rtems_semaphore_release (mutex);
0082 
0083   if (sc != RTEMS_SUCCESSFUL)
0084     printf ("error: CT1a: mutex release: %s\n", rtems_status_text (sc));
0085 
0086   capture_CT1a_deleted = 1;
0087 
0088   rtems_task_exit();
0089 }
0090 
0091 static void
0092 capture_CT1b (rtems_task_argument arg)
0093 {
0094   volatile int i;
0095 
0096   while (!capture_CT1c_deleted)
0097     i++;
0098 
0099   capture_CT1b_deleted = 1;
0100 
0101   rtems_task_exit();
0102 }
0103 
0104 static void
0105 capture_CT1c (rtems_task_argument arg)
0106 {
0107   rtems_id          mutex = (rtems_id) arg;
0108   rtems_status_code sc;
0109 
0110   sc = rtems_semaphore_obtain (mutex, RTEMS_WAIT, 0);
0111 
0112   if (sc != RTEMS_SUCCESSFUL)
0113     printf ("error: CT1c: mutex obtain: %s\n", rtems_status_text (sc));
0114 
0115   capture_wait (500);
0116 
0117   sc = rtems_semaphore_release (mutex);
0118 
0119   if (sc != RTEMS_SUCCESSFUL)
0120     printf ("error: CT1c: mutex release: %s\n", rtems_status_text (sc));
0121 
0122   capture_CT1c_deleted = 1;
0123 
0124   rtems_task_exit();
0125 }
0126 
0127 static void
0128 capture_test_1 (int                                argc,
0129                 char**                             argv,
0130                 const rtems_monitor_command_arg_t* command_arg,
0131                 bool                               verbose)
0132 {
0133   rtems_status_code sc;
0134   rtems_name        name;
0135   rtems_id          id[3];
0136   rtems_id          mutex;
0137   int               loops;
0138 
0139   capture_CT1a_deleted = 0;
0140   capture_CT1b_deleted = 0;
0141   capture_CT1c_deleted = 0;
0142 
0143   name = rtems_build_name('C', 'T', 'm', '1');
0144 
0145   sc = rtems_semaphore_create (name, 1,
0146                                RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE |
0147                                RTEMS_INHERIT_PRIORITY,
0148                                0, &mutex);
0149 
0150   if (sc != RTEMS_SUCCESSFUL)
0151   {
0152     printf ("error: Test 1: cannot mutex: %s\n", rtems_status_text (sc));
0153     return;
0154   }
0155 
0156   name = rtems_build_name('C', 'T', '1', 'a');
0157 
0158   sc = rtems_task_create (name, 102, 2 * 1024,
0159                           RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
0160                           RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR,
0161                           &id[0]);
0162 
0163   if (sc != RTEMS_SUCCESSFUL)
0164   {
0165     printf ("error: Test 1: cannot create CT1a: %s\n", rtems_status_text (sc));
0166     rtems_semaphore_delete (mutex);
0167     return;
0168   }
0169 
0170   sc = rtems_task_start (id[0], capture_CT1a, (rtems_task_argument) mutex);
0171 
0172   if (sc != RTEMS_SUCCESSFUL)
0173   {
0174     printf ("error: Test 1: cannot start CT1a: %s\n", rtems_status_text (sc));
0175     rtems_task_exit();
0176     rtems_semaphore_delete (mutex);
0177     return;
0178   }
0179 
0180   capture_wait (1000);
0181 
0182   name = rtems_build_name('C', 'T', '1', 'b');
0183 
0184   sc = rtems_task_create (name, 101, 2 * 1024,
0185                           RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
0186                           RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR,
0187                           &id[1]);
0188 
0189   if (sc != RTEMS_SUCCESSFUL)
0190   {
0191     printf ("error: Test 1: cannot create CT1b: %s\n", rtems_status_text (sc));
0192     rtems_task_exit();
0193     rtems_semaphore_delete (mutex);
0194     return;
0195   }
0196 
0197   sc = rtems_task_start (id[1], capture_CT1b, 0);
0198 
0199   if (sc != RTEMS_SUCCESSFUL)
0200   {
0201     printf ("error: Test 1: cannot start CT1b: %s\n", rtems_status_text (sc));
0202     rtems_task_exit();
0203     rtems_task_exit();
0204     rtems_semaphore_delete (mutex);
0205     return;
0206   }
0207 
0208   capture_wait (1000);
0209 
0210   name = rtems_build_name('C', 'T', '1', 'c');
0211 
0212   sc = rtems_task_create (name, 100, 2 * 1024,
0213                           RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
0214                           RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR,
0215                           &id[2]);
0216 
0217   if (sc != RTEMS_SUCCESSFUL)
0218   {
0219     printf ("error: Test 1: cannot create CT1c: %s\n", rtems_status_text (sc));
0220     rtems_task_exit();
0221     rtems_task_exit();
0222     rtems_semaphore_delete (mutex);
0223     return;
0224   }
0225 
0226   sc = rtems_task_start (id[2], capture_CT1c, (rtems_task_argument) mutex);
0227 
0228   if (sc != RTEMS_SUCCESSFUL)
0229   {
0230     printf ("error: Test 1: cannot start CT1c: %s\n", rtems_status_text (sc));
0231     rtems_task_exit();
0232     rtems_task_exit();
0233     rtems_task_exit();
0234     rtems_semaphore_delete (mutex);
0235     return;
0236   }
0237 
0238   loops = 15;
0239 
0240   while (!(capture_CT1a_deleted || capture_CT1b_deleted ||
0241            capture_CT1c_deleted) && loops)
0242   {
0243     loops--;
0244     capture_wait (1000);
0245   }
0246 
0247   if (!loops)
0248   {
0249     printf ("error: Test 1: test tasks did not delete\n");
0250     rtems_task_exit();
0251     rtems_task_exit();
0252     rtems_task_exit();
0253   }
0254 
0255   sc = rtems_semaphore_delete (mutex);
0256   if (sc != RTEMS_SUCCESSFUL)
0257     printf ("error: Test 1: deleting the mutex: %s\n", rtems_status_text (sc));
0258 }
0259 
0260 static rtems_monitor_command_entry_t capture_cmds[] =
0261 {
0262   {
0263     "test1",
0264     "usage: \n",
0265     0,
0266     capture_test_1,
0267     { 0 },
0268     0
0269   }
0270 };
0271 
0272 void setup_tasks_to_watch (void)
0273 {
0274   size_t cmd;
0275   for (cmd = 0;
0276        cmd < sizeof (capture_cmds) / sizeof (rtems_monitor_command_entry_t);
0277        cmd++)
0278       rtems_monitor_insert_cmd (&capture_cmds[cmd]);
0279 }