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