Annotation of nono/lib/mythread.cpp, revision 1.1.1.4

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
1.1.1.3   root        7: //
1.1       root        8: // pthread の OS ごとに違う部分を吸収する
1.1.1.3   root        9: //
1.1       root       10: 
                     11: #include "mythread.h"
                     12: #include <pthread.h>
                     13: #if defined(HAVE_PTHREAD_NP_H)
                     14: #include <pthread_np.h>
                     15: #endif
                     16: 
1.1.1.4 ! root       17: #if defined(HAVE_PTHREAD_SETAFFINITY_NP)
        !            18: // pthread_setaffinity_np は今のところどの OS でもだいたい同じだが
        !            19: // <pthread_np.h> が必要な関係でこっちに置いておく。
        !            20: int
        !            21: PTHREAD_SETAFFINITY(pthread_t thread, const MICPUSet& m)
        !            22: {
        !            23:        return pthread_setaffinity_np(thread, m.Count(), m.Get());
        !            24: }
        !            25: #endif
        !            26: 
1.1       root       27: // pthread_set{,_}name_np() のプロトタイプは OS によってみんなフリーダムなので
                     28: // (というか _np は Non Portable か Non Posix のことらしい?)、
                     29: // ここで吸収する。
                     30: //
                     31: // MacOSX  は void pthread_setname_np(name)
                     32: // Linux   は int  pthread_setname_np(threadID, name)
                     33: // NetBSD  は int  pthread_setname_np(threadID, name, arg)
                     34: // OpenBSD は void pthread_set_name_np(threadID, name)
                     35: // FreeBSD は void pthread_set_name_np(threadID, name)
                     36: // (2020/06 以降は pthread_setname_np(threadID, name) も追加)
1.1.1.3   root       37: //
                     38: // 戻り値を返す Linux と NetBSD は、いずれも正常なら 0、失敗ならエラーコード
                     39: // を返す、としているので、ここでもそれを返す。
                     40: int
1.1       root       41: PTHREAD_SETNAME(const char *name)
                     42: {
1.1.1.2   root       43: #if defined(__linux__)
                     44:        // Linux (Ubuntu 20.04) の top はスレッド名があればそれだけ表示するらしい。
                     45:        // スレッド名 "Main" がプロセス名なしに表示されても何のことか分からないので
                     46:        // プロセス名を入れておきたい。
                     47:        // 一方 NetBSD の top ではプロセス名とスレッド名は欄が別なので(そして狭い)
                     48:        // ここにプロセス名は入れたくない。ので、Linux の時だけに分離する。
                     49:        // 他の OS はしらん。
1.1.1.3   root       50:        // Linux の setname は '\0' 込みで 16バイト。
                     51:        char buf[16];
1.1.1.2   root       52: 
                     53:        snprintf(buf, sizeof(buf), "nono:%s", name);
                     54:        name = buf;
                     55: #endif
                     56: 
1.1       root       57: #if defined(HAVE_PTHREAD_SETNAME_NP_name)
                     58:        pthread_setname_np(name);
                     59: 
                     60: #elif defined(HAVE_PTHREAD_SETNAME_NP_th_name)
1.1.1.3   root       61: # if defined(__linux__)
                     62:        // Linux には戻り値がある
                     63:        return pthread_setname_np(pthread_self(), name);
                     64: # else
1.1       root       65:        pthread_setname_np(pthread_self(), name);
1.1.1.3   root       66: # endif
1.1       root       67: 
                     68: #elif defined(HAVE_PTHREAD_SETNAME_NP_th_name_arg)
1.1.1.3   root       69: # if defined(__NetBSD__)
                     70:        // NetBSD には戻り値がある
                     71:        return pthread_setname_np(pthread_self(), name, NULL);
                     72: # else
1.1       root       73:        pthread_setname_np(pthread_self(), name, NULL);
1.1.1.3   root       74: # endif
1.1       root       75: 
                     76: #elif defined(HAVE_PTHREAD_SET_NAME_NP_th_name)
                     77:        pthread_set_name_np(pthread_self(), name);
                     78: 
                     79: #else
                     80:        // デバッガとかでスレッドに名前がついてると嬉しいという程度なので、
                     81:        // なければ気にしない。
                     82: #endif
1.1.1.3   root       83: 
                     84:        return 0;
                     85: }
                     86: 
                     87: // pthread_get{,_}name_np() の OS ごとの違いを吸収して、
                     88: // 指定のスレッドの名前を std::string で返す。
                     89: std::string
                     90: PTHREAD_GETNAME(pthread_t thread)
                     91: {
                     92:        char name[32];
                     93: 
                     94:        name[0] = '\0';
                     95: 
                     96: #if defined(HAVE_PTHREAD_GETNAME_NP)
                     97:        pthread_getname_np(thread, name, sizeof(name));
                     98: 
                     99: #elif defined(HAVE_PTHREAD_GET_NAME_NP)
                    100:        pthread_get_name_np(thread, name, sizeof(name));
                    101: 
                    102: #else
                    103:        // なければ気にしない
                    104: #endif
                    105: 
                    106:        return std::string(name);
1.1       root      107: }
1.1.1.4 ! root      108: 
        !           109: 
        !           110: //
        !           111: // cpu{,_}set_t とその関数群の違いを吸収するクラス。
        !           112: //
        !           113: 
        !           114: // NetBSD の cpuset_t は opaque 型なので alloc/free が必要。
        !           115: // Linux には alloc/free もあるが実体を用意して使ってもよさげ(*1)。
        !           116: // FreeBSD は実体を用意しておく方式のみ。
        !           117: // うーんこの。
        !           118: // OpenBSD などこの機能がない OS では気にせず無視する。
        !           119: //
        !           120: //     NetBSD                          Linux                   FreeBSD
        !           121: //     ------                          -----                   -------
        !           122: //     cpuset_t *                      cpu_set_t               cpuset_t
        !           123: //     cpuset_create()         *1                              -
        !           124: //     cpuset_destroy()        *1                              -
        !           125: //     cpuset_zero(s)          CPU_ZERO(&s)    CPU_ZERO(&s)
        !           126: //     cpuset_set(n,s)         CPU_SET(n,&s)   CPU_SET(n,&s)
        !           127: //     cpuset_size(s)          CPU_COUNT(&s)   sizeof(s)
        !           128: //
        !           129: //     HAVE_CPUSET_T=no                                        HAVE_CPUSET_T=yes
        !           130: //     HAVE_CPUSET_T_P=yes                                     HAVE_CPUSET_T_P=yes
        !           131: 
        !           132: #if defined(HAVE_MICPUSET)
        !           133: 
        !           134: // コンストラクタ
        !           135: MICPUSet::MICPUSet()
        !           136: {
        !           137: #if defined(HAVE_CPUSET_CREATE)
        !           138:        // NetBSD の cpuset_t は opaque 型なので実体を持てない。
        !           139:        set = cpuset_create();
        !           140:        cpuset_zero(set);
        !           141: #elif defined(HAVE_CPU_ZERO)
        !           142:        // 実体を持てる。
        !           143:        set = &entity;
        !           144:        CPU_ZERO(set);
        !           145: #endif
        !           146: }
        !           147: 
        !           148: // デストラクタ
        !           149: MICPUSet::~MICPUSet()
        !           150: {
        !           151: #if defined(HAVE_CPUSET_CREATE)
        !           152:        if (set != NULL) {
        !           153:                cpuset_destroy(set);
        !           154:                set = NULL;
        !           155:        }
        !           156: #else
        !           157:        // メンバが実体なので放置でよい。
        !           158: #endif
        !           159: }
        !           160: 
        !           161: // ビットをセットする
        !           162: void
        !           163: MICPUSet::Set(uint n)
        !           164: {
        !           165: #if defined(HAVE_CPUSET_SET)
        !           166:        cpuset_set(n, set);
        !           167: #elif defined(HAVE_CPU_SET)
        !           168:        CPU_SET(n, set);
        !           169: #endif
        !           170: }
        !           171: 
        !           172: // ビットの状態を取得する
        !           173: bool
        !           174: MICPUSet::Get(uint n) const
        !           175: {
        !           176: #if defined(HAVE_CPUSET_ISSET)
        !           177:        return cpuset_isset(n, set);
        !           178: #elif defined(HAVE_CPU_ISSET)
        !           179:        return CPU_ISSET(n, set);
        !           180: #else
        !           181:        return false;
        !           182: #endif
        !           183: }
        !           184: 
        !           185: // サイズを返す
        !           186: size_t
        !           187: MICPUSet::Count() const
        !           188: {
        !           189: #if defined(HAVE_CPUSET_SIZE)
        !           190:        return cpuset_size(set);
        !           191: #elif defined(HAVE_CPU_COUNT)
        !           192:        return (size_t)CPU_COUNT(set);
        !           193: #else
        !           194:        return sizeof(entity);
        !           195: #endif
        !           196: }
        !           197: 
        !           198: #endif // HAVE_MICPUSET

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.