Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 2014.
0005  *  On-Line Applications Research Corporation (OAR).
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  * 2. Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *
0016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0026  * POSSIBILITY OF SUCH DAMAGE.
0027  */
0028 
0029 /*
0030  * The init task UT1 should start on cpu 3 and has priority:affinity set
0031  * 7:{2,3} The test creates 4 more tasks TA1 - TA4
0032  * with priorty:affinity sets 8:{2,3}, 5:{0,1}, 6:{0,3}, and 9:{1}.
0033  * This should result in cpu:task  0:TA3, 1:TA2, 2:TA1, 3:UT1 with
0034  * TA4 waiting on a cpu.
0035  *
0036  * The test then raises the priority of TA4 to 4, resulting
0037  * in the following cpu:task 0:TA2, 1:TA4, 2:UT1, 3:TA3 with
0038  * TA1 waiting on a CPU.  The tasks are then terminated.
0039  *
0040  * The capture engine is set up read and report the results.
0041  */
0042 
0043 #ifdef HAVE_CONFIG_H
0044 #include "config.h"
0045 #endif
0046 
0047 #include <rtems.h>
0048 #include <rtems/captureimpl.h>
0049 
0050 #include "tmacros.h"
0051 
0052 const char rtems_test_name[] = "SMPCAPTURE 1";
0053 
0054 #define NUM_CPUS   4
0055 #define TASK_COUNT 5
0056 
0057 struct task_data_t {
0058   rtems_id            id;
0059   cpu_set_t           cpuset;
0060   rtems_task_priority priority;
0061   bool                ran;
0062   int                 expected_cpu;
0063   int                 actual_cpu;
0064   int                 migrate_cpu;
0065 };
0066 
0067 static struct task_data_t task_data[TASK_COUNT] = {
0068   {0x0, {{0xc}}, 7, false,  3, -1,  2},
0069   {0x0, {{0xf}}, 8, false,  2, -1, -1},
0070   {0x0, {{0x3}}, 5, false,  1, -1,  0},
0071   {0x0, {{0x9}}, 6, false,  0, -1,  3},
0072   {0x0, {{0x2}}, 9, false, -1, -1,  1}
0073 };
0074 
0075 rtems_id           task_sem;
0076 
0077 /*
0078  * Spin loop to allow tasks to delay without yeilding the
0079  * processor.
0080  */
0081 static void test_delay(int ticks)
0082 {
0083   rtems_interval start, stop;
0084   start = rtems_clock_get_ticks_since_boot();
0085   do {
0086     stop = rtems_clock_get_ticks_since_boot();
0087   } while ( (stop - start) < ticks );
0088 }
0089 
0090 static void task(rtems_task_argument arg)
0091 {
0092   rtems_status_code   sc;
0093 
0094   while (true) {
0095     sc = rtems_semaphore_obtain (task_sem, RTEMS_NO_WAIT, 0);
0096     if (sc == RTEMS_SUCCESSFUL) {
0097       task_data[arg].ran = true;
0098       task_data[arg].actual_cpu = rtems_scheduler_get_processor();
0099       rtems_semaphore_release(task_sem);
0100       test_delay(1);
0101     }
0102   }
0103 }
0104 
0105 static void set_init_task(void)
0106 {
0107   while( rtems_semaphore_obtain (task_sem, RTEMS_NO_WAIT, 0) != RTEMS_SUCCESSFUL );
0108 
0109   /* Set Init task data */
0110   task_data[0].ran = true;
0111   task_data[0].actual_cpu = rtems_scheduler_get_processor();
0112 
0113   rtems_semaphore_release(task_sem);
0114 }
0115 
0116 static void test(void)
0117 {
0118   rtems_status_code   sc;
0119   rtems_task_argument i;
0120   size_t              size;
0121   uint32_t            cpu_count;
0122   rtems_task_priority priority;
0123 
0124   /* Get the number of processors that we are using. */
0125   cpu_count = rtems_scheduler_get_processor_maximum();
0126   if (cpu_count != 4) {
0127     printf("Test requires a minimum of 4 cores\n");
0128     return;
0129   }
0130 
0131   size = sizeof(cpu_set_t);
0132   task_data[0].id = rtems_task_self();
0133 
0134   sc = rtems_semaphore_create(
0135     rtems_build_name('S', 'E', 'M', '0'),
0136     1,                                               /* initial count = 1 */
0137     RTEMS_LOCAL                   |
0138     RTEMS_SIMPLE_BINARY_SEMAPHORE |
0139     RTEMS_NO_INHERIT_PRIORITY     |
0140     RTEMS_NO_PRIORITY_CEILING     |
0141     RTEMS_FIFO,
0142     0,
0143     &task_sem
0144   );
0145   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0146 
0147   sc = rtems_task_set_affinity(
0148     task_data[ 0 ].id,
0149     size,
0150     &task_data[0].cpuset
0151   );
0152   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0153 
0154 
0155   /* Create and start tasks on each cpu with the appropriate affinity. */
0156   for (i = 1; i < TASK_COUNT; i++) {
0157 
0158       sc = rtems_task_create(
0159         rtems_build_name('T', 'A', '0', '0'+i),
0160         task_data[ i ].priority,
0161         RTEMS_MINIMUM_STACK_SIZE,
0162         RTEMS_DEFAULT_MODES,
0163         RTEMS_DEFAULT_ATTRIBUTES,
0164         &task_data[ i ].id
0165       );
0166       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0167 
0168       sc = rtems_task_set_affinity(
0169         task_data[ i ].id,
0170         size,
0171         &task_data[i].cpuset
0172       );
0173       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0174 
0175       sc = rtems_task_start( task_data[ i ].id, task, i );
0176       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0177   }
0178 
0179   /* spin for 10 ticks */
0180   test_delay(10);
0181 
0182   set_init_task();
0183 
0184   i = TASK_COUNT - 1;
0185   task_data[ i ].priority = 4;
0186   sc = rtems_task_set_priority(
0187     task_data[ i ].id,
0188     task_data[ i ].priority,
0189     &priority
0190   );
0191   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0192 
0193   test_delay(10);
0194 
0195   while( rtems_semaphore_obtain (task_sem, RTEMS_NO_WAIT, 0) != RTEMS_SUCCESSFUL );
0196   for (i = 0; i < TASK_COUNT; i++) {
0197     task_data[ i ].expected_cpu = task_data[ i ].migrate_cpu;
0198     task_data[ i ].actual_cpu = -1;
0199     task_data[ i ].ran = false;
0200   }
0201   rtems_semaphore_release(task_sem);
0202   test_delay(10);
0203   set_init_task();
0204 
0205   for (i = 1; i < TASK_COUNT; i++) {
0206     sc = rtems_task_delete( task_data[ i ].id );
0207     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0208   }
0209   test_delay(25);
0210 }
0211 
0212 static void Init(rtems_task_argument arg)
0213 {
0214   rtems_status_code   sc;
0215   rtems_name          to_name = rtems_build_name('I', 'D', 'L', 'E');;
0216   uint32_t            i;
0217 
0218   TEST_BEGIN();
0219 
0220   sc = rtems_capture_open (5000, NULL);
0221   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0222 
0223   sc = rtems_capture_watch_ceiling (0);
0224   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0225 
0226   sc = rtems_capture_watch_floor (20);
0227   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0228 
0229   sc = rtems_capture_watch_global (true);
0230   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0231 
0232   sc = rtems_capture_set_trigger (
0233     0,
0234     0,
0235     to_name,
0236     0,
0237     rtems_capture_from_any,
0238     rtems_capture_switch
0239   );
0240   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0241 
0242   for (i = 1; i < TASK_COUNT; i++) {
0243      to_name = rtems_build_name('T', 'A', '0', '0'+i);
0244      sc = rtems_capture_set_trigger (
0245       0,
0246       0,
0247       to_name,
0248       0,
0249       rtems_capture_from_any,
0250       rtems_capture_switch
0251     );
0252   }
0253 
0254   sc = rtems_capture_set_control (true);
0255   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0256 
0257   test();
0258 
0259   sc = rtems_capture_set_control (false);
0260   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0261 
0262   rtems_capture_print_trace_records ( 22, false );
0263   rtems_capture_print_trace_records ( 22, false );
0264   rtems_capture_print_trace_records ( 22, false );
0265 
0266   TEST_END();
0267   rtems_test_exit(0);
0268 }
0269 
0270 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0271 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0272 
0273 #define CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
0274 
0275 #define CONFIGURE_MAXIMUM_SEMAPHORES 1
0276 
0277 #define CONFIGURE_MAXIMUM_PROCESSORS NUM_CPUS
0278 
0279 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0280 
0281 #define CONFIGURE_INIT_TASK_PRIORITY       7
0282 #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
0283 
0284 #define TASK_ALLOCATION_SIZE     (5)
0285 #define CONFIGURE_MAXIMUM_TASKS  rtems_resource_unlimited(TASK_ALLOCATION_SIZE)
0286 #define CONFIGURE_EXTRA_TASK_STACKS (75 * RTEMS_MINIMUM_STACK_SIZE)
0287 
0288 #define CONFIGURE_MAXIMUM_USER_EXTENSIONS (5)
0289 
0290 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0291 
0292 #define CONFIGURE_INIT
0293 
0294 #include <rtems/confdefs.h>