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  * Use the Init task to walk the higher priority TA1 across all the cores.
0031  */
0032 
0033 #ifdef HAVE_CONFIG_H
0034 #include "config.h"
0035 #endif
0036 
0037 #include <rtems.h>
0038 
0039 #include "tmacros.h"
0040 
0041 const char rtems_test_name[] = "SMPSCHEDAFFINITY 4";
0042 
0043 #define NUM_CPUS   4
0044 #define TASK_COUNT 2
0045 
0046 struct task_data_t {
0047   rtems_id   id;
0048   int        expected_cpu;
0049   bool       ran;
0050   int        actual_cpu;
0051 };
0052 
0053 struct task_data_t task_data = {
0054   0x0, 2, false, 0xff
0055 };
0056 
0057 rtems_id           task_sem;
0058 
0059 static void task(rtems_task_argument arg);
0060 
0061 static void test_delay(int ticks)
0062 { 
0063   rtems_interval start, stop;
0064   start = rtems_clock_get_ticks_since_boot();
0065   do {
0066     stop = rtems_clock_get_ticks_since_boot();
0067   } while ( (stop - start) < ticks );
0068 }
0069 
0070 /*
0071  * Task that continually sets the cpu and 
0072  * run indicators without blocking.
0073  */
0074 static void task(rtems_task_argument arg)
0075 {
0076   rtems_status_code   sc;
0077 
0078   while (true) {
0079     sc = rtems_semaphore_obtain (task_sem, RTEMS_NO_WAIT, 0);
0080     if (sc == RTEMS_SUCCESSFUL) {
0081       task_data.ran = true;
0082       task_data.actual_cpu = rtems_scheduler_get_processor();
0083       rtems_semaphore_release(task_sem);
0084     }
0085   }
0086 }
0087 
0088 static void test(void)
0089 {
0090   rtems_status_code   sc;
0091   uint32_t            cpu_count;
0092   int                 cpu;
0093   int                 i;
0094   cpu_set_t           cpuset;
0095 
0096   /* Get the number of processors that we are using. */
0097   cpu_count = rtems_scheduler_get_processor_maximum();
0098   if (cpu_count < 2) {
0099     printf("Error: Test requires at least 2 cpus\n");
0100     return;
0101   }
0102 
0103   printf("Create Semaphore\n");
0104   sc = rtems_semaphore_create(  
0105     rtems_build_name('S', 'E', 'M', '0'),
0106     1,                                               /* initial count = 1 */
0107     RTEMS_BINARY_SEMAPHORE |
0108     RTEMS_PRIORITY | 
0109     RTEMS_PRIORITY_CEILING,
0110     0,
0111     &task_sem
0112   );  
0113   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0114 
0115   /*
0116    * Create and start TA1 at a higher priority
0117    * than the init task. 
0118    */
0119   sc = rtems_task_create(
0120     rtems_build_name('T', 'A', '0', '1'),
0121     4,
0122     RTEMS_MINIMUM_STACK_SIZE,
0123     RTEMS_DEFAULT_MODES,
0124     RTEMS_DEFAULT_ATTRIBUTES,
0125     &task_data.id
0126   );
0127   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0128 
0129   printf("Start TA1\n");
0130   sc = rtems_task_start( task_data.id, task, 0 );
0131   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0132 
0133   /* 
0134    * Verify the Init task is running on the max core.
0135    */ 
0136   printf("Verify Init task is on cpu %" PRIu32 "\n",cpu_count-1);
0137   cpu = rtems_scheduler_get_processor();
0138   rtems_test_assert(cpu == (cpu_count-1));
0139 
0140   /* Walk TA1 across all of the cores */
0141   for(i=0; i < cpu_count; i++) {
0142     /* Set the Affinity to core i */
0143     CPU_ZERO(&cpuset);
0144     CPU_SET(i, &cpuset);
0145     printf("Set Affinity TA1 to cpu %d\n", i);
0146     sc = rtems_task_set_affinity( task_data.id, sizeof(cpuset), &cpuset );
0147     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0148 
0149     /* Wait a bit to be sure it has switched cores then clear the task data */
0150     test_delay(50);
0151     while( rtems_semaphore_obtain (task_sem, RTEMS_NO_WAIT, 0) != RTEMS_SUCCESSFUL );
0152     task_data.ran = false;
0153     task_data.expected_cpu = i;
0154     rtems_semaphore_release(task_sem);
0155     test_delay(50);
0156 
0157     /* Verify the task ran on core i */
0158     while( rtems_semaphore_obtain (task_sem, RTEMS_NO_WAIT, 0) != RTEMS_SUCCESSFUL );
0159     if (task_data.ran != true)
0160       printf("Error: TA01 never ran.\n");
0161     else
0162       printf(
0163         "TA1 expected cpu: %d actual cpu %d\n", 
0164         task_data.expected_cpu,
0165         task_data.actual_cpu
0166       );
0167     rtems_test_assert(task_data.ran == true);
0168     rtems_test_assert(task_data.expected_cpu == task_data.actual_cpu);
0169     rtems_semaphore_release(task_sem);
0170   }
0171 }
0172 
0173 static void Init(rtems_task_argument arg)
0174 {
0175   TEST_BEGIN();
0176 
0177   test();
0178 
0179   TEST_END();
0180   rtems_test_exit(0);
0181 }
0182 
0183 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0184 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0185 
0186 #define CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
0187 
0188 #define CONFIGURE_MAXIMUM_SEMAPHORES 1
0189 
0190 #define CONFIGURE_MAXIMUM_PROCESSORS NUM_CPUS
0191 
0192 #define CONFIGURE_MAXIMUM_TASKS          TASK_COUNT
0193 
0194 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0195 
0196 #define CONFIGURE_INIT_TASK_PRIORITY      8
0197 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0198 
0199 #define CONFIGURE_INIT
0200 
0201 #include <rtems/confdefs.h>