xref: /llvm-project/openmp/runtime/test/affinity/libomp_test_affinity.h (revision e8679b93daa0db1e9b1838186f6309f59ad5cd0b)
15ebbb366SPeyton, Jonathan L #ifndef LIBOMP_TEST_AFFINITY_H
25ebbb366SPeyton, Jonathan L #define LIBOMP_TEST_AFFINITY_H
35ebbb366SPeyton, Jonathan L 
45ebbb366SPeyton, Jonathan L #ifndef _GNU_SOURCE
55ebbb366SPeyton, Jonathan L #define _GNU_SOURCE
65ebbb366SPeyton, Jonathan L #endif
75ebbb366SPeyton, Jonathan L #include <sched.h>
85ebbb366SPeyton, Jonathan L #include <stdio.h>
95ebbb366SPeyton, Jonathan L #include <stdlib.h>
105ebbb366SPeyton, Jonathan L #include <string.h>
115ebbb366SPeyton, Jonathan L typedef struct affinity_mask_t {
125ebbb366SPeyton, Jonathan L   size_t setsize;
135ebbb366SPeyton, Jonathan L   cpu_set_t *set;
145ebbb366SPeyton, Jonathan L } affinity_mask_t;
155ebbb366SPeyton, Jonathan L 
16*e8679b93SKazushi Marukawa #ifdef __ve__
17*e8679b93SKazushi Marukawa // VE's sched_getaffinity put garbage if the buffer is too big.  512 is
18*e8679b93SKazushi Marukawa // a good number to make all tests run correctly.
19*e8679b93SKazushi Marukawa #define AFFINITY_MAX_CPUS 512
20*e8679b93SKazushi Marukawa #else
215ebbb366SPeyton, Jonathan L #define AFFINITY_MAX_CPUS (32 * 64)
22*e8679b93SKazushi Marukawa #endif
235ebbb366SPeyton, Jonathan L 
245ebbb366SPeyton, Jonathan L // Operating system affinity mask API
affinity_mask_zero(affinity_mask_t * mask)255ebbb366SPeyton, Jonathan L static void affinity_mask_zero(affinity_mask_t *mask) {
265ebbb366SPeyton, Jonathan L   CPU_ZERO_S(mask->setsize, mask->set);
275ebbb366SPeyton, Jonathan L }
285ebbb366SPeyton, Jonathan L 
affinity_mask_alloc()295ebbb366SPeyton, Jonathan L static affinity_mask_t *affinity_mask_alloc() {
305ebbb366SPeyton, Jonathan L   size_t setsize = CPU_ALLOC_SIZE(AFFINITY_MAX_CPUS);
315ebbb366SPeyton, Jonathan L   cpu_set_t *set = CPU_ALLOC(AFFINITY_MAX_CPUS);
325ebbb366SPeyton, Jonathan L   affinity_mask_t *retval = (affinity_mask_t *)malloc(sizeof(affinity_mask_t));
335ebbb366SPeyton, Jonathan L   retval->setsize = setsize;
345ebbb366SPeyton, Jonathan L   retval->set = set;
355ebbb366SPeyton, Jonathan L   affinity_mask_zero(retval);
365ebbb366SPeyton, Jonathan L   return retval;
375ebbb366SPeyton, Jonathan L }
385ebbb366SPeyton, Jonathan L 
affinity_mask_free(affinity_mask_t * mask)395ebbb366SPeyton, Jonathan L static void affinity_mask_free(affinity_mask_t *mask) { CPU_FREE(mask->set); }
405ebbb366SPeyton, Jonathan L 
affinity_mask_copy(affinity_mask_t * dest,const affinity_mask_t * src)415ebbb366SPeyton, Jonathan L static void affinity_mask_copy(affinity_mask_t *dest,
425ebbb366SPeyton, Jonathan L                                const affinity_mask_t *src) {
435ebbb366SPeyton, Jonathan L   memcpy(dest->set, src->set, dest->setsize);
445ebbb366SPeyton, Jonathan L }
455ebbb366SPeyton, Jonathan L 
affinity_mask_set(affinity_mask_t * mask,int cpu)465ebbb366SPeyton, Jonathan L static void affinity_mask_set(affinity_mask_t *mask, int cpu) {
475ebbb366SPeyton, Jonathan L   CPU_SET_S(cpu, mask->setsize, mask->set);
485ebbb366SPeyton, Jonathan L }
495ebbb366SPeyton, Jonathan L 
affinity_mask_clr(affinity_mask_t * mask,int cpu)505ebbb366SPeyton, Jonathan L static void affinity_mask_clr(affinity_mask_t *mask, int cpu) {
515ebbb366SPeyton, Jonathan L   CPU_CLR_S(cpu, mask->setsize, mask->set);
525ebbb366SPeyton, Jonathan L }
535ebbb366SPeyton, Jonathan L 
affinity_mask_isset(const affinity_mask_t * mask,int cpu)545ebbb366SPeyton, Jonathan L static int affinity_mask_isset(const affinity_mask_t *mask, int cpu) {
555ebbb366SPeyton, Jonathan L   return CPU_ISSET_S(cpu, mask->setsize, mask->set);
565ebbb366SPeyton, Jonathan L }
575ebbb366SPeyton, Jonathan L 
affinity_mask_count(const affinity_mask_t * mask)585ebbb366SPeyton, Jonathan L static int affinity_mask_count(const affinity_mask_t *mask) {
595ebbb366SPeyton, Jonathan L   return CPU_COUNT_S(mask->setsize, mask->set);
605ebbb366SPeyton, Jonathan L }
615ebbb366SPeyton, Jonathan L 
affinity_mask_equal(const affinity_mask_t * mask1,const affinity_mask_t * mask2)625ebbb366SPeyton, Jonathan L static int affinity_mask_equal(const affinity_mask_t *mask1,
635ebbb366SPeyton, Jonathan L                                const affinity_mask_t *mask2) {
645ebbb366SPeyton, Jonathan L   return CPU_EQUAL_S(mask1->setsize, mask1->set, mask2->set);
655ebbb366SPeyton, Jonathan L }
665ebbb366SPeyton, Jonathan L 
get_thread_affinity(affinity_mask_t * mask)675ebbb366SPeyton, Jonathan L static void get_thread_affinity(affinity_mask_t *mask) {
685ebbb366SPeyton, Jonathan L   if (sched_getaffinity(0, mask->setsize, mask->set) != 0) {
695ebbb366SPeyton, Jonathan L     perror("sched_getaffinity()");
705ebbb366SPeyton, Jonathan L     exit(EXIT_FAILURE);
715ebbb366SPeyton, Jonathan L   }
725ebbb366SPeyton, Jonathan L }
735ebbb366SPeyton, Jonathan L 
set_thread_affinity(const affinity_mask_t * mask)745ebbb366SPeyton, Jonathan L static void set_thread_affinity(const affinity_mask_t *mask) {
755ebbb366SPeyton, Jonathan L   if (sched_setaffinity(0, mask->setsize, mask->set) != 0) {
765ebbb366SPeyton, Jonathan L     perror("sched_setaffinity()");
775ebbb366SPeyton, Jonathan L     exit(EXIT_FAILURE);
785ebbb366SPeyton, Jonathan L   }
795ebbb366SPeyton, Jonathan L }
805ebbb366SPeyton, Jonathan L 
affinity_update_snprintf_values(char ** ptr,size_t * remaining,size_t n,size_t * retval)815ebbb366SPeyton, Jonathan L static void affinity_update_snprintf_values(char **ptr, size_t *remaining,
825ebbb366SPeyton, Jonathan L                                             size_t n, size_t *retval) {
835ebbb366SPeyton, Jonathan L   if (n > *remaining && *remaining > 0) {
845ebbb366SPeyton, Jonathan L     *ptr += *remaining;
855ebbb366SPeyton, Jonathan L     *remaining = 0;
865ebbb366SPeyton, Jonathan L   } else {
875ebbb366SPeyton, Jonathan L     *ptr += n;
885ebbb366SPeyton, Jonathan L     *remaining -= n;
895ebbb366SPeyton, Jonathan L   }
905ebbb366SPeyton, Jonathan L   *retval += n;
915ebbb366SPeyton, Jonathan L }
925ebbb366SPeyton, Jonathan L 
affinity_mask_snprintf(char * buf,size_t bufsize,const affinity_mask_t * mask)935ebbb366SPeyton, Jonathan L static size_t affinity_mask_snprintf(char *buf, size_t bufsize,
945ebbb366SPeyton, Jonathan L                                      const affinity_mask_t *mask) {
955ebbb366SPeyton, Jonathan L   int cpu, need_comma, begin, end;
965ebbb366SPeyton, Jonathan L   size_t n;
975ebbb366SPeyton, Jonathan L   char *ptr = buf;
985ebbb366SPeyton, Jonathan L   size_t remaining = bufsize;
995ebbb366SPeyton, Jonathan L   size_t retval = 0;
1005ebbb366SPeyton, Jonathan L 
1015ebbb366SPeyton, Jonathan L   n = snprintf(ptr, remaining, "%c", '{');
1025ebbb366SPeyton, Jonathan L   affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
1035ebbb366SPeyton, Jonathan L 
1045ebbb366SPeyton, Jonathan L   need_comma = 0;
1055ebbb366SPeyton, Jonathan L   for (cpu = 0; cpu < AFFINITY_MAX_CPUS; cpu++) {
1065ebbb366SPeyton, Jonathan L     if (!affinity_mask_isset(mask, cpu))
1075ebbb366SPeyton, Jonathan L       continue;
1085ebbb366SPeyton, Jonathan L     if (need_comma) {
1095ebbb366SPeyton, Jonathan L       n = snprintf(ptr, remaining, "%c", ',');
1105ebbb366SPeyton, Jonathan L       affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
1115ebbb366SPeyton, Jonathan L     }
1125ebbb366SPeyton, Jonathan L     begin = cpu;
1135ebbb366SPeyton, Jonathan L     // Find end of range (inclusive end)
1145ebbb366SPeyton, Jonathan L     for (end = begin + 1; end < AFFINITY_MAX_CPUS; ++end) {
1155ebbb366SPeyton, Jonathan L       if (!affinity_mask_isset(mask, end))
1165ebbb366SPeyton, Jonathan L         break;
1175ebbb366SPeyton, Jonathan L     }
1185ebbb366SPeyton, Jonathan L     end--;
1195ebbb366SPeyton, Jonathan L 
1205ebbb366SPeyton, Jonathan L     if (end - begin >= 2) {
1215ebbb366SPeyton, Jonathan L       n = snprintf(ptr, remaining, "%d-%d", begin, end);
1225ebbb366SPeyton, Jonathan L       affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
1235ebbb366SPeyton, Jonathan L     } else if (end - begin == 1) {
1245ebbb366SPeyton, Jonathan L       n = snprintf(ptr, remaining, "%d,%d", begin, end);
1255ebbb366SPeyton, Jonathan L       affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
1265ebbb366SPeyton, Jonathan L     } else if (end - begin == 0) {
1275ebbb366SPeyton, Jonathan L       n = snprintf(ptr, remaining, "%d", begin);
1285ebbb366SPeyton, Jonathan L       affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
1295ebbb366SPeyton, Jonathan L     }
1305ebbb366SPeyton, Jonathan L     need_comma = 1;
1315ebbb366SPeyton, Jonathan L     cpu = end;
1325ebbb366SPeyton, Jonathan L   }
1335ebbb366SPeyton, Jonathan L   n = snprintf(ptr, remaining, "%c", '}');
1345ebbb366SPeyton, Jonathan L   affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
1355ebbb366SPeyton, Jonathan L   return retval;
1365ebbb366SPeyton, Jonathan L }
1375ebbb366SPeyton, Jonathan L #endif
138