|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2017 [email protected] ! 4: // ! 5: ! 6: #pragma once ! 7: ! 8: #define NONO_MAJOR_VER (0) ! 9: #define NONO_MINOR_VER (0) ! 10: #define NONO_PATCH_VER (1) ! 11: ! 12: #include "config.h" ! 13: #include <cassert> ! 14: #include <cctype> ! 15: #include <cerrno> ! 16: #include <cstdarg> ! 17: #include <cstdio> ! 18: #include <cstdint> ! 19: #include <cstdlib> ! 20: #include <cstring> ! 21: #include <string> ! 22: ! 23: #include <err.h> ! 24: #include <inttypes.h> ! 25: #include <unistd.h> ! 26: #include <sys/cdefs.h> ! 27: #include <sys/time.h> ! 28: #include <sys/types.h> ! 29: ! 30: typedef uint8_t uint8; ! 31: typedef uint16_t uint16; ! 32: typedef uint32_t uint32; ! 33: typedef uint64_t uint64; ! 34: typedef int8_t int8; ! 35: typedef int16_t int16; ! 36: typedef int32_t int32; ! 37: typedef int64_t int64; ! 38: ! 39: #if defined(HAVE_ENDIAN_H) ! 40: #include <endian.h> ! 41: #elif defined(HAVE_SYS_ENDIAN_H) ! 42: #include <sys/endian.h> ! 43: #else ! 44: #include "missing_endian.h" ! 45: #endif ! 46: ! 47: #if defined(HAVE_BSD_BSD_H) ! 48: #include <bsd/bsd.h> ! 49: #endif ! 50: ! 51: #if !defined(__printflike) ! 52: #if defined(HAVE___ATTRIBUTE_FORMAT) ! 53: # define __printflike(a,b) __attribute__((__format__(__printf__, (a), (b)))) ! 54: #else ! 55: # define __printflike(a,b) ! 56: #endif ! 57: #endif ! 58: ! 59: #if !defined(__unreachable) ! 60: #if defined(HAVE___BUILTIN_UNREACHABLE) ! 61: # define __unreachable() __builtin_unreachable() ! 62: #else ! 63: # define __unreachable() ((void)0) ! 64: #endif ! 65: #endif ! 66: ! 67: // gcc でコンパイラに最適化の条件を与える。 ! 68: #if defined(HAVE___BUILTIN_ASSUME) ! 69: #define __assume(cond) __builtin_assume(cond) ! 70: #else ! 71: #define __assume(cond) if (!(cond)) __unreachable() ! 72: #endif ! 73: ! 74: #if !defined(__packed) ! 75: #if defined(HAVE___ATTRIBUTE_PACKED) ! 76: # define __packed __attribute__((__packed__)) ! 77: #else ! 78: # error not tested. ! 79: #endif ! 80: #endif ! 81: ! 82: #if !defined(__predict_true) ! 83: #if defined(HAVE___BUILTIN_EXPECT) ! 84: # define __predict_true(exp) __builtin_expect((exp) != 0, 1) ! 85: # define __predict_false(exp) __builtin_expect((exp) != 0, 0) ! 86: #else ! 87: # define __predict_true(exp) (exp) ! 88: # define __predict_false(exp) (exp) ! 89: #endif ! 90: #endif ! 91: ! 92: #if !defined(__unused) ! 93: #if defined(HAVE___ATTRIBUTE_UNUSED) ! 94: # define __unused __attribute__((__unused__)) ! 95: #else ! 96: # define __unused ! 97: #endif ! 98: #endif ! 99: ! 100: #if defined(HAVE___ATTRIBUTE_FALLTHROUGH) ! 101: # define FALLTHROUGH __attribute__((__fallthrough__)) ! 102: #else ! 103: # define FALLTHROUGH ((void)0) ! 104: #endif ! 105: ! 106: #if defined(HAVE___ATTRIBUTE_NO_SANITIZE) ! 107: # define NO_SANITIZE(x) __attribute__((no_sanitize(x))) ! 108: #else ! 109: # define NO_SANITIZE(x) ! 110: #endif ! 111: ! 112: #ifndef countof ! 113: #define countof(x) (sizeof(x) / sizeof(x[0])) ! 114: #endif ! 115: ! 116: // NetBSD は pthread_setname_np(threadID, name, arg) だが ! 117: // Linux は pthread_setname_np(threadID, name) で ! 118: // MacOSX は pthread_setname_np(name) だったりする。 ! 119: // 今の所 NetBSD でも arg はいらないので(というか NetBSD の name, arg の ! 120: // デザインはおかしい)、引数1つバージョンに揃えることにする。 ! 121: #if HAVE_PTHREAD_SETNAME_NP == 3 ! 122: #define pthread_setname_np(name) pthread_setname_np(pthread_self(), name, NULL) ! 123: #elif HAVE_PTHREAD_SETNAME_NP == 2 ! 124: #define pthread_setname_np(name) pthread_setname_np(pthread_self(), name) ! 125: #endif ! 126: ! 127: // 便利マクロ ! 128: #define kevent_set(k, e, n) kevent((k), (e), (n), NULL, 0, NULL) ! 129: #define kevent_poll(k, e, n, t) kevent((k), NULL, 0, (e), (n), (t)) ! 130: ! 131: // atomic_compare_exchange_strong() の短縮マクロ。 ! 132: // ライブラリ実装は第2引数の expected が値ではなくポインタなので一旦代入操作を ! 133: // 行わないといけないのと、第3引数の newval は型が uint8 だと int 即値が書けず ! 134: // (int8) でキャストしないといけない。 ! 135: // その上 atomic_compare_exchange_strong() が長い、と、いろいろ微妙なので、 ! 136: // その辺を短くするマクロを用意する。ただしこれでは expected 変数の型が ! 137: // 自動判別できないので、_8 と _32 を用意するところは妥協。 ! 138: // (static) inline 関数にすることも出来るけどそうするとここで <atomic> ヘッダ ! 139: // を読み込まなければならなくなるため、マクロで実現する。 ! 140: #define atomic_cas_8(varp, expval, newval) ({ \ ! 141: uint8 expected = (expval); \ ! 142: atomic_compare_exchange_strong((varp), &expected, (uint8)(newval)); \ ! 143: }) ! 144: #define atomic_cas_32(varp, expval, newval) ({ \ ! 145: uint32 expected = (expval); \ ! 146: atomic_compare_exchange_strong((varp), &expected, (uint32)(newval)); \ ! 147: }) ! 148: ! 149: // ログ ! 150: #define PANIC(...) panic(__PRETTY_FUNCTION__, __VA_ARGS__) ! 151: [[noreturn]] extern void panic(const char *funcname, const char *fmt, ...) ! 152: __printflike(2, 3);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.