aboutsummaryrefslogtreecommitdiff
path: root/openmp/runtime/test/affinity/libomp_test_affinity.h
blob: fb9316a3ed2dc4e64adbb8fbc05e3acd3bfc35d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifndef LIBOMP_TEST_AFFINITY_H
#define LIBOMP_TEST_AFFINITY_H

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct affinity_mask_t {
  size_t setsize;
  cpu_set_t *set;
} affinity_mask_t;

#ifdef __ve__
// VE's sched_getaffinity put garbage if the buffer is too big.  512 is
// a good number to make all tests run correctly.
#define AFFINITY_MAX_CPUS 512
#else
#define AFFINITY_MAX_CPUS (32 * 64)
#endif

// Operating system affinity mask API
static void affinity_mask_zero(affinity_mask_t *mask) {
  CPU_ZERO_S(mask->setsize, mask->set);
}

static affinity_mask_t *affinity_mask_alloc() {
  size_t setsize = CPU_ALLOC_SIZE(AFFINITY_MAX_CPUS);
  cpu_set_t *set = CPU_ALLOC(AFFINITY_MAX_CPUS);
  affinity_mask_t *retval = (affinity_mask_t *)malloc(sizeof(affinity_mask_t));
  retval->setsize = setsize;
  retval->set = set;
  affinity_mask_zero(retval);
  return retval;
}

static void affinity_mask_free(affinity_mask_t *mask) { CPU_FREE(mask->set); }

static void affinity_mask_copy(affinity_mask_t *dest,
                               const affinity_mask_t *src) {
  memcpy(dest->set, src->set, dest->setsize);
}

static void affinity_mask_set(affinity_mask_t *mask, int cpu) {
  CPU_SET_S(cpu, mask->setsize, mask->set);
}

static void affinity_mask_clr(affinity_mask_t *mask, int cpu) {
  CPU_CLR_S(cpu, mask->setsize, mask->set);
}

static int affinity_mask_isset(const affinity_mask_t *mask, int cpu) {
  return CPU_ISSET_S(cpu, mask->setsize, mask->set);
}

static int affinity_mask_count(const affinity_mask_t *mask) {
  return CPU_COUNT_S(mask->setsize, mask->set);
}

static int affinity_mask_equal(const affinity_mask_t *mask1,
                               const affinity_mask_t *mask2) {
  return CPU_EQUAL_S(mask1->setsize, mask1->set, mask2->set);
}

static void get_thread_affinity(affinity_mask_t *mask) {
  if (sched_getaffinity(0, mask->setsize, mask->set) != 0) {
    perror("sched_getaffinity()");
    exit(EXIT_FAILURE);
  }
}

static void set_thread_affinity(const affinity_mask_t *mask) {
  if (sched_setaffinity(0, mask->setsize, mask->set) != 0) {
    perror("sched_setaffinity()");
    exit(EXIT_FAILURE);
  }
}

static void affinity_update_snprintf_values(char **ptr, size_t *remaining,
                                            size_t n, size_t *retval) {
  if (n > *remaining && *remaining > 0) {
    *ptr += *remaining;
    *remaining = 0;
  } else {
    *ptr += n;
    *remaining -= n;
  }
  *retval += n;
}

static size_t affinity_mask_snprintf(char *buf, size_t bufsize,
                                     const affinity_mask_t *mask) {
  int cpu, need_comma, begin, end;
  size_t n;
  char *ptr = buf;
  size_t remaining = bufsize;
  size_t retval = 0;

  n = snprintf(ptr, remaining, "%c", '{');
  affinity_update_snprintf_values(&ptr, &remaining, n, &retval);

  need_comma = 0;
  for (cpu = 0; cpu < AFFINITY_MAX_CPUS; cpu++) {
    if (!affinity_mask_isset(mask, cpu))
      continue;
    if (need_comma) {
      n = snprintf(ptr, remaining, "%c", ',');
      affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
    }
    begin = cpu;
    // Find end of range (inclusive end)
    for (end = begin + 1; end < AFFINITY_MAX_CPUS; ++end) {
      if (!affinity_mask_isset(mask, end))
        break;
    }
    end--;

    if (end - begin >= 2) {
      n = snprintf(ptr, remaining, "%d-%d", begin, end);
      affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
    } else if (end - begin == 1) {
      n = snprintf(ptr, remaining, "%d,%d", begin, end);
      affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
    } else if (end - begin == 0) {
      n = snprintf(ptr, remaining, "%d", begin);
      affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
    }
    need_comma = 1;
    cpu = end;
  }
  n = snprintf(ptr, remaining, "%c", '}');
  affinity_update_snprintf_values(&ptr, &remaining, n, &retval);
  return retval;
}
#endif