diff --git a/brlib b/brlib index a48ebf9..180839c 160000 --- a/brlib +++ b/brlib @@ -1 +1 @@ -Subproject commit a48ebf9099de55fad51dbb98f467d113450276d4 +Subproject commit 180839c9602058a79ec576f47518ddc5ef856989 diff --git a/src/alloc.c b/src/alloc.c index aa2c82b..bb90e3d 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -13,39 +13,162 @@ #include #include +#include #include +#include +#include #include "chessdefs.h" #include "alloc.h" -/* force BUG_ON, to get a program abort for failed malloc/free +/* values for linux + * PAGE_SIZE can be obtained with getpagesize(2), but unfortunately nothing for + * HUGE_PAGE_SIZE (except looking in /proc/meminfo or such). */ -#pragma push_macro("BUG_ON") -#undef BUG_ON -#define BUG_ON 1 -#include +#define PAGE_SIZE (4 * 1024) /* 4 Kb */ +#define HUGE_PAGE_SIZE (2 * 1024 * 1024) /* 2 Mb */ -void *safe_alloc(size_t size) +/** + * alloc() - allocate memory. + * @size: size to allocate + * + * Allocate memory on the heap. + * + * @return: memory address if success, NULL otherwise. + */ +void *alloc(size_t size) { - void *mem = malloc(size); - bug_on(mem == NULL); + return malloc(size); +} + +/** + * alloc_aligned() - allocate aligned memory. + * @align: alignment, in bytes + * @size: size to allocate + * + * Allocate aligned memory on the heap. @align must be a power of 2 and + * a multiple of sizeof(void *). See aligned_alloc(3) for details. + * + * @return: memory address if success, NULL otherwise. + */ +void *alloc_aligned(size_t align, size_t size) +{ + bug_on(!size || !align || + align & (align - 1) || align % sizeof (void *)); + return aligned_alloc(align, size); +} + +/** + * alloc_page_aligned() - allocate page-aligned memory. + * @size: size to allocate + * + * Allocate page-aligned memory on the heap. + * + * @return: memory address if success, NULL otherwise. + */ +void *alloc_aligned_page(size_t size) +{ + /* round size (up) to alignment */ + //size_t rounded = (size + PAGE_SIZE - 1) & -PAGE_SIZE; + void *mem = alloc_aligned(PAGE_SIZE, size); return mem; } -void *safe_alloc_page_aligned(size_t size) +/** + * alloc_huge_page_aligned() - allocate huge-page-aligned memory. + * @size: size to allocate + * + * Allocate page-aligned memory on the heap. + * + * @return: memory address if success, NULL otherwise. + */ +void *alloc_aligned_hugepage(size_t size) +{ + /* round size (up) to alignment */ + size_t rounded = (size + PAGE_SIZE - 1) & -PAGE_SIZE; + void *mem = alloc_aligned(PAGE_SIZE, rounded); + printf("size=%zu rounded=%zu\n", size, rounded); + //void *mem = aligned_alloc(HUGE_PAGE_SIZE, size); + if (mem) { + if (madvise(mem, rounded, MADV_HUGEPAGE | MADV_RANDOM)) + perror("madvise"); + } + + return mem; +} + +/** + * safe_alloc() - allocate memory or fail. + * @size: size to allocate + * + * Allocate memory on the heap. This function does not return if allocation + * fails. + * + * @return: memory address (if success only). + */ +void *safe_alloc(size_t size) { void *mem = malloc(size); - bug_on(mem == NULL); + bug_on_always(mem == NULL); + return mem; +} + +/** + * safe_alloc_aligned() - allocate aligned memory or fail. + * @align: alignment. + * @size: size to allocate + * + * Allocate aligned memory on the heap. + * This function does not return if allocation fails. See alloc_aligned() + * for more details. + * + * @return: memory address (if success only). + */ +void *safe_alloc_aligned(size_t align, size_t size) +{ + void *mem = alloc_aligned(align, size); + bug_on_always(mem == NULL); + return mem; +} + +/** + * safe_alloc_aligned_page() - allocate page-aligned memory or fail. + * @size: size to allocate + * + * Allocate memory on the heap. This function does not return if allocation + * fails. See alloc_aligned() for more details. + * + * @return: memory address (if success only). + */ +void *safe_alloc_aligned_page(size_t size) +{ + void *mem = alloc_aligned_page(size); + bug_on_always(mem == NULL); + return mem; +} + +/** + * safe_alloc_aligned_hugepage() - allocate huge page aligned memory or fail. + * @size: size to allocate + * + * Allocate memory on the heap. This function does not return if allocation + * fails. See alloc_aligned() for more details. + * + * @return: memory address (if success only). + */ +void *safe_alloc_aligned_hugepage(size_t size) +{ + /* round size (up) to alignment */ + //size_t rounded = (size + HUGE_PAGE_SIZE - 1) & -HUGE_PAGE_SIZE; + //void *mem = aligned_alloc(rounded, HUGE_PAGE_SIZE); + void *mem = alloc_aligned_hugepage(size); + bug_on_always(mem == NULL); return mem; } void safe_free(void *ptr) { - bug_on(ptr == NULL); + bug_on_always(ptr == NULL); free(ptr); } - -/* restore BUG_ON - */ -#pragma pop_macro("BUG_ON") diff --git a/src/alloc.h b/src/alloc.h index 4054813..96bfe26 100644 --- a/src/alloc.h +++ b/src/alloc.h @@ -11,11 +11,20 @@ * */ -#include -#include +#ifndef _ALLOC_H +#define _ALLOC_H #include "chessdefs.h" +void *alloc(size_t size); +void *alloc_aligned(size_t align, size_t size); +void *alloc_aligned_page(size_t size); +void *alloc_aligned_hugepage(size_t size); + void *safe_alloc(size_t size); -void *safe_alloc_page_aligned(size_t size); +void *safe_alloc_aligned(size_t align, size_t size); +void *safe_alloc_aligned_page(size_t size); +void *safe_alloc_aligned_hugepage(size_t size); void safe_free(void *ptr); + +#endif /* _ALLOC_H */ diff --git a/src/hash.c b/src/hash.c index 3b0bdd2..b33172b 100644 --- a/src/hash.c +++ b/src/hash.c @@ -16,6 +16,7 @@ #include #include +#include #include "chessdefs.h" #include "alloc.h" @@ -101,13 +102,6 @@ hkey_t zobrist_calc(pos_t *pos) */ #ifdef ZOBRIST_VERIFY -#pragma push_macro("BUG_ON") /* force BUG_ON and WARN_ON */ -#pragma push_macro("WARN_ON") -#undef BUG_ON -#define BUG_ON -#undef WARN_ON -#define WARN_ON - bool zobrist_verify(pos_t *pos) { hkey_t diff, key = zobrist_calc(pos); @@ -147,12 +141,10 @@ bool zobrist_verify(pos_t *pos) } warn(true, "zobrist diff %lx is unknown\n", diff); end: - bug_on(false); + bug_on_always(false); /* not reached */ return true; } -#pragma pop_macro("WARN_ON") -#pragma pop_macro("BUG_ON") #endif @@ -211,7 +203,7 @@ int tt_create(s32 sizemb) hash_tt.mask = -1ull >> (64 - nbits); - hash_tt.keys = safe_alloc(hash_tt.bytes); + hash_tt.keys = safe_alloc_aligned_hugepage(hash_tt.bytes); //printf("bits=%2d size=%'15lu/%'6d Mb/%'14lu buckets ", // hash_tt.nbits, hash_tt.bytes, hash_tt.mb, hash_tt.nbuckets); diff --git a/src/hash.h b/src/hash.h index 13011f1..db56fc6 100644 --- a/src/hash.h +++ b/src/hash.h @@ -22,7 +22,7 @@ #define ENTRIES_PER_BUCKET 4 /* buckets per hash table entry */ -#define HASH_SIZE_DEFAULT 32 /* default: 32Mb */ +#define HASH_SIZE_DEFAULT 16 /* default: 16Mb */ #define HASH_SIZE_MIN 1 #define HASH_SIZE_MAX 32768 /* 32Gb */ diff --git a/src/position.c b/src/position.c index 4736b07..c5d53fd 100644 --- a/src/position.c +++ b/src/position.c @@ -20,6 +20,7 @@ #include #include +#include #include "chessdefs.h" #include "position.h" @@ -362,33 +363,24 @@ bitboard_t pos_king_blockers(const pos_t *pos, const color_t color, const bitboa bool pos_ok(pos_t *pos, const bool strict) { int n, count = 0, bbcount = 0, error = 0; - color_t __unused us = pos->turn, __unused them = OPPONENT(us); - - /* force BUG_ON and WARN_ON */ -# pragma push_macro("BUG_ON") -# pragma push_macro("WARN_ON") -# undef BUG_ON -# define BUG_ON -# undef WARN_ON -# define WARN_ON -# include + color_t us = pos->turn, __unused them = OPPONENT(us); /* pawns on 1st ot 8th rank */ - error += warn_on((pos->bb[WHITE][PAWN] | pos->bb[BLACK][PAWN]) & - (RANK_1bb | RANK_8bb)); + error += warn_on_or_eval((pos->bb[WHITE][PAWN] | pos->bb[BLACK][PAWN]) & + (RANK_1bb | RANK_8bb)); for (color_t color = WHITE; color <= BLACK; ++color) { /* pawn count */ n = popcount64(pos->bb[color][PAWN]); - error += warn_on(n > 8); + error += warn_on_or_eval(n > 8); /* king count */ n = popcount64(pos->bb[color][KING]); - error += warn_on(n != 1); + error += warn_on_or_eval(n != 1); /* king mismatch with board */ - error += warn_on(PIECE(pos->board[pos->king[color]]) != KING); + error += warn_on_or_eval(PIECE(pos->board[pos->king[color]]) != KING); /* pieces count */ n = popcount64(pos->bb[color][ALL_PIECES]); - error += warn_on(n == 0 || n > 16); + error += warn_on_or_eval(n == 0 || n > 16); bbcount += n; } for (square_t sq = 0; sq < 64; ++sq) { @@ -399,27 +391,24 @@ bool pos_ok(pos_t *pos, const bool strict) color_t c = COLOR(piece); piece_type_t p = PIECE(piece); match = pos->bb[c][p] & BIT(sq); - error += warn_on(!match); + error += warn_on_or_eval(!match); count++; } /* occupied board is different from bitboards */ - error += warn_on(count != bbcount); + error += warn_on_or_eval(count != bbcount); /* is opponent already in check ? */ - error += warn_on(pos_checkers(pos, them)); + error += warn_on_or_eval(pos_checkers(pos, them)); /* is color to play in check more than twice ? */ - error += warn_on(popcount64(pos_checkers(pos, us)) > 2); + error += warn_on_or_eval(popcount64(pos_checkers(pos, us)) > 2); /* kings distance is less than 2 */ - error += warn_on(sq_dist(pos->king[WHITE], pos->king[BLACK]) < 2); + error += warn_on_or_eval(sq_dist(pos->king[WHITE], pos->king[BLACK]) < 2); /* e.p. and castling rights check */ error += fen_ok(pos, false); if (strict) { - bug_on(error); - /* not reached */ + bug_on_always(error); } return error? false: true; -# pragma pop_macro("WARN_ON") -# pragma pop_macro("BUG_ON") } /**