--- nono/lib/mythread.cpp 2026/04/29 17:05:08 1.1.1.3 +++ nono/lib/mythread.cpp 2026/04/29 17:05:26 1.1.1.4 @@ -14,6 +14,16 @@ #include #endif +#if defined(HAVE_PTHREAD_SETAFFINITY_NP) +// pthread_setaffinity_np は今のところどの OS でもだいたい同じだが +// が必要な関係でこっちに置いておく。 +int +PTHREAD_SETAFFINITY(pthread_t thread, const MICPUSet& m) +{ + return pthread_setaffinity_np(thread, m.Count(), m.Get()); +} +#endif + // pthread_set{,_}name_np() のプロトタイプは OS によってみんなフリーダムなので // (というか _np は Non Portable か Non Posix のことらしい?)、 // ここで吸収する。 @@ -90,9 +100,99 @@ PTHREAD_GETNAME(pthread_t thread) pthread_get_name_np(thread, name, sizeof(name)); #else -#error pthread_getname // なければ気にしない #endif return std::string(name); } + + +// +// cpu{,_}set_t とその関数群の違いを吸収するクラス。 +// + +// NetBSD の cpuset_t は opaque 型なので alloc/free が必要。 +// Linux には alloc/free もあるが実体を用意して使ってもよさげ(*1)。 +// FreeBSD は実体を用意しておく方式のみ。 +// うーんこの。 +// OpenBSD などこの機能がない OS では気にせず無視する。 +// +// NetBSD Linux FreeBSD +// ------ ----- ------- +// cpuset_t * cpu_set_t cpuset_t +// cpuset_create() *1 - +// cpuset_destroy() *1 - +// cpuset_zero(s) CPU_ZERO(&s) CPU_ZERO(&s) +// cpuset_set(n,s) CPU_SET(n,&s) CPU_SET(n,&s) +// cpuset_size(s) CPU_COUNT(&s) sizeof(s) +// +// HAVE_CPUSET_T=no HAVE_CPUSET_T=yes +// HAVE_CPUSET_T_P=yes HAVE_CPUSET_T_P=yes + +#if defined(HAVE_MICPUSET) + +// コンストラクタ +MICPUSet::MICPUSet() +{ +#if defined(HAVE_CPUSET_CREATE) + // NetBSD の cpuset_t は opaque 型なので実体を持てない。 + set = cpuset_create(); + cpuset_zero(set); +#elif defined(HAVE_CPU_ZERO) + // 実体を持てる。 + set = &entity; + CPU_ZERO(set); +#endif +} + +// デストラクタ +MICPUSet::~MICPUSet() +{ +#if defined(HAVE_CPUSET_CREATE) + if (set != NULL) { + cpuset_destroy(set); + set = NULL; + } +#else + // メンバが実体なので放置でよい。 +#endif +} + +// ビットをセットする +void +MICPUSet::Set(uint n) +{ +#if defined(HAVE_CPUSET_SET) + cpuset_set(n, set); +#elif defined(HAVE_CPU_SET) + CPU_SET(n, set); +#endif +} + +// ビットの状態を取得する +bool +MICPUSet::Get(uint n) const +{ +#if defined(HAVE_CPUSET_ISSET) + return cpuset_isset(n, set); +#elif defined(HAVE_CPU_ISSET) + return CPU_ISSET(n, set); +#else + return false; +#endif +} + +// サイズを返す +size_t +MICPUSet::Count() const +{ +#if defined(HAVE_CPUSET_SIZE) + return cpuset_size(set); +#elif defined(HAVE_CPU_COUNT) + return (size_t)CPU_COUNT(set); +#else + return sizeof(entity); +#endif +} + +#endif // HAVE_MICPUSET