--- nono/lib/header.h 2026/04/29 17:04:28 1.1 +++ nono/lib/header.h 2026/04/29 17:05:12 1.1.1.16 @@ -1,15 +1,21 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt +// + +// +// 基本ヘッダ // #pragma once #define NONO_MAJOR_VER (0) -#define NONO_MINOR_VER (0) -#define NONO_PATCH_VER (1) +#define NONO_MINOR_VER (4) +#define NONO_PATCH_VER (0) +#define NONO_DATE "2022/06/18" -#include "config.h" +#include "config-nono.h" #include #include #include @@ -18,36 +24,30 @@ #include #include #include +#include #include #include #include #include #include -#include #include -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef uint64_t uint64; -typedef int8_t int8; -typedef int16_t int16; -typedef int32_t int32; -typedef int64_t int64; - -#if defined(HAVE_ENDIAN_H) -#include -#elif defined(HAVE_SYS_ENDIAN_H) -#include -#else -#include "missing_endian.h" -#endif +using uint8 = uint8_t; +using uint16 = uint16_t; +using uint32 = uint32_t; +using uint64 = uint64_t; +using int8 = int8_t; +using int16 = int16_t; +using int32 = int32_t; +using int64 = int64_t; #if defined(HAVE_BSD_BSD_H) #include #endif +#include "myendian.h" + #if !defined(__printflike) #if defined(HAVE___ATTRIBUTE_FORMAT) # define __printflike(a,b) __attribute__((__format__(__printf__, (a), (b)))) @@ -79,15 +79,18 @@ typedef int64_t int64; #endif #endif -#if !defined(__predict_true) +// FreeBSD(12.1) の __predict_true/false は定義がいまいちで使えない。 +// __builtin_expect() があることが分かればどの環境でも自前で定義できるので +// 既存定義は取り消す。 #if defined(HAVE___BUILTIN_EXPECT) +# undef __predict_true +# undef __predict_false # define __predict_true(exp) __builtin_expect((exp) != 0, 1) # define __predict_false(exp) __builtin_expect((exp) != 0, 0) -#else +#elif !defined(__predict_true) # define __predict_true(exp) (exp) # define __predict_false(exp) (exp) #endif -#endif #if !defined(__unused) #if defined(HAVE___ATTRIBUTE_UNUSED) @@ -97,7 +100,9 @@ typedef int64_t int64; #endif #endif -#if defined(HAVE___ATTRIBUTE_FALLTHROUGH) +#if defined(__clang__) +# define FALLTHROUGH [[clang::fallthrough]] +#elif defined(HAVE___ATTRIBUTE_FALLTHROUGH) # define FALLTHROUGH __attribute__((__fallthrough__)) #else # define FALLTHROUGH ((void)0) @@ -109,24 +114,60 @@ typedef int64_t int64; # define NO_SANITIZE(x) #endif +// x86_64 では SSE のために16バイト境界に整列させたいが、ほかの +// アーキテクチャでは alignas(16) がエラーになる場合がある。この場合の +// alignas() は SSE のために必要なので、他アーキテクチャではそもそも +// 指定しなくていい。ということで x86_64 の時に限って指定したい時に使う。 +// うーん、なんだこれ。 +#if defined(__x86_64__) +#define ALIGNAS_IF_X86(n) alignas(n) +#else +#define ALIGNAS_IF_X86(n) /**/ +#endif + +// 64ビット数と2つの32ビット数を扱う共用体。 +// 構造はまったく同じだが名前だけ場所に合わせてつけたい。 +#if BYTE_ORDER == LITTLE_ENDIAN +#define DEF_UNION64(NAME, Q, H, L) \ + union NAME { \ + uint64 Q; \ + struct { uint32 L, H; }; \ + } +#else +#define DEF_UNION64(NAME, Q, H, L) \ + union NAME { \ + uint64 Q; \ + struct { uint32 H, L; }; \ + } +#endif + +DEF_UNION64(union64, q, h, l); + #ifndef countof #define countof(x) (sizeof(x) / sizeof(x[0])) #endif -// NetBSD は pthread_setname_np(threadID, name, arg) だが -// Linux は pthread_setname_np(threadID, name) で -// MacOSX は pthread_setname_np(name) だったりする。 -// 今の所 NetBSD でも arg はいらないので(というか NetBSD の name, arg の -// デザインはおかしい)、引数1つバージョンに揃えることにする。 -#if HAVE_PTHREAD_SETNAME_NP == 3 -#define pthread_setname_np(name) pthread_setname_np(pthread_self(), name, NULL) -#elif HAVE_PTHREAD_SETNAME_NP == 2 -#define pthread_setname_np(name) pthread_setname_np(pthread_self(), name) +#ifndef roundup +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +#ifndef rounddown +#define rounddown(x, y) (((x)/(y))*(y)) #endif -// 便利マクロ -#define kevent_set(k, e, n) kevent((k), (e), (n), NULL, 0, NULL) -#define kevent_poll(k, e, n, t) kevent((k), NULL, 0, (e), (n), (t)) +// メッセージ付きの assert。 +// 本当は後ろに足したいのだがそれは無理なので、せめてそれっぽく1行にしてみる。 +#if !defined(NDEBUG) +#define assertmsg(expr, ...) do { \ + if (__predict_false(!(expr))) { \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, ": "); \ + assert(expr); \ + } \ +} while (0) +#else +#define assertmsg(expr, ...) +#endif // atomic_compare_exchange_strong() の短縮マクロ。 // ライブラリ実装は第2引数の expected が値ではなくポインタなので一旦代入操作を @@ -146,7 +187,12 @@ typedef int64_t int64; atomic_compare_exchange_strong((varp), &expected, (uint32)(newval)); \ }) -// ログ +// パニック (PC を表示しない) #define PANIC(...) panic(__PRETTY_FUNCTION__, __VA_ARGS__) [[noreturn]] extern void panic(const char *funcname, const char *fmt, ...) __printflike(2, 3); + +// VM 用パニック (PC を表示する) +#define VMPANIC(...) vmpanic(__PRETTY_FUNCTION__, __VA_ARGS__) +[[noreturn]] extern void vmpanic(const char *funcname, const char *fmt, ...) + __printflike(2, 3);