|
|
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);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.