|
|
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.2 ! root 10: #define NONO_PATCH_VER (2)
1.1 root 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.