Back to home page

LXR

 
 

    


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

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  * Start 4 tasks with affinity for each of the 4 cpus.
0031  * Allow tasks to set their actual cpu value and delete themselves.
0032  * Verify the actual cpu values match the expected cpu values.
0033  *
0034  * Init task is at a lower priority 8 and the threads
0035  * with affinity are at priority 4, so the affinity task
0036  * on the core init is running on will preempt it.
0037  *
0038  * Test tasks run and delete themselves. 
0039  * Init task never blocks.
0040  */
0041 
0042 #ifdef HAVE_CONFIG_H
0043 #include "config.h"
0044 #endif
0045 
0046 #include <rtems.h>
0047 
0048 #include "tmacros.h"
0049 
0050 const char rtems_test_name[] = "SMPSCHEDAFFINITY 1";
0051 
0052 #define NUM_CPUS   4
0053 #define TASK_COUNT 5
0054 
0055 struct task_data_t {
0056   rtems_id   id;
0057   int        expected_cpu;
0058   cpu_set_t  cpuset;
0059   bool       ran;
0060   int        actual_cpu;
0061 };
0062 
0063 static struct task_data_t task_data[NUM_CPUS] = {
0064   {0x0, 2, {{0x4}}, false, -1},
0065   {0x0, 0, {{0x1}}, false, -1},
0066   {0x0, 3, {{0x8}}, false, -1},
0067   {0x0, 1, {{0x2}}, false, -1}
0068 };
0069   
0070 /*
0071  * Spin loop to allow tasks to delay without yeilding the
0072  * processor.
0073  */
0074 static void test_delay(int ticks)
0075 { 
0076   rtems_interval start, stop;
0077   start = rtems_clock_get_ticks_since_boot();
0078   do {
0079     stop = rtems_clock_get_ticks_since_boot();
0080   } while ( (stop - start) < ticks );
0081 }
0082 
0083 static void task(rtems_task_argument arg)
0084 {
0085   uint32_t cpu;
0086   cpu_set_t cpuset;
0087 
0088   cpu = rtems_scheduler_get_processor();
0089 
0090   rtems_task_get_affinity( rtems_task_self(), sizeof(cpuset), &cpuset );
0091 
0092   task_data[arg].ran = true;
0093   task_data[arg].actual_cpu = cpu;
0094 
0095   rtems_task_exit();
0096 }
0097 
0098 static void test(void)
0099 {
0100   rtems_status_code   sc;
0101   rtems_task_argument i;
0102   size_t              size;
0103   uint32_t            cpu_count;
0104 
0105   /* Get the number of processors that we are using. */
0106   cpu_count = rtems_scheduler_get_processor_maximum();
0107  
0108   size = sizeof(cpu_set_t);
0109 
0110   /* Create and start tasks on each cpu with the appropriate affinity. */
0111   for (i = 0; i < NUM_CPUS; i++) {
0112 
0113       /* Skip if this cpu doesn't exist, don't create task */
0114       if ( task_data[i].expected_cpu >= cpu_count ) {
0115         printf(
0116           "Skipping TA0%" PRIdrtems_task_argument
0117             " because on a core we do not have\n",
0118           i
0119         );
0120         continue;
0121       }
0122 
0123       sc = rtems_task_create(
0124         rtems_build_name('T', 'A', '0', '0'+i),
0125         4,
0126         RTEMS_MINIMUM_STACK_SIZE,
0127         RTEMS_DEFAULT_MODES,
0128         RTEMS_DEFAULT_ATTRIBUTES,
0129         &task_data[ i ].id
0130       );
0131       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0132 
0133       printf(
0134         "Set TA%" PRIdrtems_task_argument " affinity to cpu %d\n",
0135         i,
0136         task_data[i].expected_cpu
0137       );
0138       sc = rtems_task_set_affinity( task_data[ i ].id, size, &task_data[i].cpuset );
0139       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0140 
0141       printf(
0142         "Start TA%" PRIdrtems_task_argument " on cpu %d\n",
0143         i,
0144         task_data[i].expected_cpu
0145       );
0146       sc = rtems_task_start( task_data[ i ].id, task, i );
0147       rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0148   }
0149 
0150   /* spin for 100 ticks */
0151   test_delay(100);
0152 
0153   printf("Verify Tasks Ran\n");
0154   for (i = 0; i < NUM_CPUS; i++) {
0155 
0156     /* Skip if this cpu doesn't exist, task doesn't exist */
0157     if ( task_data[i].expected_cpu >= cpu_count ) {
0158       printf(
0159         "Skipping TA0%" PRIdrtems_task_argument
0160           " because on a core we do not have\n",
0161         i
0162       );
0163       continue;
0164     }
0165 
0166     /* print the expected and actual values */
0167     printf(
0168       "TA0%" PRIdrtems_task_argument ": ran=%d expected=%d actual=%d\n",
0169       i,
0170       task_data[i].ran,
0171       task_data[i].expected_cpu,
0172       task_data[i].actual_cpu
0173     );
0174 
0175     /*  Abort test if values are not as expected */
0176     rtems_test_assert( task_data[i].ran == true );
0177     rtems_test_assert( task_data[i].expected_cpu == task_data[i].actual_cpu );
0178   }
0179 }
0180 
0181 static void Init(rtems_task_argument arg)
0182 {
0183   TEST_BEGIN();
0184 
0185   test();
0186 
0187   TEST_END();
0188   rtems_test_exit(0);
0189 }
0190 
0191 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0192 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0193 
0194 #define CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
0195 
0196 #define CONFIGURE_MAXIMUM_PROCESSORS NUM_CPUS
0197 
0198 #define CONFIGURE_MAXIMUM_TASKS          TASK_COUNT
0199 
0200 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0201 
0202   #define CONFIGURE_INIT_TASK_PRIORITY      8
0203 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0204 
0205 #define CONFIGURE_INIT
0206 
0207 #include <rtems/confdefs.h>