update bug_on (brlib + hash.c + position.h), new alloc.[ch]

This commit is contained in:
2024-07-15 08:21:56 +02:00
parent ca76b28b00
commit 30ac647fe5
6 changed files with 169 additions and 56 deletions

2
brlib

Submodule brlib updated: a48ebf9099...180839c960

View File

@@ -13,39 +13,162 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/mman.h>
#include <brlib.h> #include <brlib.h>
#include <bitops.h>
#include <bug.h>
#include "chessdefs.h" #include "chessdefs.h"
#include "alloc.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") #define PAGE_SIZE (4 * 1024) /* 4 Kb */
#undef BUG_ON #define HUGE_PAGE_SIZE (2 * 1024 * 1024) /* 2 Mb */
#define BUG_ON 1
#include <bug.h>
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); return malloc(size);
bug_on(mem == NULL); }
/**
* 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; 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); 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; return mem;
} }
void safe_free(void *ptr) void safe_free(void *ptr)
{ {
bug_on(ptr == NULL); bug_on_always(ptr == NULL);
free(ptr); free(ptr);
} }
/* restore BUG_ON
*/
#pragma pop_macro("BUG_ON")

View File

@@ -11,11 +11,20 @@
* *
*/ */
#include <stdio.h> #ifndef _ALLOC_H
#include <stdlib.h> #define _ALLOC_H
#include "chessdefs.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(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); void safe_free(void *ptr);
#endif /* _ALLOC_H */

View File

@@ -16,6 +16,7 @@
#include <brlib.h> #include <brlib.h>
#include <bitops.h> #include <bitops.h>
#include <bug.h>
#include "chessdefs.h" #include "chessdefs.h"
#include "alloc.h" #include "alloc.h"
@@ -101,13 +102,6 @@ hkey_t zobrist_calc(pos_t *pos)
*/ */
#ifdef ZOBRIST_VERIFY #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) bool zobrist_verify(pos_t *pos)
{ {
hkey_t diff, key = zobrist_calc(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); warn(true, "zobrist diff %lx is unknown\n", diff);
end: end:
bug_on(false); bug_on_always(false);
/* not reached */ /* not reached */
return true; return true;
} }
#pragma pop_macro("WARN_ON")
#pragma pop_macro("BUG_ON")
#endif #endif
@@ -211,7 +203,7 @@ int tt_create(s32 sizemb)
hash_tt.mask = -1ull >> (64 - nbits); 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 ", //printf("bits=%2d size=%'15lu/%'6d Mb/%'14lu buckets ",
// hash_tt.nbits, hash_tt.bytes, hash_tt.mb, hash_tt.nbuckets); // hash_tt.nbits, hash_tt.bytes, hash_tt.mb, hash_tt.nbuckets);

View File

@@ -22,7 +22,7 @@
#define ENTRIES_PER_BUCKET 4 /* buckets per hash table entry */ #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_MIN 1
#define HASH_SIZE_MAX 32768 /* 32Gb */ #define HASH_SIZE_MAX 32768 /* 32Gb */

View File

@@ -20,6 +20,7 @@
#include <brlib.h> #include <brlib.h>
#include <bitops.h> #include <bitops.h>
#include <bug.h>
#include "chessdefs.h" #include "chessdefs.h"
#include "position.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) bool pos_ok(pos_t *pos, const bool strict)
{ {
int n, count = 0, bbcount = 0, error = 0; int n, count = 0, bbcount = 0, error = 0;
color_t __unused us = pos->turn, __unused them = OPPONENT(us); color_t 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 <bug.h>
/* pawns on 1st ot 8th rank */ /* pawns on 1st ot 8th rank */
error += warn_on((pos->bb[WHITE][PAWN] | pos->bb[BLACK][PAWN]) & error += warn_on_or_eval((pos->bb[WHITE][PAWN] | pos->bb[BLACK][PAWN]) &
(RANK_1bb | RANK_8bb)); (RANK_1bb | RANK_8bb));
for (color_t color = WHITE; color <= BLACK; ++color) { for (color_t color = WHITE; color <= BLACK; ++color) {
/* pawn count */ /* pawn count */
n = popcount64(pos->bb[color][PAWN]); n = popcount64(pos->bb[color][PAWN]);
error += warn_on(n > 8); error += warn_on_or_eval(n > 8);
/* king count */ /* king count */
n = popcount64(pos->bb[color][KING]); n = popcount64(pos->bb[color][KING]);
error += warn_on(n != 1); error += warn_on_or_eval(n != 1);
/* king mismatch with board */ /* 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 */ /* pieces count */
n = popcount64(pos->bb[color][ALL_PIECES]); 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; bbcount += n;
} }
for (square_t sq = 0; sq < 64; ++sq) { 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); color_t c = COLOR(piece);
piece_type_t p = PIECE(piece); piece_type_t p = PIECE(piece);
match = pos->bb[c][p] & BIT(sq); match = pos->bb[c][p] & BIT(sq);
error += warn_on(!match); error += warn_on_or_eval(!match);
count++; count++;
} }
/* occupied board is different from bitboards */ /* occupied board is different from bitboards */
error += warn_on(count != bbcount); error += warn_on_or_eval(count != bbcount);
/* is opponent already in check ? */ /* 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 ? */ /* 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 */ /* 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 */ /* e.p. and castling rights check */
error += fen_ok(pos, false); error += fen_ok(pos, false);
if (strict) { if (strict) {
bug_on(error); bug_on_always(error);
/* not reached */
} }
return error? false: true; return error? false: true;
# pragma pop_macro("WARN_ON")
# pragma pop_macro("BUG_ON")
} }
/** /**