nissy-core

The "engine" of nissy, including the H48 optimal solver.
git clone https://git.tronto.net/nissy-core
Download | Log | Files | Refs | README | LICENSE

commit 50bd8f0f568120e554d416f474cc72247d0b3240
parent 315d0f118f3d5ec2578249182f7b0eebf99d2943
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Tue, 12 Aug 2025 09:36:36 +0100

Merge branch 'master' of https://github.com/sebastianotronto/nissy-core into windows

Diffstat:
M.gitignore | 1+
MREADME.md | 4++--
Mbuild | 20++++++++++++++------
Mcpp/nissy.cpp | 3++-
Mpython/examples/move.py | 7+++++--
Mpython/examples/solve.py | 11++++++-----
Mpython/examples/variations.py | 5+++--
Mpython/nissy_module.c | 6+++---
Msrc/solvers/distribution.h | 6+++---
Msrc/solvers/h48/gendata_h48.h | 79++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/solvers/h48/gendata_types_macros.h | 16++++++++--------
Msrc/solvers/h48/solve.h | 26+++++++++++++-------------
Msrc/solvers/h48/utils.h | 11+++++++++--
Msrc/solvers/solutions_types_macros.h | 2+-
Msrc/utils/utils.h | 1+
Asrc/utils/wrapthread.h | 37+++++++++++++++++++++++++++++++++++++
Mtest/150_variations/variations.c | 2+-
Mtest/test.h | 1+
18 files changed, 154 insertions(+), 84 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -36,6 +36,7 @@ tools/results *.a *.o *.so +*/*.so *.s *.pyd *.dll diff --git a/README.md b/README.md @@ -224,8 +224,8 @@ $ ./build python And to import it ``` -$ python # In the main folder ->>> import nissy_python_module as nissy # In the python shell +$ python # In the main folder or in the python subfolder +>>> import nissy # In the python shell ``` From here you can call the library functions directly, for example: diff --git a/build b/build @@ -117,15 +117,23 @@ parsesanitize() { done } +maybe_pthread() { + if [ "$THREADS" -gt 1 ]; then + echo "-pthread" + else + echo "" + fi +} + # Build flags -CFLAGS="-std=c11 -fPIC -D_POSIX_C_SOURCE=199309L -pthread" -PYCFLAGS="-std=c11 -fPIC -pthread" +CFLAGS="-std=c11 -fPIC -D_POSIX_C_SOURCE=199309L $(maybe_pthread)" +PYCFLAGS="-std=c11 -fPIC $(maybe_pthread)" [ "$ARCH" = "AVX2" ] && CFLAGS="$CFLAGS -mavx2" WFLAGS="-pedantic -Wall -Wextra -Wno-unused-parameter -Wno-unused-function" OFLAGS="$OPTIMIZE" DFLAGS="-DDEBUG -g3 $(parsesanitize "$SANITIZE")" MFLAGS="-DTHREADS=$THREADS -D$ARCH" -CPPFLAGS="-std=c++20 -pthread" +CPPFLAGS="-std=c++20 $(maybe_pthread)" # TODO: # MEMORY64 is supported on Firefox (from version 134) and Chrome (from 133), @@ -140,9 +148,9 @@ CPPFLAGS="-std=c++20 -pthread" # The options below have to be adjusted when native WASM_SIMD is implemented. # Build flags for emscripten (WASM target) -WASMCFLAGS="-std=c11 -fPIC -D_POSIX_C_SOURCE=199309L -pthread +WASMCFLAGS="-std=c11 -fPIC -D_POSIX_C_SOURCE=199309L $(maybe_pthread) -mfpu=neon -mrelaxed-simd" -WASMCPPFLAGS="-std=c++20 -pthread" +WASMCPPFLAGS="-std=c++20 $(maybe_pthread)" WASMDBGFLAGS="-sASSERTIONS" WASMMFLAGS="-DTHREADS=$THREADS -DNEON" WASMLINKFLAGS="--no-entry -sEXPORT_NAME='Nissy' -sMODULARIZE @@ -272,7 +280,7 @@ build_python() { fi build_nissy || exit 1 run $CC $PYCFLAGS $WFLAGS $PYTHON3_INCLUDES $OFLAGS -shared \ - -o nissy_python_module.so nissy.o python/nissy_module.c + -o python/nissy.so nissy.o python/nissy_module.c } build_cpp() { diff --git a/cpp/nissy.cpp b/cpp/nissy.cpp @@ -12,7 +12,8 @@ extern "C" { long long nissy_inverse(const char *, char *); long long nissy_applymoves(const char *, const char *, char *); long long nissy_applytrans(const char *, const char *, char *); - long long nissy_variations(const char *, const char *, size_t, char*); + long long nissy_variations(const char *, const char *, + unsigned long long, char*); long long nissy_getcube(long long, long long, long long, long long, long long, const char *, char *); long long nissy_solverinfo(const char *, char *); diff --git a/python/examples/move.py b/python/examples/move.py @@ -1,10 +1,13 @@ -# Small example of nissy_python_module usage +# Small example of nissy Python module usage # See the solve.py example for more details on how this works import os, sys +# Assume we are eithe rin the top-level directory of the nissy-core repo, +# or in the python subdirectory sys.path.append(os.getcwd()) -import nissy_python_module as nissy +sys.path.append(os.getcwd() + os.path.sep + "python") +import nissy cube = nissy.applymoves(nissy.solved_cube, "R' U' F"); print("Cube after the moves R' U' F:") diff --git a/python/examples/solve.py b/python/examples/solve.py @@ -1,14 +1,15 @@ -# Small example of nissy_python_module usage +# Small example of nissy Python module usage -# Compile the python module with "make python", then run this from the main -# folder containing nissy_python_module.so +# Run "./build python", then run this from either the top-level directory +# of the nissy-core repo or from the python subdirectory. -# Append the main folder to the python path so we can load the module +# Append the directories to the python path so we can load the module import sys, os sys.path.append(os.getcwd()) +sys.path.append(os.getcwd() + os.path.sep + "python") # Import with a nicer name -import nissy_python_module as nissy +import nissy # Choose the solver you prefer solver = "h48h0k4" diff --git a/python/examples/variations.py b/python/examples/variations.py @@ -1,9 +1,10 @@ -# Small example of nissy_python_module usage +# Small example of nissy Python module usage # See the solve.py example for more details on how this works import sys, os sys.path.append(os.getcwd()) -import nissy_python_module as nissy +sys.path.append(os.getcwd() + os.path.sep + "python") +import nissy moves = "R U' Bw2 M D' x' F B(E2 F D B' Lw2 U2 U' S2 B)" diff --git a/python/nissy_module.c b/python/nissy_module.c @@ -431,7 +431,7 @@ static PyMethodDef nissy_methods[] = { { NULL, NULL, 0, NULL } }; -static struct PyModuleDef nissy_python_module = { +static struct PyModuleDef nissy = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "nissy", .m_doc = "python module for libnissy", @@ -449,11 +449,11 @@ log_stdout(const char *str, void *unused) fprintf(stderr, "%s", str); } -PyMODINIT_FUNC PyInit_nissy_python_module(void) { +PyMODINIT_FUNC PyInit_nissy(void) { PyObject *module; nissy_setlogger(log_stdout, NULL); - module = PyModule_Create(&nissy_python_module); + module = PyModule_Create(&nissy); PyModule_AddStringConstant(module, "solved_cube", NISSY_SOLVED_CUBE); PyModule_AddIntConstant(module, "nissflag_normal", NISSY_NISSFLAG_NORMAL); diff --git a/src/solvers/distribution.h b/src/solvers/distribution.h @@ -43,7 +43,7 @@ getdistribution( const tableinfo_t info[static 1] ) { getdistribution_data_t targ[THREADS]; - pthread_t thread[THREADS]; + wrapthread_define_var_thread_t(thread[THREADS]); uint8_t pval, k; uint64_t local_distr[THREADS][INFO_DISTRIBUTION_LEN]; uint64_t i, j, nbytes, sz, epb; @@ -60,12 +60,12 @@ getdistribution( .distr = local_distr[i], .table = table, }; - pthread_create(&thread[i], NULL, + wrapthread_create(&thread[i], NULL, getdistribution_runthread, &targ[i]); } for (i = 0; i < THREADS; i++) - pthread_join(thread[i], NULL); + wrapthread_join(thread[i], NULL); memset(distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); for (i = 0; i < THREADS; i++) diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h @@ -21,9 +21,9 @@ STATIC const unsigned char *get_h48data_constptr(const unsigned char *); STATIC_INLINE uint8_t get_h48_pval(const unsigned char *, uint64_t, uint8_t); STATIC_INLINE void set_h48_pval(unsigned char *, uint64_t, uint8_t, uint8_t); STATIC_INLINE uint8_t get_h48_pval_atomic( - _Atomic const unsigned char *, uint64_t, uint8_t); + wrapthread_atomic const unsigned char *, uint64_t, uint8_t); STATIC_INLINE void set_h48_pval_atomic( - _Atomic unsigned char *, uint64_t, uint8_t, uint8_t); + wrapthread_atomic unsigned char *, uint64_t, uint8_t, uint8_t); STATIC long long gendata_h48_dispatch( @@ -115,7 +115,7 @@ gendata_h48(gendata_h48_arg_t arg[static 1]) cocsepdata_offset = arg->buf + INFOSIZE; arg->cocsepdata = (uint32_t *)cocsepdata_offset; - arg->h48buf = (_Atomic unsigned char*)arg->buf + cocsepsize; + arg->h48buf = (wrapthread_atomic unsigned char*)arg->buf + cocsepsize; arg->base = 99; @@ -207,13 +207,13 @@ gendata_h48(gendata_h48_arg_t arg[static 1]) STATIC void gendata_h48h0k4(gendata_h48_arg_t arg[static 1]) { - _Atomic unsigned char *table; + wrapthread_atomic unsigned char *table; uint8_t val; uint64_t i, sc, done, d, h48max; uint64_t t, tt, isize, cc, bufsize; h48h0k4_bfs_arg_t bfsarg[THREADS]; - pthread_t thread[THREADS]; - pthread_mutex_t table_mutex[CHUNKS]; + wrapthread_define_var_thread_t(thread[THREADS]); + wrapthread_define_var_mutex_t(table_mutex[CHUNKS]); arg->info = (tableinfo_t) { .solver = "h48 solver h = 0, k = 4", @@ -241,7 +241,7 @@ gendata_h48h0k4(gendata_h48_arg_t arg[static 1]) isize = h48max / THREADS; isize = (isize / H48_COEFF(arg->k)) * H48_COEFF(arg->k); for (t = 0; t < CHUNKS; t++) - pthread_mutex_init(&table_mutex[t], NULL); + wrapthread_mutex_init(&table_mutex[t], NULL); for (t = 0; t < THREADS; t++) { bfsarg[t] = (h48h0k4_bfs_arg_t) { .cocsepdata = arg->cocsepdata, @@ -259,12 +259,12 @@ gendata_h48h0k4(gendata_h48_arg_t arg[static 1]) for (t = 0; t < THREADS; t++) { bfsarg[t].depth = d; - pthread_create(&thread[t], NULL, + wrapthread_create(&thread[t], NULL, gendata_h48h0k4_runthread, &bfsarg[t]); } for (t = 0; t < THREADS; t++) - pthread_join(thread[t], NULL); + wrapthread_join(thread[t], NULL); for (i = 0, cc = 0; i < h48max; i++) { val = get_h48_pval_atomic(table, i, 4); @@ -395,13 +395,14 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1]) int sleeptime; unsigned char *table; uint64_t j; - _Atomic uint64_t count; + wrapthread_atomic uint64_t count; uint64_t i, ii, inext, bufsize, done, nshort, velocity; h48map_t shortcubes; gendata_h48short_arg_t shortarg; h48k2_dfs_arg_t dfsarg[THREADS]; - pthread_t thread[THREADS]; - pthread_mutex_t shortcubes_mutex, table_mutex[CHUNKS]; + wrapthread_define_var_thread_t(thread[THREADS]); + wrapthread_define_var_mutex_t(shortcubes_mutex); + wrapthread_define_var_mutex_t(table_mutex[CHUNKS]); table = (unsigned char *)arg->h48buf + INFOSIZE; memset(table, 0xFF, H48_TABLESIZE(arg->h, arg->k)); @@ -425,9 +426,9 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1]) inext = 0; count = 0; - pthread_mutex_init(&shortcubes_mutex, NULL); + wrapthread_mutex_init(&shortcubes_mutex, NULL); for (i = 0; i < CHUNKS; i++) - pthread_mutex_init(&table_mutex[i], NULL); + wrapthread_mutex_init(&table_mutex[i], NULL); for (i = 0; i < THREADS; i++) { dfsarg[i] = (h48k2_dfs_arg_t){ .h = arg->h, @@ -446,7 +447,7 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1]) for (ii = 0; ii < CHUNKS; ii++) dfsarg[i].table_mutex[ii] = &table_mutex[ii]; - pthread_create( + wrapthread_create( &thread[i], NULL, gendata_h48k2_runthread, &dfsarg[i]); } @@ -464,9 +465,9 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1]) done = count; while (nshort - done > (velocity * sleeptime) / 1000) { msleep(sleeptime); - pthread_mutex_lock(&shortcubes_mutex); + wrapthread_mutex_lock(&shortcubes_mutex); done = count; - pthread_mutex_unlock(&shortcubes_mutex); + wrapthread_mutex_unlock(&shortcubes_mutex); LOG("Processed %" PRIu64 " / %" PRIu64 " cubes\n", (done / 1000) * 1000, nshort); } @@ -476,7 +477,7 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1]) } for (i = 0; i < THREADS; i++) - pthread_join(thread[i], NULL); + wrapthread_join(thread[i], NULL); h48map_destroy(&shortcubes); @@ -492,29 +493,30 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1]) STATIC void * gendata_h48k2_runthread(void *arg) { - uint64_t coord, mutex; + uint64_t coord; kvpair_t kv; h48k2_dfs_arg_t *dfsarg; + wrapthread_define_if_threads(uint64_t, mutex); dfsarg = (h48k2_dfs_arg_t *)arg; while (true) { - pthread_mutex_lock(dfsarg->shortcubes_mutex); + wrapthread_mutex_lock(dfsarg->shortcubes_mutex); kv = h48map_nextkvpair(dfsarg->shortcubes, dfsarg->next); if (*dfsarg->next == dfsarg->shortcubes->capacity) { - pthread_mutex_unlock(dfsarg->shortcubes_mutex); + wrapthread_mutex_unlock(dfsarg->shortcubes_mutex); break; } (*dfsarg->count)++; - pthread_mutex_unlock(dfsarg->shortcubes_mutex); + wrapthread_mutex_unlock(dfsarg->shortcubes_mutex); if (kv.val < dfsarg->shortdepth) { coord = kv.key >> (uint64_t)(11 - dfsarg->h); mutex = H48_INDEX(coord, dfsarg->k) % CHUNKS; - pthread_mutex_lock(dfsarg->table_mutex[mutex]); + wrapthread_mutex_lock(dfsarg->table_mutex[mutex]); set_h48_pval(dfsarg->table, coord, dfsarg->k, 0); - pthread_mutex_unlock(dfsarg->table_mutex[mutex]); + wrapthread_mutex_unlock(dfsarg->table_mutex[mutex]); } else { dfsarg->cube = invcoord_h48(kv.key, dfsarg->crep, 11); gendata_h48k2_dfs(dfsarg); @@ -607,7 +609,8 @@ STATIC_INLINE void gendata_h48_mark_atomic(gendata_h48_mark_t arg[static 1]) { uint8_t oldval, newval; - uint64_t coord, mutex; + uint64_t coord; + wrapthread_define_if_threads(uint64_t, mutex); FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim, coord = coord_h48(arg->cube, arg->cocsepdata, arg->h); @@ -615,10 +618,10 @@ gendata_h48_mark_atomic(gendata_h48_mark_t arg[static 1]) newval = (uint8_t)MAX(arg->depth, 0); if (newval < oldval) { mutex = H48_INDEX(coord, arg->k) % CHUNKS; - pthread_mutex_lock(arg->table_mutex[mutex]); + wrapthread_mutex_lock(arg->table_mutex[mutex]); set_h48_pval_atomic( arg->table_atomic, coord, arg->k, newval); - pthread_mutex_unlock(arg->table_mutex[mutex]); + wrapthread_mutex_unlock(arg->table_mutex[mutex]); } ) } @@ -627,16 +630,17 @@ STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t arg[static 1]) { uint8_t oldval, newval; - uint64_t coord, mutex; + uint64_t coord; + wrapthread_define_if_threads(uint64_t, mutex); FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim, coord = coord_h48(arg->cube, arg->cocsepdata, arg->h); mutex = H48_INDEX(coord, arg->k) % CHUNKS; - pthread_mutex_lock(arg->table_mutex[mutex]); + wrapthread_mutex_lock(arg->table_mutex[mutex]); oldval = get_h48_pval(arg->table, coord, arg->k); newval = (uint8_t)MAX(arg->depth, 0); set_h48_pval(arg->table, coord, arg->k, MIN(newval, oldval)); - pthread_mutex_unlock(arg->table_mutex[mutex]); + wrapthread_mutex_unlock(arg->table_mutex[mutex]); ) } @@ -644,7 +648,8 @@ STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t cube, int8_t d, h48k2_dfs_arg_t arg[static 1]) { uint64_t val; - uint64_t coord, mutex; + uint64_t coord; + wrapthread_define_if_threads(uint64_t, mutex); int8_t oldval; if (arg->h == 0 || arg->h == 11) { @@ -652,9 +657,9 @@ gendata_h48k2_dfs_stop(cube_t cube, int8_t d, h48k2_dfs_arg_t arg[static 1]) if this coordinate has already been visited */ coord = coord_h48(cube, arg->cocsepdata, arg->h); mutex = H48_INDEX(coord, arg->k) % CHUNKS; - pthread_mutex_lock(arg->table_mutex[mutex]); + wrapthread_mutex_lock(arg->table_mutex[mutex]); oldval = get_h48_pval(arg->table, coord, arg->k); - pthread_mutex_unlock(arg->table_mutex[mutex]); + wrapthread_mutex_unlock(arg->table_mutex[mutex]); return oldval <= d; } else { /* With 0 < k < 11 we do not have a "real coordinate". @@ -711,7 +716,11 @@ get_h48_pval(const unsigned char *table, uint64_t i, uint8_t k) } STATIC_INLINE uint8_t -get_h48_pval_atomic(_Atomic const unsigned char *table, uint64_t i, uint8_t k) +get_h48_pval_atomic( + wrapthread_atomic const unsigned char *table, + uint64_t i, + uint8_t k +) { return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k); } @@ -725,7 +734,7 @@ set_h48_pval(unsigned char *table, uint64_t i, uint8_t k, uint8_t val) STATIC_INLINE void set_h48_pval_atomic( - _Atomic unsigned char *table, + wrapthread_atomic unsigned char *table, uint64_t i, uint8_t k, uint8_t val diff --git a/src/solvers/h48/gendata_types_macros.h b/src/solvers/h48/gendata_types_macros.h @@ -68,7 +68,7 @@ typedef struct { tableinfo_t info; uint64_t buf_size; unsigned char *buf; - _Atomic unsigned char *h48buf; + wrapthread_atomic unsigned char *h48buf; uint32_t *cocsepdata; uint64_t selfsim[COCSEP_CLASSES]; cube_t crep[COCSEP_CLASSES]; @@ -85,12 +85,12 @@ typedef struct { typedef struct { uint8_t depth; uint32_t *cocsepdata; - _Atomic unsigned char *table; + wrapthread_atomic unsigned char *table; uint64_t *selfsim; cube_t *crep; uint64_t start; uint64_t end; - pthread_mutex_t *table_mutex[CHUNKS]; + wrapthread_define_struct_mutex_t(*table_mutex[CHUNKS]); } h48h0k4_bfs_arg_t; typedef struct { @@ -104,10 +104,10 @@ typedef struct { uint64_t *selfsim; cube_t *crep; h48map_t *shortcubes; - pthread_mutex_t *shortcubes_mutex; - pthread_mutex_t *table_mutex[CHUNKS]; + wrapthread_define_struct_mutex_t(*shortcubes_mutex); + wrapthread_define_struct_mutex_t(*table_mutex[CHUNKS]); uint64_t *next; - _Atomic uint64_t *count; + wrapthread_atomic uint64_t *count; } h48k2_dfs_arg_t; typedef struct { @@ -118,6 +118,6 @@ typedef struct { uint32_t *cocsepdata; uint64_t *selfsim; unsigned char *table; - _Atomic unsigned char *table_atomic; - pthread_mutex_t **table_mutex; + wrapthread_atomic unsigned char *table_atomic; + wrapthread_define_struct_mutex_t(**table_mutex); } gendata_h48_mark_t; diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h @@ -43,9 +43,9 @@ typedef struct { int ntasks; solve_h48_task_t *tasks; int thread_id; - pthread_mutex_t *solutions_mutex; - _Atomic int *status; - _Atomic bool thread_done; + wrapthread_define_struct_mutex_t(*solutions_mutex); + wrapthread_atomic int *status; + wrapthread_atomic bool thread_done; } dfsarg_solve_h48_t; typedef struct { @@ -207,10 +207,10 @@ solve_h48_dfs(dfsarg_solve_h48_t arg[static 1]) + arg->solution_moves->npremoves; if (arg->target_depth != nm) return 0; - pthread_mutex_lock(arg->solutions_mutex); + wrapthread_mutex_lock(arg->solutions_mutex); ret = appendsolution(arg->solution_moves, arg->solution_settings, arg->solution_list); - pthread_mutex_unlock(arg->solutions_mutex); + wrapthread_mutex_unlock(arg->solutions_mutex); return ret; } @@ -455,7 +455,7 @@ solve_h48( { int i, ntasks, eoesep_table_index; bool td; - _Atomic int status, prev_status; + wrapthread_atomic int status, prev_status; size_t lastused; int8_t d; dfsarg_solve_h48_t arg[THREADS]; @@ -471,8 +471,8 @@ solve_h48( solution_moves_t solution_moves[THREADS]; solution_settings_t settings; solution_list_t sollist; - pthread_t thread[THREADS]; - pthread_mutex_t solutions_mutex; + wrapthread_define_var_thread_t(thread[THREADS]); + wrapthread_define_var_mutex_t(solutions_mutex); if (!solution_list_init(&sollist, solutions_size, solutions)) goto solve_h48_error_solutions_buffer; @@ -541,7 +541,7 @@ solve_h48( } - pthread_mutex_init(&solutions_mutex, NULL); + wrapthread_mutex_init(&solutions_mutex, NULL); maketasks_arg = (dfsarg_solve_h48_maketasks_t) { .cube = oc.cube, @@ -591,7 +591,7 @@ solve_h48( for (i = 0; i < threads; i++) { arg[i].target_depth = d; arg[i].thread_done = false; - pthread_create( + wrapthread_create( &thread[i], NULL, solve_h48_runthread, &arg[i]); } @@ -601,10 +601,10 @@ solve_h48( while (!td && status != NISSY_STATUS_STOP) { msleep(BASE_SLEEP_TIME); - pthread_mutex_lock(&solutions_mutex); + wrapthread_mutex_lock(&solutions_mutex); solve_h48_log_solutions(&sollist, lastused); lastused = sollist.used; - pthread_mutex_unlock(&solutions_mutex); + wrapthread_mutex_unlock(&solutions_mutex); prev_status = status; status = poll_status(poll_status_data); @@ -621,7 +621,7 @@ solve_h48( } for (i = 0; i < threads; i++) - pthread_join(thread[i], NULL); + wrapthread_join(thread[i], NULL); solve_h48_log_solutions(&sollist, lastused); lastused = sollist.used; diff --git a/src/solvers/h48/utils.h b/src/solvers/h48/utils.h @@ -1,3 +1,9 @@ +#if SIZE_MAX == UINT64_MAX +#define H48_HMAX UINT8_C(11) +#else +#define H48_HMAX UINT8_C(7) +#endif + long long parse_h48_hk( const char *, uint8_t [static 1], uint8_t [static 1]); STATIC long long dataid_h48(const char *, char [static NISSY_SIZE_DATAID]); @@ -18,8 +24,9 @@ parse_h48_hk(const char *buf, uint8_t h[static 1], uint8_t k[static 1]) buf++; *h = atoi(buf); - if (*h > 11) { - LOG("[H48] Invalid value %" PRIu8 " for parameter h\n", *h); + if (*h > H48_HMAX) { + LOG("[H48] Invalid value %" PRIu8 " for parameter h (must be " + "at most %" PRIu8 ")\n", *h, H48_HMAX); goto parse_h48_hk_error; } diff --git a/src/solvers/solutions_types_macros.h b/src/solvers/solutions_types_macros.h @@ -17,7 +17,7 @@ typedef struct { } solution_settings_t; typedef struct { - _Atomic uint64_t nsols; + wrapthread_atomic uint64_t nsols; uint8_t shortest_sol; size_t size; size_t used; diff --git a/src/utils/utils.h b/src/utils/utils.h @@ -2,3 +2,4 @@ #include "constants.h" #include "math.h" #include "sleep.h" +#include "wrapthread.h" diff --git a/src/utils/wrapthread.h b/src/utils/wrapthread.h @@ -0,0 +1,37 @@ +#if THREADS == 1 + +#define wrapthread_atomic + +#define wrapthread_define_var_thread_t(x) char x; (void)(x) +#define wrapthread_define_var_mutex_t(x) char x; (void)(x) +#define wrapthread_define_struct_thread_t(x) char x +#define wrapthread_define_struct_mutex_t(x) char x + +#define wrapthread_define_if_threads(T, x) T x; (void)(x) + +#define wrapthread_create(a, b, c, d) c(d) +#define wrapthread_join(a, b) +#define wrapthread_mutex_init(a, b) +#define wrapthread_mutex_lock(a) +#define wrapthread_mutex_unlock(a) + +#else + +#include <pthread.h> + +#define wrapthread_atomic _Atomic + +#define wrapthread_define_var_thread_t(x) pthread_t x +#define wrapthread_define_var_mutex_t(x) pthread_mutex_t x +#define wrapthread_define_struct_thread_t(x) pthread_t x +#define wrapthread_define_struct_mutex_t(x) pthread_mutex_t x + +#define wrapthread_define_if_threads(T, x) T x + +#define wrapthread_create(a, b, c, d) pthread_create(a, b, c, d) +#define wrapthread_join(a, b) pthread_join(a, b) +#define wrapthread_mutex_init(a, b) pthread_mutex_init(a, b) +#define wrapthread_mutex_lock(a) pthread_mutex_lock(a) +#define wrapthread_mutex_unlock(a) pthread_mutex_unlock(a) + +#endif diff --git a/test/150_variations/variations.c b/test/150_variations/variations.c @@ -1,7 +1,7 @@ #include "../test.h" long long nissy_variations( - const char *, const char *, long long unsigned, char *); + const char *, const char *, unsigned long long, char *); void run(void) { long long err; diff --git a/test/test.h b/test/test.h @@ -8,6 +8,7 @@ #include <stdlib.h> #include <string.h> +#include "../src/utils/wrapthread.h" #include "../src/nissy.h" #include "../src/arch/arch.h" #include "../src/core/core_types.h"