Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       CPU_SET,  CPU_CLR,  CPU_ISSET,  CPU_ZERO,  CPU_COUNT, CPU_AND, CPU_OR, CPU_XOR, CPU_EQUAL,
       CPU_ALLOC,  CPU_ALLOC_SIZE,  CPU_FREE,  CPU_SET_S,  CPU_CLR_S,  CPU_ISSET_S,   CPU_ZERO_S,
       CPU_COUNT_S, CPU_AND_S, CPU_OR_S, CPU_XOR_S, CPU_EQUAL_S - CPU 集合を操作するためのマクロ

書式

       #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 集合は sched_setaffinity(2) や同様の
       インターフェースで使用されている。

       cpu_set_t データ型はビットマスクとして実装されている。 しかし、 データ構造体はその実装を意
       識せずに扱うべきであり、 CPU 集合のすべての操作は、 このページで説明されているマクロを通し
       て行うべきである。

       以下のマクロが CPU 集合 set を操作するために提供されている。

       CPU_ZERO()
              set をクリアする。 集合には何も CPU が含まれない状態となる。

       CPU_SET()
              setcpu を追加する。

       CPU_CLR()
              set から cpu を削除する。

       CPU_ISSET()
              CPU cpuset のメンバーであるかを検査する。

       CPU_COUNT()
              set に含まれる CPU 数を返す。

       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_AND()
              集合 srcset1srcset2 の積集合を destset に格納する (元の集合のいずれかが destset
              として使用される場合もある)。

       CPU_OR()
              集合 srcset1srcset2 の和集合を destset に格納する (元の集合のいずれかが destset
              として使用される場合もある)。

       CPU_XOR()
              集合  srcset1srcset2 の XOR を destset に格納する (元の集合のいずれかが destset
              として使用される場合もある)。 XOR とは、 srcset1srcset2  のいずれかに含まれる
              が、両方には含まれない集合のことである。

       CPU_EQUAL()
              二つの CPU 集合が全く同じ CPU を含んでいるかを検査する。

   動的に大きさが決まる CPU 集合
       いくつかのアプリケーションでは   CPU   集合の大きさを動的に決める能力   (例えば、   標準の
       cpu_set_t  データ型で定義されたよりも大きい集合を割り当てるなど)  が必要となることがあるた
       め、 現在 glibc はこれに対応するためにいくつかのマクロを提供している。

       以下のマクロを使うと CPU 集合の割り当てと解放ができる。

       CPU_ALLOC()
              0  から num_cpus-1 までの範囲の CPU を保持するのに十分な大きさの CPU 集合を割り当て
              る。

       CPU_ALLOC_SIZE()
              0 から num_cpus-1 までの範囲の CPU を保持するのに必要な CPU  集合の大きさをバイト数
              で返す。  このマクロが返す値は、 後述の CPU_*_S() マクロの setsize 引数として使用で
              きる。

       CPU_FREE()
              以前に CPU_ALLOC() で割り当てられた CPU 集合を解放する。

       名前が "_S" で終わるマクロは  "_S"  なしの同じ名前のマクロと同等である。  これらのマクロは
       "_S"  なしのものと同じ動作をするが、  動的に割り当てられた、 大きさが setsize バイトの CPU
       集合に対して操作を行う点が異なる。

返り値

       CPU_ISSET() と CPU_ISSET_S() は、 cpuset に含まれていれば 0 以外を返し、含まれない場合
       0 を返す。

       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_ZERO(), CPU_SET(), CPU_CLR(), CPU_ISSET() は glibc 2.3.3 で追加された。

       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 で初めて登場した。

準拠

       これらのインターフェースは Linux 固有である。

注意

       CPU 集合を複製するには、 memcpy(3) を使用する。

       CPU 集合はロングワード単位に割り当てられるビットマスクなので、 動的に割り当てられた CPU 集
       合の実際の CPU 数は sizeof(unsigned  long)  の次の倍数に切り上げられることになる。  アプリ
       ケーションは、 これらの余分なビットの内容は不定と考えるべきである。

       名前は似ているが、 定数 CPU_SETSIZEcpu_set_t データ型に含まれる CPU 数 (つまり、事実上
       ビットマスク内のビットカウント) を示すのに対して、 マクロ CPU_*_S() の setsize  引数はバイ
       ト単位のサイズである点に注意すること。

       「書式」に書かれている引数と返り値のデータ型は、それぞれの場合でどんな型が期待されるかのヒ
       ントである。 しかしながら、 これらのインターフェースはマクロとして実装されているため、  こ
       のヒントを守らなかった場合に、    コンパイラが必ずしも全ての型エラーを捕捉できるとは限らな
       い。

バグ

       glibc 2.8 以前の 32 ビットプラットフォームでは、 CPU_ALLOC()  は必要な空間の割り当てを二度
       行い、  CPU_ALLOC_SIZE() は本来あるべき値の二倍の値を返す。 このバグはプログラムの動作には
       影響を与えないはずだが、 無駄にメモリーを消費し、 動的に割り当てられた CPU  集合に対して操
       作を行うマクロの動作の効率が下がる結果となる。 これらのバグは glibc 2.9 で修正された。

       以下のプログラムは、動的に割り当てた  CPU 集合に対していくつかのマクロを使用する例を示して
       いる。

       #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);
       }

関連項目

       sched_setaffinity(2), pthread_attr_setaffinity_np(3), pthread_setaffinity_np(3), cpuset(7)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの
       説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。