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) 1989-2011.
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 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032 
0033 #define NUM_CPUS   4
0034 
0035 #define  _GNU_SOURCE
0036 
0037 #include <tmacros.h>
0038 #include <errno.h>
0039 #include <pthread.h>
0040 #include <sched.h>
0041 
0042 const char rtems_test_name[] = "SMPPSXAFFINITY 2";
0043 
0044 pthread_t           Init_id;
0045 pthread_t           Med_id[NUM_CPUS-1];
0046 pthread_t           Low_id[NUM_CPUS];
0047 
0048 /* forward declarations to avoid warnings */
0049 void *POSIX_Init(void *argument);
0050 void Validate_setaffinity_errors(void);
0051 void Validate_getaffinity_errors(void);
0052 void Validate_affinity(void);
0053 void *Thread_1(void *unused);
0054 
0055 void *Thread_1(void *unused)
0056 {
0057   while(1);
0058 }
0059 
0060 void Validate_setaffinity_errors(void)
0061 {
0062   int                 sc;
0063   cpu_set_t           cpuset;
0064 
0065   /* Verify pthread_setaffinity_np checks that more cpu's don't hurt. */
0066   CPU_FILL(&cpuset);
0067   puts( "Init - pthread_setaffinity_np - Lots of cpus - SUCCESS" );
0068   sc = pthread_setaffinity_np( Init_id, sizeof(cpu_set_t), &cpuset );
0069   rtems_test_assert( sc == 0 );
0070 
0071   /* Verify pthread_setaffinity_np checks that at least one cpu is set */
0072   CPU_ZERO(&cpuset);
0073   puts( "Init - pthread_setaffinity_np - no cpu - EINVAL" );
0074   sc = pthread_setaffinity_np( Init_id, sizeof(cpu_set_t), &cpuset );
0075   rtems_test_assert( sc == EINVAL );
0076 
0077   /* Verify pthread_setaffinity_np checks that at thread id is valid */
0078   CPU_ZERO(&cpuset);
0079   CPU_SET(0, &cpuset);
0080   puts( "Init - pthread_setaffinity_np - Invalid thread - ESRCH" );
0081   sc = pthread_setaffinity_np( 999, sizeof(cpu_set_t), &cpuset );
0082   rtems_test_assert( sc == ESRCH );
0083 
0084   /* Verify pthread_setaffinity_np validates cpusetsize */
0085   puts( "Init - pthread_setaffinity_np - Invalid cpusetsize - EINVAL" );
0086   sc = pthread_setaffinity_np( Init_id,  1, &cpuset );
0087   rtems_test_assert( sc == EINVAL );
0088 
0089   /* Verify pthread_setaffinity_np validates cpuset */
0090   puts( "Init - pthread_setaffinity_np - Invalid cpuset - EFAULT" );
0091   sc = pthread_setaffinity_np( Init_id, sizeof(cpu_set_t), NULL );
0092   rtems_test_assert( sc == EFAULT );
0093 }
0094 
0095 void Validate_getaffinity_errors(void)
0096 {
0097   int                 sc;
0098   cpu_set_t           cpuset;
0099 
0100   /* Verify pthread_getaffinity_np checks that at thread id is valid */
0101   CPU_ZERO(&cpuset);
0102   CPU_SET(0, &cpuset);
0103   puts( "Init - pthread_getaffinity_np - Invalid thread - ESRCH" );
0104   sc = pthread_getaffinity_np( 999, sizeof(cpu_set_t), &cpuset );
0105   rtems_test_assert( sc == ESRCH );
0106 
0107   /* Verify pthread_getaffinity_np validates cpusetsize */
0108   puts( "Init - pthread_getaffinity_np - Invalid cpusetsize - EINVAL" );
0109   sc = pthread_getaffinity_np( Init_id,  1, &cpuset );
0110   rtems_test_assert( sc == EINVAL );
0111 
0112   /* Verify pthread_getaffinity_np validates cpuset */
0113   puts("Init - pthread_getaffinity_np - Invalid cpuset - EFAULT");
0114   sc = pthread_getaffinity_np( Init_id, sizeof(cpu_set_t), NULL );
0115   rtems_test_assert( sc == EFAULT );
0116 }
0117 
0118 void Validate_affinity(void )
0119 {
0120   pthread_attr_t       attr;
0121   cpu_set_t            cpuset0;
0122   cpu_set_t            cpuset1;
0123   cpu_set_t            cpuset2;
0124   uint32_t             i;
0125   int                  sc;
0126   int                  cpu_count;
0127   struct sched_param   param;
0128 
0129 
0130   puts( "Init - Set Init priority to high");
0131   sc = pthread_getattr_np( Init_id, &attr );
0132   rtems_test_assert( sc == 0 );
0133 
0134   sc = pthread_attr_setstack( &attr, NULL, 0 );
0135   rtems_test_assert( sc == 0 );
0136 
0137   sc = pthread_attr_getschedparam( &attr, &param );
0138   rtems_test_assert( sc == 0 );
0139   param.sched_priority = sched_get_priority_max( SCHED_FIFO );
0140   sc = pthread_setschedparam( Init_id, SCHED_FIFO, &param );
0141   rtems_test_assert( !sc );
0142 
0143   sc = pthread_getaffinity_np( Init_id, sizeof(cpu_set_t), &cpuset0 );
0144   rtems_test_assert( !sc );
0145 
0146   /* Get the number of processors that we are using. */
0147   cpu_count = rtems_scheduler_get_processor_maximum();
0148 
0149   /* Fill the remaining cpus with med priority tasks */
0150   puts( "Init - Create Medium priority tasks");
0151   for (i=0; i<(cpu_count-1); i++){
0152     sc = pthread_create( &Med_id[i], &attr, Thread_1, NULL );
0153     rtems_test_assert( !sc );
0154   }
0155 
0156   puts( "Init - Verify Medium priority tasks");
0157   for (i=0; i<(cpu_count-1); i++){
0158     sc = pthread_getaffinity_np( Med_id[i], sizeof(cpu_set_t), &cpuset2 );
0159     rtems_test_assert( !sc );
0160     rtems_test_assert( CPU_EQUAL(&cpuset0, &cpuset2) );
0161   }
0162 
0163   /*
0164    * Create low priority thread for each remaining cpu with the affinity
0165    * set to only run on one cpu.
0166    */
0167   puts( "Init - Create  Low priority tasks");
0168   for (i=0; i<cpu_count; i++){
0169     CPU_ZERO(&cpuset1);
0170     CPU_SET(i, &cpuset1);
0171 
0172     sc = pthread_attr_setaffinity_np( &attr, sizeof(cpu_set_t), &cpuset1 );
0173     rtems_test_assert( !sc );
0174 
0175     sc = pthread_create( &Low_id[i], &attr, Thread_1, NULL );
0176     rtems_test_assert( !sc );
0177   }
0178 
0179   /* Verify affinity on low priority tasks */
0180   puts( "Init - Verify Low priority tasks");
0181   for (i=0; i<(cpu_count-1); i++){
0182     CPU_ZERO(&cpuset1);
0183     CPU_SET(i, &cpuset1);
0184 
0185     sc = pthread_getaffinity_np( Low_id[i], sizeof(cpu_set_t), &cpuset2 );
0186     rtems_test_assert( !sc );
0187     rtems_test_assert( CPU_EQUAL(&cpuset1, &cpuset2) );
0188   }
0189 
0190   /* Change the affinity for each low priority task */
0191   puts("Init - Change affinity on Low priority tasks");
0192   CPU_COPY(&cpuset0, &cpuset1);
0193   for (i=0; i<cpu_count; i++){
0194 
0195     CPU_CLR(i, &cpuset1);
0196     sc = pthread_setaffinity_np( Low_id[i], sizeof(cpu_set_t), &cpuset1 );
0197 
0198     /* Verify no cpu's are now set in the cpuset */
0199     if (i== (cpu_count-1)) {
0200       rtems_test_assert( sc == EINVAL );
0201       sc = pthread_setaffinity_np( Low_id[i], sizeof(cpu_set_t), &cpuset0 );
0202     }
0203     rtems_test_assert( !sc );
0204   }
0205 
0206   puts("Init - Validate affinity on Low priority tasks");
0207   CPU_COPY(&cpuset0, &cpuset1);
0208   for (i=0; i<cpu_count; i++){
0209     CPU_CLR(i, &cpuset1);
0210 
0211     sc = pthread_getaffinity_np( Low_id[i], sizeof(cpu_set_t), &cpuset2 );
0212     rtems_test_assert( !sc );
0213     if (i== (cpu_count-1))
0214       rtems_test_assert( CPU_EQUAL(&cpuset0, &cpuset2) );
0215     else
0216       rtems_test_assert( CPU_EQUAL(&cpuset1, &cpuset2) );
0217   }
0218 }
0219 
0220 void *POSIX_Init(
0221   void *ignored
0222 )
0223 {
0224   TEST_BEGIN();
0225 
0226   /* Initialize thread id */
0227   Init_id = pthread_self();
0228 
0229   Validate_setaffinity_errors();
0230   Validate_getaffinity_errors();
0231   Validate_affinity();
0232 
0233   TEST_END();
0234   rtems_test_exit(0);
0235 }
0236 
0237 /* configuration information */
0238 
0239 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0240 #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
0241 
0242 #define CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
0243 
0244 #define CONFIGURE_MAXIMUM_PROCESSORS NUM_CPUS
0245 
0246 #define CONFIGURE_MAXIMUM_POSIX_THREADS (NUM_CPUS*2)
0247 
0248 #define CONFIGURE_POSIX_INIT_THREAD_TABLE
0249 
0250 #define CONFIGURE_INIT
0251 #include <rtems/confdefs.h>
0252 
0253 /* global variables */