Annotation of nono/lib/header.h, revision 1.1.1.4

1.1       root        1: //
                      2: // nono
1.1.1.4 ! root        3: // Copyright (C) 2020 nono project
        !             4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #pragma once
                      8: 
                      9: #define NONO_MAJOR_VER (0)
1.1.1.4 ! root       10: #define NONO_MINOR_VER (1)
        !            11: #define NONO_PATCH_VER (0)
        !            12: #define NONO_DATE              "2020/07/19"
1.1       root       13: 
1.1.1.3   root       14: #include "config-nono.h"
1.1       root       15: #include <cassert>
                     16: #include <cctype>
                     17: #include <cerrno>
                     18: #include <cstdarg>
                     19: #include <cstdio>
                     20: #include <cstdint>
                     21: #include <cstdlib>
                     22: #include <cstring>
1.1.1.3   root       23: #include <memory>
1.1       root       24: #include <string>
                     25: 
                     26: #include <err.h>
                     27: #include <inttypes.h>
                     28: #include <unistd.h>
                     29: #include <sys/cdefs.h>
                     30: #include <sys/time.h>
                     31: #include <sys/types.h>
                     32: 
1.1.1.4 ! root       33: using uint8            = uint8_t;
        !            34: using uint16   = uint16_t;
        !            35: using uint32   = uint32_t;
        !            36: using uint64   = uint64_t;
        !            37: using int8             = int8_t;
        !            38: using int16            = int16_t;
        !            39: using int32            = int32_t;
        !            40: using int64            = int64_t;
1.1       root       41: 
                     42: #if defined(HAVE_ENDIAN_H)
                     43: #include <endian.h>
                     44: #elif defined(HAVE_SYS_ENDIAN_H)
                     45: #include <sys/endian.h>
                     46: #else
                     47: #include "missing_endian.h"
                     48: #endif
                     49: 
                     50: #if defined(HAVE_BSD_BSD_H)
                     51: #include <bsd/bsd.h>
                     52: #endif
                     53: 
                     54: #if !defined(__printflike)
                     55: #if defined(HAVE___ATTRIBUTE_FORMAT)
                     56: # define __printflike(a,b)     __attribute__((__format__(__printf__, (a), (b))))
                     57: #else
                     58: # define __printflike(a,b)
                     59: #endif
                     60: #endif
                     61: 
                     62: #if !defined(__unreachable)
                     63: #if defined(HAVE___BUILTIN_UNREACHABLE)
                     64: # define __unreachable()       __builtin_unreachable()
                     65: #else
                     66: # define __unreachable()       ((void)0)
                     67: #endif
                     68: #endif
                     69: 
                     70: // gcc でコンパイラに最適化の条件を与える。
                     71: #if defined(HAVE___BUILTIN_ASSUME)
                     72: #define __assume(cond) __builtin_assume(cond)
                     73: #else
                     74: #define __assume(cond) if (!(cond)) __unreachable()
                     75: #endif
                     76: 
                     77: #if !defined(__packed)
                     78: #if defined(HAVE___ATTRIBUTE_PACKED)
                     79: # define __packed      __attribute__((__packed__))
                     80: #else
                     81: # error not tested.
                     82: #endif
                     83: #endif
                     84: 
                     85: #if !defined(__predict_true)
                     86: #if defined(HAVE___BUILTIN_EXPECT)
                     87: # define __predict_true(exp)   __builtin_expect((exp) != 0, 1)
                     88: # define __predict_false(exp)  __builtin_expect((exp) != 0, 0)
                     89: #else
                     90: # define __predict_true(exp)   (exp)
                     91: # define __predict_false(exp)  (exp)
                     92: #endif
                     93: #endif
                     94: 
                     95: #if !defined(__unused)
                     96: #if defined(HAVE___ATTRIBUTE_UNUSED)
                     97: # define __unused __attribute__((__unused__))
                     98: #else
                     99: # define __unused
                    100: #endif
                    101: #endif
                    102: 
1.1.1.4 ! root      103: #if defined(__clang__)
        !           104: # define FALLTHROUGH   [[clang::fallthrough]]
        !           105: #elif defined(HAVE___ATTRIBUTE_FALLTHROUGH)
1.1       root      106: # define FALLTHROUGH   __attribute__((__fallthrough__))
                    107: #else
                    108: # define FALLTHROUGH   ((void)0)
                    109: #endif
                    110: 
                    111: #if defined(HAVE___ATTRIBUTE_NO_SANITIZE)
                    112: # define NO_SANITIZE(x)        __attribute__((no_sanitize(x)))
                    113: #else
                    114: # define NO_SANITIZE(x)
                    115: #endif
                    116: 
1.1.1.3   root      117: // 64ビット数と2つの32ビット数を扱う共用体。
                    118: // 構造はまったく同じだが名前だけ場所に合わせてつけたい。
                    119: #if _BYTE_ORDER == _LITTLE_ENDIAN
                    120: #define DEF_UNION64(NAME, Q, H, L)     \
                    121:        union NAME {    \
                    122:                uint64 Q;       \
                    123:                struct { uint32 L, H; };        \
                    124:        }
                    125: #else
                    126: #define DEF_UNION64(NAME, Q, H, L)     \
                    127:        union NAME {    \
                    128:                uint64 Q;       \
                    129:                struct { uint32 H, L; };        \
                    130:        }
                    131: #endif
                    132: 
                    133: DEF_UNION64(union64, q, h, l);
                    134: 
1.1       root      135: #ifndef countof
                    136: #define countof(x)     (sizeof(x) / sizeof(x[0]))
                    137: #endif
                    138: 
1.1.1.3   root      139: // メッセージ付きの assert。
                    140: #define assertmsg(expr, fmt, ...)      do {    \
                    141:        if (__predict_false(!(expr))) { \
                    142:                fprintf(stderr, fmt "\n", __VA_ARGS__); \
                    143:                assert(expr);   \
                    144:        }       \
                    145: } while (0)
                    146: 
1.1       root      147: // 便利マクロ
                    148: #define kevent_set(k, e, n)            kevent((k), (e), (n), NULL, 0, NULL)
                    149: #define kevent_poll(k, e, n, t)        kevent((k), NULL, 0, (e), (n), (t))
                    150: 
                    151: // atomic_compare_exchange_strong() の短縮マクロ。
                    152: // ライブラリ実装は第2引数の expected が値ではなくポインタなので一旦代入操作を
                    153: // 行わないといけないのと、第3引数の newval は型が uint8 だと int 即値が書けず
                    154: // (int8) でキャストしないといけない。
                    155: // その上 atomic_compare_exchange_strong() が長い、と、いろいろ微妙なので、
                    156: // その辺を短くするマクロを用意する。ただしこれでは expected 変数の型が
                    157: // 自動判別できないので、_8 と _32 を用意するところは妥協。
                    158: // (static) inline 関数にすることも出来るけどそうするとここで <atomic> ヘッダ
                    159: // を読み込まなければならなくなるため、マクロで実現する。
                    160: #define atomic_cas_8(varp, expval, newval)     ({      \
                    161:        uint8 expected = (expval);      \
                    162:        atomic_compare_exchange_strong((varp), &expected, (uint8)(newval));     \
                    163: })
                    164: #define atomic_cas_32(varp, expval, newval)    ({      \
                    165:        uint32 expected = (expval);     \
                    166:        atomic_compare_exchange_strong((varp), &expected, (uint32)(newval));    \
                    167: })
                    168: 
                    169: // ログ
                    170: #define PANIC(...)     panic(__PRETTY_FUNCTION__, __VA_ARGS__)
                    171: [[noreturn]] extern void panic(const char *funcname, const char *fmt, ...)
                    172:        __printflike(2, 3);

unix.superglobalmegacorp.com

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