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  * Test designed for 2 cores: Init task and TA1 task.
0031  * of equal priorities.  
0032  *
0033  *  - Set TA1 affinity to core 0 verify
0034  *  - Set TA1 affinity to core 1 verify it does not run because
0035  *    the Init task never blocks
0036  *  - Set Init affinity to core 0 verify both tasks are on the correct cores.
0037  */
0038 
0039 #ifdef HAVE_CONFIG_H
0040 #include "config.h"
0041 #endif
0042 
0043 #include <rtems.h>
0044 
0045 #include "tmacros.h"
0046 
0047 const char rtems_test_name[] = "SMPSCHEDAFFINITY 2";
0048 
0049 #define NUM_CPUS   2
0050 
0051 struct task_data_t {
0052   rtems_id   id;
0053   int        expected_cpu;
0054   cpu_set_t  cpuset;
0055   bool       ran;
0056   int        actual_cpu;
0057 };
0058 
0059 struct task_data_t task_data = {
0060   0x0, 0, {{0x3}}, false, -1
0061 };
0062 
0063 rtems_id           task_sem;
0064 
0065 static void task(rtems_task_argument arg);
0066 static void task_verify( bool ran, bool change_affinity, int cpu );
0067 static void init_verify( int expect ); 
0068 
0069 static void test_delay(int ticks)
0070 { 
0071   rtems_interval start, stop;
0072   start = rtems_clock_get_ticks_since_boot();
0073   do {
0074     stop = rtems_clock_get_ticks_since_boot();
0075   } while ( (stop - start) < ticks );
0076 }
0077 
0078 static void task_verify( bool ran, bool change_affinity, int cpu )
0079 {
0080   rtems_status_code   sc;
0081   size_t              size = sizeof(cpu_set_t);
0082 
0083   /* Obtain the semaphore without blocking */
0084   while( rtems_semaphore_obtain (task_sem, RTEMS_NO_WAIT, 0) != RTEMS_SUCCESSFUL );
0085 
0086   /* print the expected and actual values */
0087   printf( "TA01: expected=%d actual=%d ran=%d\n", 
0088    task_data.expected_cpu,
0089    task_data.actual_cpu,
0090    task_data.ran
0091    );
0092 
0093   /* Verify expected results */
0094   rtems_test_assert( task_data.ran == ran );
0095   if (ran)
0096     rtems_test_assert( task_data.expected_cpu == task_data.actual_cpu );
0097 
0098   if (change_affinity) {
0099     printf("Set TA01 to cpu %d\n", cpu);
0100     CPU_ZERO(&task_data.cpuset);
0101     CPU_SET(cpu, &task_data.cpuset);
0102     sc = rtems_task_set_affinity( task_data.id, size, &task_data.cpuset );
0103     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0104   }
0105 
0106   /* Reset the states */
0107   task_data.ran = false;
0108   task_data.expected_cpu = cpu;
0109 
0110   /* Release the semaphore */
0111   rtems_semaphore_release(task_sem);
0112   test_delay(25);
0113 } 
0114 
0115 static void init_verify( int expect ) 
0116 {
0117   int cpu;
0118 
0119 
0120   test_delay(20);
0121 
0122   cpu = rtems_scheduler_get_processor();
0123   printf( "Init: expected=%d actual=%d\n", expect, cpu);
0124   rtems_test_assert( expect == cpu );
0125 }
0126 
0127 static void task(rtems_task_argument arg)
0128 {
0129   rtems_status_code   sc;
0130 
0131   /* Never block and continually get core id  */
0132   while (true) {
0133     sc = rtems_semaphore_obtain (task_sem, RTEMS_NO_WAIT, 0);
0134     if (sc == RTEMS_SUCCESSFUL) {
0135       task_data.actual_cpu = rtems_scheduler_get_processor();
0136       task_data.ran = true;
0137       rtems_semaphore_release(task_sem);
0138       test_delay(25);
0139     }
0140   }
0141 }
0142 
0143 static void test(void)
0144 {
0145   rtems_status_code   sc;
0146   uint32_t            cpu_count;
0147   rtems_id            id_self;
0148   cpu_set_t           cpuset;
0149  
0150   /* Get the number of processors that we are using. */
0151   cpu_count = rtems_scheduler_get_processor_maximum();
0152   if (cpu_count < NUM_CPUS) {
0153     printf("Error: Test requires at least 2 cpus\n");
0154     return;
0155   }
0156 
0157   id_self = rtems_task_self();
0158  
0159   printf("Create Semaphore\n");
0160   sc = rtems_semaphore_create(  
0161     rtems_build_name('S', 'E', 'M', '0'),
0162     1,
0163     RTEMS_BINARY_SEMAPHORE |
0164     RTEMS_PRIORITY | 
0165     RTEMS_PRIORITY_CEILING,
0166     0,
0167     &task_sem
0168   );  
0169   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0170 
0171   printf("Create TA1\n");
0172   sc = rtems_task_create(
0173     rtems_build_name('T', 'A', '0', '1'),
0174     4,
0175     RTEMS_MINIMUM_STACK_SIZE,
0176     RTEMS_DEFAULT_MODES,
0177     RTEMS_DEFAULT_ATTRIBUTES,
0178     &task_data.id
0179   );
0180   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0181 
0182   /* TA1 should start on cpu  0, since init starts on core 1 */
0183   sc = rtems_task_start( task_data.id, task, 1 );
0184   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0185 
0186   /* Verify Init task is on cpu 1  */
0187   init_verify(1);
0188 
0189   /* Verify TA1 on cpu 0 and set the affinity to cpu 0 */
0190   task_verify( true, true, 0 );
0191    
0192   /* Verify Init task is on cpu 1  */
0193   init_verify(1);
0194 
0195   /* Verify TA1 on cpu 0 and change the affinity to cpu 1 */
0196   task_verify( true, true, 1 );
0197 
0198   /* Verify Init task is on cpu 1  */
0199   init_verify(1);
0200 
0201   /* Verify TA1 did not run */
0202   task_verify( false, false, 1 );
0203 
0204   /* Set affinity of Init to cpu 0 */
0205   printf("Set Affinity of init task to cpu 0\n");
0206   CPU_ZERO(&cpuset);
0207   CPU_SET(0, &cpuset);
0208   sc = rtems_task_set_affinity( id_self, sizeof(cpuset), &cpuset );
0209   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0210 
0211   /* Verify init task went to cpu 0 */
0212   test_delay(50);
0213   init_verify(0);
0214 
0215   /* Verfiy TA1 is now running on cpu 1 */
0216   task_verify(true, false, 1);
0217 }
0218 
0219 static void Init(rtems_task_argument arg)
0220 {
0221   TEST_BEGIN();
0222 
0223   test();
0224 
0225   TEST_END();
0226   rtems_test_exit(0);
0227 }
0228 
0229 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0230 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0231 
0232 #define CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
0233 
0234 #define CONFIGURE_MAXIMUM_PROCESSORS NUM_CPUS
0235 
0236 #define CONFIGURE_MAXIMUM_TASKS          NUM_CPUS
0237 
0238 #define CONFIGURE_MAXIMUM_SEMAPHORES 1
0239 
0240 #define CONFIGURE_INIT_TASK_PRIORITY      4
0241 
0242 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0243 
0244 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0245 
0246 #define CONFIGURE_INIT
0247 
0248 #include <rtems/confdefs.h>