00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00038 #ifndef TOPOLOGY_CPUSET_H
00039 #define TOPOLOGY_CPUSET_H
00040
00041 #include <topology/config.h>
00042 #include <topology/cpuset-bits.h>
00043
00044
00058 typedef struct { unsigned long s[TOPO_CPUSUBSET_COUNT]; } topo_cpuset_t;
00059
00060
00061
00062
00063
00064
00065
00067 #define TOPO_CPUSET_ZERO (topo_cpuset_t){ .s[0 ... TOPO_CPUSUBSET_COUNT-1] = TOPO_CPUSUBSET_ZERO }
00068
00069 #define TOPO_CPUSET_FULL (topo_cpuset_t){ .s[0 ... TOPO_CPUSUBSET_COUNT-1] = TOPO_CPUSUBSET_FULL }
00070
00071 #define TOPO_CPUSET_CPU(cpu) ({ topo_cpuset_t __set = TOPO_CPUSET_ZERO; TOPO_CPUSUBSET_CPUSUBSET(__set,cpu) = TOPO_CPUSUBSET_VAL(cpu); __set; })
00072
00073
00074
00075
00076
00077
00082 #define TOPO_CPUSET_STRING_LENGTH (TOPO_CPUSET_SUBSTRING_COUNT*(TOPO_CPUSET_SUBSTRING_LENGTH+1))
00083
00084 #define TOPO_PRIxCPUSET "s"
00085
00092 static __inline__ int
00093 topo_cpuset_snprintf(char * __topo_restrict buf, size_t buflen, const topo_cpuset_t * __topo_restrict set)
00094 {
00095 ssize_t size = buflen;
00096 char *tmp = buf;
00097 int res;
00098 int i;
00099 unsigned long accum = 0;
00100 int accumed = 0;
00101 #if TOPO_BITS_PER_LONG == TOPO_CPUSET_SUBSTRING_SIZE
00102 const unsigned long accum_mask = ~0UL;
00103 #else
00104 const unsigned long accum_mask = ((1UL << TOPO_CPUSET_SUBSTRING_SIZE) - 1) << (TOPO_BITS_PER_LONG - TOPO_CPUSET_SUBSTRING_SIZE);
00105 #endif
00106
00107
00108 *tmp = '\0';
00109
00110 i=TOPO_CPUSUBSET_COUNT-1;
00111 while (i>=0 || accumed) {
00112
00113 if (tmp != buf) {
00114 res = snprintf(tmp, size, ",");
00115 tmp += res; size -= res;
00116 if (size <= 1)
00117 break;
00118 }
00119
00120
00121 if (!accumed) {
00122 accum = set->s[i--];
00123 accumed = TOPO_BITS_PER_LONG;
00124 }
00125
00126 if (accum & accum_mask) {
00127
00128 res = snprintf(tmp, size, TOPO_PRIxCPUSUBSET, (accum & accum_mask) >> (TOPO_BITS_PER_LONG - TOPO_CPUSET_SUBSTRING_SIZE));
00129 } else if (i == -1 && accumed == TOPO_CPUSET_SUBSTRING_SIZE)
00130
00131 res = snprintf(tmp, size, "0");
00132 else
00133 res = 0;
00134 #if TOPO_BITS_PER_LONG == TOPO_CPUSET_SUBSTRING_SIZE
00135 accum = 0;
00136 accumed = 0;
00137 #else
00138 accum <<= TOPO_CPUSET_SUBSTRING_SIZE;
00139 accumed -= TOPO_CPUSET_SUBSTRING_SIZE;
00140 #endif
00141
00142 tmp += res; size -= res;
00143 if (size <= 1)
00144 break;
00145 }
00146
00147 return tmp-buf+1;
00148 }
00149
00154 static __inline__ void
00155 topo_cpuset_from_string(const char * __topo_restrict string, topo_cpuset_t * __topo_restrict set)
00156 {
00157 char * current = (char *) string;
00158 int count=0, i;
00159 unsigned long accum = 0;
00160 int accumed = 0;
00161
00162 while (*current != '\0') {
00163 unsigned long val;
00164 char *next;
00165 val = strtoul(current, &next, 16);
00166
00167 #if TOPO_BITS_PER_LONG == TOPO_CPUSET_SUBSTRING_SIZE
00168 accum = val;
00169 #else
00170 accum = (accum << TOPO_CPUSET_SUBSTRING_SIZE) | val;
00171 #endif
00172 accumed += TOPO_CPUSET_SUBSTRING_SIZE;
00173 if (accumed == TOPO_BITS_PER_LONG) {
00174 set->s[TOPO_CPUSUBSET_COUNT-1-count] = accum;
00175 count++;
00176 accum = 0;
00177 accumed = 0;
00178 }
00179 if (*next != ',')
00180 break;
00181 current = next+1;
00182 if (count == TOPO_CPUSUBSET_COUNT)
00183 break;
00184 }
00185
00186
00187 for (i = 0; i < count; i++) {
00188 set->s[i] = accum;
00189 set->s[i] |= set->s[TOPO_CPUSUBSET_COUNT-count+i] << accumed;
00190 if (accumed)
00191 accum = set->s[TOPO_CPUSUBSET_COUNT-count+i] >> (TOPO_BITS_PER_LONG - accumed);
00192 }
00193
00194 if (accumed && count < TOPO_CPUSUBSET_COUNT)
00195 set->s[i++] = accum;
00196 for( ; i<TOPO_CPUSUBSET_COUNT; i++)
00197 set->s[i] = 0;
00198 }
00199
00200
00201
00207 static __inline__ void topo_cpuset_zero(topo_cpuset_t * set)
00208 {
00209 int i;
00210 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00211 TOPO_CPUSUBSET_SUBSET(*set,i) = TOPO_CPUSUBSET_ZERO;
00212 }
00213
00215 static __inline__ void topo_cpuset_fill(topo_cpuset_t * set)
00216 {
00217 int i;
00218 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00219 TOPO_CPUSUBSET_SUBSET(*set,i) = TOPO_CPUSUBSET_FULL;
00220 }
00221
00223 static __inline__ void topo_cpuset_from_ulong(topo_cpuset_t *set, unsigned long mask)
00224 {
00225 int i;
00226 TOPO_CPUSUBSET_SUBSET(*set,0) = mask;
00227 for(i=1; i<TOPO_CPUSUBSET_COUNT; i++)
00228 TOPO_CPUSUBSET_SUBSET(*set,i) = TOPO_CPUSUBSET_ZERO;
00229 }
00230
00232 static __inline__ void topo_cpuset_from_ith_ulong(topo_cpuset_t *set, int i, unsigned long mask)
00233 {
00234 int j;
00235 TOPO_CPUSUBSET_SUBSET(*set,i) = mask;
00236 for(j=1; j<TOPO_CPUSUBSET_COUNT; j++)
00237 if (j != i)
00238 TOPO_CPUSUBSET_SUBSET(*set,j) = TOPO_CPUSUBSET_ZERO;
00239 }
00240
00242 static __inline__ unsigned long topo_cpuset_to_ulong(const topo_cpuset_t *set)
00243 {
00244 return TOPO_CPUSUBSET_SUBSET(*set,0);
00245 }
00246
00248 static __inline__ unsigned long topo_cpuset_to_ith_ulong(const topo_cpuset_t *set, int i)
00249 {
00250 return TOPO_CPUSUBSET_SUBSET(*set,i);
00251 }
00252
00254 static __inline__ void topo_cpuset_cpu(topo_cpuset_t * set,
00255 unsigned cpu)
00256 {
00257 topo_cpuset_zero(set);
00258 TOPO_CPUSUBSET_CPUSUBSET(*set,cpu) |= TOPO_CPUSUBSET_VAL(cpu);
00259 }
00260
00262 static __inline__ void topo_cpuset_all_but_cpu(topo_cpuset_t * set,
00263 unsigned cpu)
00264 {
00265 topo_cpuset_fill(set);
00266 TOPO_CPUSUBSET_CPUSUBSET(*set,cpu) &= ~TOPO_CPUSUBSET_VAL(cpu);
00267 }
00268
00270 static __inline__ void topo_cpuset_set(topo_cpuset_t * set,
00271 unsigned cpu)
00272 {
00273 TOPO_CPUSUBSET_CPUSUBSET(*set,cpu) |= TOPO_CPUSUBSET_VAL(cpu);
00274 }
00275
00277 static __inline__ void topo_cpuset_set_range(topo_cpuset_t * set,
00278 unsigned begincpu, unsigned endcpu)
00279 {
00280 int i;
00281 for (i=begincpu; i<=endcpu; i++)
00282 TOPO_CPUSUBSET_CPUSUBSET(*set,i) |= TOPO_CPUSUBSET_VAL(i);
00283 }
00284
00286 static __inline__ void topo_cpuset_clr(topo_cpuset_t * set,
00287 unsigned cpu)
00288 {
00289 TOPO_CPUSUBSET_CPUSUBSET(*set,cpu) &= ~TOPO_CPUSUBSET_VAL(cpu);
00290 }
00291
00293 static __inline__ int topo_cpuset_isset(const topo_cpuset_t * set,
00294 unsigned cpu)
00295 {
00296 return (TOPO_CPUSUBSET_CPUSUBSET(*set,cpu) & TOPO_CPUSUBSET_VAL(cpu)) != 0;
00297 }
00298
00300 static __inline__ int topo_cpuset_iszero(const topo_cpuset_t *set)
00301 {
00302 int i;
00303 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00304 if (TOPO_CPUSUBSET_SUBSET(*set,i) != TOPO_CPUSUBSET_ZERO)
00305 return 0;
00306 return 1;
00307 }
00308
00310 static __inline__ int topo_cpuset_isfull(const topo_cpuset_t *set)
00311 {
00312 int i;
00313 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00314 if (TOPO_CPUSUBSET_SUBSET(*set,i) != TOPO_CPUSUBSET_FULL)
00315 return 0;
00316 return 1;
00317 }
00318
00320 static __inline__ int topo_cpuset_isequal (const topo_cpuset_t *set1,
00321 const topo_cpuset_t *set2)
00322 {
00323 int i;
00324 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00325 if (TOPO_CPUSUBSET_SUBSET(*set1,i) != TOPO_CPUSUBSET_SUBSET(*set2,i))
00326 return 0;
00327 return 1;
00328 }
00329
00331 static __inline__ int topo_cpuset_intersects (const topo_cpuset_t *set1,
00332 const topo_cpuset_t *set2)
00333 {
00334 int i;
00335 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00336 if ((TOPO_CPUSUBSET_SUBSET(*set1,i) & TOPO_CPUSUBSET_SUBSET(*set2,i)) != TOPO_CPUSUBSET_ZERO)
00337 return 1;
00338 return 0;
00339 }
00340
00342 static __inline__ int topo_cpuset_isincluded (const topo_cpuset_t *sub_set,
00343 const topo_cpuset_t *super_set)
00344 {
00345 int i;
00346 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00347 if (TOPO_CPUSUBSET_SUBSET(*super_set,i) != (TOPO_CPUSUBSET_SUBSET(*super_set,i) | TOPO_CPUSUBSET_SUBSET(*sub_set,i)))
00348 return 0;
00349 return 1;
00350 }
00351
00353 static __inline__ void topo_cpuset_orset (topo_cpuset_t *set,
00354 const topo_cpuset_t *modifier_set)
00355 {
00356 int i;
00357 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00358 TOPO_CPUSUBSET_SUBSET(*set,i) |= TOPO_CPUSUBSET_SUBSET(*modifier_set,i);
00359 }
00360
00362 static __inline__ void topo_cpuset_andset (topo_cpuset_t *set,
00363 const topo_cpuset_t *modifier_set)
00364 {
00365 int i;
00366 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00367 TOPO_CPUSUBSET_SUBSET(*set,i) &= TOPO_CPUSUBSET_SUBSET(*modifier_set,i);
00368 }
00369
00371 static __inline__ void topo_cpuset_clearset (topo_cpuset_t *set,
00372 const topo_cpuset_t *modifier_set)
00373 {
00374 int i;
00375 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00376 TOPO_CPUSUBSET_SUBSET(*set,i) &= ~TOPO_CPUSUBSET_SUBSET(*modifier_set,i);
00377 }
00378
00380 static __inline__ void topo_cpuset_xorset (topo_cpuset_t *set,
00381 const topo_cpuset_t *modifier_set)
00382 {
00383 int i;
00384 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00385 TOPO_CPUSUBSET_SUBSET(*set,i) ^= TOPO_CPUSUBSET_SUBSET(*modifier_set,i);
00386 }
00387
00389 static __inline__ int topo_cpuset_first(const topo_cpuset_t * cpuset)
00390 {
00391 int i;
00392 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++) {
00393
00394 int _ffs = topo_ffsl(TOPO_CPUSUBSET_SUBSET(*cpuset,i));
00395 if (_ffs>0)
00396 return _ffs - 1 + TOPO_CPUSUBSET_SIZE*i;
00397 }
00398
00399 return -1;
00400 }
00401
00408 static __inline__ void topo_cpuset_singlify(topo_cpuset_t * set)
00409 {
00410 int i,found = 0;
00411 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++) {
00412 if (found) {
00413 TOPO_CPUSUBSET_SUBSET(*set,i) = TOPO_CPUSUBSET_ZERO;
00414 continue;
00415 } else {
00416
00417 int _ffs = topo_ffsl(TOPO_CPUSUBSET_SUBSET(*set,i));
00418 if (_ffs>0) {
00419 TOPO_CPUSUBSET_SUBSET(*set,i) = TOPO_CPUSUBSET_VAL(_ffs-1);
00420 found = 1;
00421 }
00422 }
00423 }
00424 }
00425
00431 static __inline__ int topo_cpuset_compar_first(const topo_cpuset_t * set1,
00432 const topo_cpuset_t * set2)
00433 {
00434 int i;
00435 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++) {
00436 int _ffs1 = topo_ffsl(TOPO_CPUSUBSET_SUBSET(*set1,i));
00437 int _ffs2 = topo_ffsl(TOPO_CPUSUBSET_SUBSET(*set2,i));
00438 if (!_ffs1 && !_ffs2)
00439 continue;
00440
00441 if (_ffs1 && _ffs2)
00442 return _ffs1-_ffs2;
00443
00444 return _ffs2-_ffs1;
00445 }
00446 return 0;
00447 }
00448
00454 static __inline__ int topo_cpuset_compar(const topo_cpuset_t * set1,
00455 const topo_cpuset_t * set2)
00456 {
00457 int i;
00458 for(i=TOPO_CPUSUBSET_COUNT-1; i>=0; i--) {
00459 if (TOPO_CPUSUBSET_SUBSET(*set1,i) == TOPO_CPUSUBSET_SUBSET(*set2,i))
00460 continue;
00461 return TOPO_CPUSUBSET_SUBSET(*set1,i) < TOPO_CPUSUBSET_SUBSET(*set2,i) ? -1 : 1;
00462 }
00463 return 0;
00464 }
00465
00467 static __inline__ int topo_cpuset_weight(const topo_cpuset_t * set)
00468 {
00469 int weight = 0;
00470 int i;
00471 for(i=0; i<TOPO_CPUSUBSET_COUNT; i++)
00472 weight += topo_weight_long(TOPO_CPUSUBSET_SUBSET(*set,i));
00473 return weight;
00474 }
00475
00481 #define topo_cpuset_foreach_begin(cpu, set) \
00482 for (cpu = 0; cpu < TOPO_NBMAXCPUS; cpu++) \
00483 if (topo_cpuset_isset(set, cpu)) {
00484
00487 #define topo_cpuset_foreach_end() \
00488 }
00489
00492 #endif