#define _GNU_SOURCE /* feature_test_macros(7) 参照 */ #include <sched.h> void CPU_ZERO(cpu_set_t *set); void CPU_SET(int cpu, cpu_set_t *set); void CPU_CLR(int cpu, cpu_set_t *set); int CPU_ISSET(int cpu, cpu_set_t *set); int CPU_COUNT(cpu_set_t *set); void CPU_AND(cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2); void CPU_OR(cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2); void CPU_XOR(cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2); int CPU_EQUAL(cpu_set_t *set1, cpu_set_t *set2); cpu_set_t *CPU_ALLOC(int num_cpus); void CPU_FREE(cpu_set_t *set); size_t CPU_ALLOC_SIZE(int num_cpus); void CPU_ZERO_S(size_t setsize, cpu_set_t *set); void CPU_SET_S(int cpu, size_t setsize, cpu_set_t *set); void CPU_CLR_S(int cpu, size_t setsize, cpu_set_t *set); int CPU_ISSET_S(int cpu, size_t setsize, cpu_set_t *set); int CPU_COUNT_S(size_t setsize, cpu_set_t *set); void CPU_AND_S(size_t setsize, cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2); void CPU_OR_S(size_t setsize, cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2); void CPU_XOR_S(size_t setsize, cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2); int CPU_EQUAL_S(size_t setsize, cpu_set_t *set1, cpu_set_t *set2);
cpu_set_t データ型はビットマスクとして実装されている。 しかし、 データ構造体はその実装を意識せずに扱うべきであり、 CPU 集合のすべての操作は、 このページで説明されているマクロを通して行うべきである。
以下のマクロが CPU 集合 set を操作するために提供されている。
cpu 引数が指定する場合、 その引数は副作用を伴うべきではない。 上記のマクロは引数を複数回評価する可能性があるからである。
The first CPU on the system corresponds to a cpu value of 0, the next CPU corresponds to a cpu value of 1, and so on. No assumptions should be made about particular CPUs being available, or the set of CPUs being contiguous, since CPUs can be taken offline dynamically or be otherwise absent. The constant CPU_SETSIZE (currently 1024) specifies a value one greater than the maximum CPU number that can be stored in cpu_set_t.
以下のマクロは CPU 集合どうしの論理操作を行う。
以下のマクロを使うと CPU 集合の割り当てと解放ができる。
名前が "_S" で終わるマクロは "_S" なしの同じ名前のマクロと同等である。 これらのマクロは "_S" なしのものと同じ動作をするが、 動的に割り当てられた、 大きさが setsize バイトの CPU 集合に対して操作を行う点が異なる。
CPU_COUNT() と CPU_COUNT_S() は set に含まれる CPU 数を返す。
CPU_EQUAL() と CPU_EQUAL_S() は、 二つの CPU 集合が等しければ 0 以外を返し、 等しくない場合 0 を返す。
CPU_ALLOC() は成功するとポインターを返し、 失敗すると NULL を返す (エラーは malloc(3) と同じである)。
CPU_ALLOC_SIZE() は指定された大きさの CPU 集合を格納するのに必要なバイト数を返す。
CPU_COUNT() は glibc 2.6 で初めて登場した。
CPU_AND(), CPU_OR(), CPU_XOR(), CPU_EQUAL(), CPU_ALLOC(), CPU_ALLOC_SIZE(), CPU_FREE(), CPU_ZERO_S(), CPU_SET_S(), CPU_CLR_S(), CPU_ISSET_S(), CPU_AND_S(), CPU_OR_S(), CPU_XOR_S(), CPU_EQUAL_S() は glibc 2.7 で初めて登場した。
CPU 集合はロングワード単位に割り当てられるビットマスクなので、 動的に割り当てられた CPU 集合の実際の CPU 数は sizeof(unsigned long) の次の倍数に切り上げられることになる。 アプリケーションは、 これらの余分なビットの内容は不定と考えるべきである。
名前は似ているが、 定数 CPU_SETSIZE は cpu_set_t データ型に含まれる CPU 数 (つまり、事実上ビットマスク内のビットカウント) を示すのに対して、 マクロ CPU_*_S() の setsize 引数はバイト単位のサイズである点に注意すること。
「書式」に書かれている引数と返り値のデータ型は、それぞれの場合でどんな型が期待されるかのヒントである。 しかしながら、 これらのインターフェースはマクロとして実装されているため、 このヒントを守らなかった場合に、 コンパイラが必ずしも全ての型エラーを捕捉できるとは限らない。
#define _GNU_SOURCE #include <sched.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <assert.h>
int main(int argc, char *argv[]) {
cpu_set_t *cpusetp;
size_t size;
int num_cpus;
if (argc < 2) {
fprintf(stderr, "Usage: %s <num-cpus>\n", argv[0]);
exit(EXIT_FAILURE);
}
num_cpus = atoi(argv[1]);
cpusetp = CPU_ALLOC(num_cpus);
if (cpusetp == NULL) {
perror("CPU_ALLOC");
exit(EXIT_FAILURE);
}
size = CPU_ALLOC_SIZE(num_cpus);
CPU_ZERO_S(size, cpusetp);
for (int cpu = 0; cpu < num_cpus; cpu += 2)
CPU_SET_S(cpu, size, cpusetp);
printf("CPU_COUNT() of set: %d\n", CPU_COUNT_S(size, cpusetp));
CPU_FREE(cpusetp);
exit(EXIT_SUCCESS); }
[man1]
[man2]
[man3]
[man4]
[man5]
[man6]
[man7]
[man8]
[a]
[b]
[c]
[d]
[e]
[f]
[g]
[h]
[i]
[j]
[k]
[l]
[m]
[n]
[o]
[p]
[q]
[r]
[s]
[t]
[u]
[v]
[w]
[x]
[y]
[z]