aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-04-29 10:08:04 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2025-04-29 10:08:04 +0200
commit8d3fc9f5f9c0593fcae9c451efe6c89c64dcbe84 (patch)
tree8c0182f9bf94aaa8afe5126988e07af82c4409fd
parentcdf46d85efe7fa54e8c302a255214341c567b4af (diff)
downloadnissy-core-8d3fc9f5f9c0593fcae9c451efe6c89c64dcbe84.tar.gz
nissy-core-8d3fc9f5f9c0593fcae9c451efe6c89c64dcbe84.zip
Added stop / pause / resume solve to API
-rwxr-xr-xconfigure.sh5
-rw-r--r--cpp/examples/solve_h48h3k2.cpp2
-rw-r--r--cpp/nissy.cpp13
-rw-r--r--cpp/nissy.h12
-rw-r--r--python/nissy_module.c6
-rw-r--r--shell/shell.c2
-rw-r--r--src/nissy.c24
-rw-r--r--src/nissy.h53
-rw-r--r--src/solvers/coord/solve.h14
-rw-r--r--src/solvers/h48/solve.h69
-rw-r--r--src/utils/sleep.h48
-rw-r--r--src/utils/utils.h1
-rw-r--r--tools/300_solve_small/solve_small.c3
-rw-r--r--tools/301_solve_file/solve_file.c3
-rw-r--r--tools/302_solve_multisol/solve_multisol.c3
-rw-r--r--tools/400_solvetest/solve_test.c6
16 files changed, 213 insertions, 51 deletions
diff --git a/configure.sh b/configure.sh
index e31e650..4a60ed4 100755
--- a/configure.sh
+++ b/configure.sh
@@ -85,6 +85,7 @@ validatethreads
85validatearch 85validatearch
86 86
87STD="-std=c11" 87STD="-std=c11"
88POSIX="-D_POSIX_C_SOURCE=199309L"
88WFLAGS="-pedantic -Wall -Wextra" 89WFLAGS="-pedantic -Wall -Wextra"
89WNOFLAGS="-Wno-unused-parameter -Wno-unused-function -Wno-unknown-pragmas" 90WNOFLAGS="-Wno-unused-parameter -Wno-unused-function -Wno-unknown-pragmas"
90WNOFLAGS="$WNOFLAGS -Wno-unused-command-line-argument" 91WNOFLAGS="$WNOFLAGS -Wno-unused-command-line-argument"
@@ -99,8 +100,8 @@ if [ -n "$SANITIZE" ]; then
99fi 100fi
100LIBS="-lpthread" 101LIBS="-lpthread"
101 102
102CFLAGS="$STD $LIBS $WFLAGS $WNOFLAGS $AVX -O3 -fPIC -D$ARCH" 103CFLAGS="$STD $POSIX $LIBS $WFLAGS $WNOFLAGS $AVX -O3 -fPIC -D$ARCH"
103DBGFLAGS="$STD $LIBS $WFLAGS $WNOFLAGS $SAN $AVX -g3 -DDEBUG -fPIC -D$ARCH" 104DBGFLAGS="$STD $POSIX $LIBS $WFLAGS $WNOFLAGS $SAN $AVX -g3 -DDEBUG -fPIC -D$ARCH"
104WASMFLAGS="$STD $LIBS $WFLAGS $WNOFLAGS -O3 -fPIC" 105WASMFLAGS="$STD $LIBS $WFLAGS $WNOFLAGS -O3 -fPIC"
105MACROS="-DTHREADS=$THREADS" 106MACROS="-DTHREADS=$THREADS"
106 107
diff --git a/cpp/examples/solve_h48h3k2.cpp b/cpp/examples/solve_h48h3k2.cpp
index f7ba235..f0d6f2f 100644
--- a/cpp/examples/solve_h48h3k2.cpp
+++ b/cpp/examples/solve_h48h3k2.cpp
@@ -68,7 +68,7 @@ int main() {
68 68
69 // Solve 69 // Solve
70 auto solve_result = h48h3k2.solve(c, nissy::nissflag::NORMAL, 70 auto solve_result = h48h3k2.solve(c, nissy::nissflag::NORMAL,
71 0, maxmoves, 1, 20, 8); 71 0, maxmoves, 1, 20, 8, NULL, NULL);
72 72
73 // Write the result 73 // Write the result
74 if (!solve_result.err.ok()) { 74 if (!solve_result.err.ok()) {
diff --git a/cpp/nissy.cpp b/cpp/nissy.cpp
index 118a072..2faea6f 100644
--- a/cpp/nissy.cpp
+++ b/cpp/nissy.cpp
@@ -20,7 +20,8 @@ extern "C" {
20 long long nissy_checkdata(unsigned long long, const unsigned char *); 20 long long nissy_checkdata(unsigned long long, const unsigned char *);
21 long long nissy_solve(const char *, const char *, unsigned, unsigned, 21 long long nissy_solve(const char *, const char *, unsigned, unsigned,
22 unsigned, unsigned, unsigned, unsigned, unsigned long long, 22 unsigned, unsigned, unsigned, unsigned, unsigned long long,
23 const unsigned char *, unsigned, char *, long long *); 23 const unsigned char *, unsigned, char *, long long *,
24 int (*)(void *), void *);
24 long long nissy_countmoves(const char *); 25 long long nissy_countmoves(const char *);
25 long long nissy_setlogger(void (*)(const char *, void *), void *); 26 long long nissy_setlogger(void (*)(const char *, void *), void *);
26} 27}
@@ -47,6 +48,10 @@ namespace nissy {
47 const error error::OPTIONS{-80}; 48 const error error::OPTIONS{-80};
48 const error error::UNKNOWN{-999}; 49 const error error::UNKNOWN{-999};
49 50
51 const status status::run{0};
52 const status status::stop{1};
53 const status status::pause{2};
54
50 namespace size { 55 namespace size {
51 constexpr size_t CUBE = 22; 56 constexpr size_t CUBE = 22;
52 constexpr size_t TRANSFORMATION = 12; 57 constexpr size_t TRANSFORMATION = 12;
@@ -154,7 +159,8 @@ namespace nissy {
154 solver::solve_result 159 solver::solve_result
155 solver::solve(const cube& cube, nissflag niss, unsigned minmoves, 160 solver::solve(const cube& cube, nissflag niss, unsigned minmoves,
156 unsigned maxmoves, unsigned maxsols, unsigned optimal, 161 unsigned maxmoves, unsigned maxsols, unsigned optimal,
157 unsigned threads) 162 unsigned threads, int (*poll_status)(void *),
163 void *poll_status_data)
158 { 164 {
159 solver::solve_result result; 165 solver::solve_result result;
160 166
@@ -171,7 +177,8 @@ namespace nissy {
171 name.c_str(), niss.value, minmoves, maxmoves, maxsols, 177 name.c_str(), niss.value, minmoves, maxmoves, maxsols,
172 optimal, threads, data.size(), 178 optimal, threads, data.size(),
173 reinterpret_cast<const unsigned char *>(data.data()), len, 179 reinterpret_cast<const unsigned char *>(data.data()), len,
174 csols.data(), result.stats.data()); 180 csols.data(), result.stats.data(), poll_status,
181 poll_status_data);
175 result.err = error{err}; 182 result.err = error{err};
176 183
177 if (err < 0) 184 if (err < 0)
diff --git a/cpp/nissy.h b/cpp/nissy.h
index 4fa98ad..41d3876 100644
--- a/cpp/nissy.h
+++ b/cpp/nissy.h
@@ -46,6 +46,15 @@ namespace nissy {
46 static const error UNKNOWN; 46 static const error UNKNOWN;
47 }; 47 };
48 48
49 class status {
50 public:
51 int value;
52
53 static const status run;
54 static const status stop;
55 static const status pause;
56 };
57
49 class cube { 58 class cube {
50 public: 59 public:
51 cube(); 60 cube();
@@ -86,7 +95,8 @@ namespace nissy {
86 void unload_data(); 95 void unload_data();
87 solve_result solve(const cube&, nissflag, unsigned minmoves, 96 solve_result solve(const cube&, nissflag, unsigned minmoves,
88 unsigned maxmoves, unsigned maxsols, unsigned optimal, 97 unsigned maxmoves, unsigned maxsols, unsigned optimal,
89 unsigned threads); 98 unsigned threads, int (*poll_status)(void *),
99 void *poll_status_data);
90 100
91 static std::variant<solver, error> get(const std::string&); 101 static std::variant<solver, error> get(const std::string&);
92 private: 102 private:
diff --git a/python/nissy_module.c b/python/nissy_module.c
index bf5a71a..069dea0 100644
--- a/python/nissy_module.c
+++ b/python/nissy_module.c
@@ -300,7 +300,7 @@ solve(PyObject *self, PyObject *args)
300 result = nissy_solve(cube, solver, nissflag, minmoves, maxmoves, 300 result = nissy_solve(cube, solver, nissflag, minmoves, maxmoves,
301 maxsolutions, optimal, threads, data->ob_alloc, 301 maxsolutions, optimal, threads, data->ob_alloc,
302 (unsigned char *)data->ob_bytes, MAX_SOLUTIONS_SIZE, solutions, 302 (unsigned char *)data->ob_bytes, MAX_SOLUTIONS_SIZE, solutions,
303 stats); 303 stats, NULL, NULL);
304 Py_END_ALLOW_THREADS 304 Py_END_ALLOW_THREADS
305 305
306 if(!check_error(result)) { 306 if(!check_error(result)) {
@@ -350,9 +350,9 @@ static PyMethodDef nissy_methods[] = {
350 { "getcube", getcube, METH_VARARGS, getcube_doc }, 350 { "getcube", getcube, METH_VARARGS, getcube_doc },
351 { "solverinfo", solverinfo, METH_VARARGS, solverinfo_doc }, 351 { "solverinfo", solverinfo, METH_VARARGS, solverinfo_doc },
352 { "gendata", gendata, METH_VARARGS, gendata_doc }, 352 { "gendata", gendata, METH_VARARGS, gendata_doc },
353 { "checkdata", checkdata, METH_VARARGS, checkdata_doc }, 353 { "checkdata", _checkdata, METH_VARARGS, checkdata_doc },
354 { "solve", solve, METH_VARARGS, solve_doc }, 354 { "solve", solve, METH_VARARGS, solve_doc },
355 { "countmoves", countmoves, METH_VARARGS, countmoves_doc }, 355 { "countmoves", _countmoves, METH_VARARGS, countmoves_doc },
356 { NULL, NULL, 0, NULL } 356 { NULL, NULL, 0, NULL }
357}; 357};
358 358
diff --git a/shell/shell.c b/shell/shell.c
index 3ee69c4..1fa854f 100644
--- a/shell/shell.c
+++ b/shell/shell.c
@@ -435,7 +435,7 @@ solve_exec(args_t *args)
435 ret = nissy_solve( 435 ret = nissy_solve(
436 args->cube, args->str_solver, nissflag, args->minmoves, 436 args->cube, args->str_solver, nissflag, args->minmoves,
437 args->maxmoves, args->maxsolutions, args->optimal, args->threads, 437 args->maxmoves, args->maxsolutions, args->optimal, args->threads,
438 size, buf, SOLUTIONS_BUFFER_SIZE, solutions, stats); 438 size, buf, SOLUTIONS_BUFFER_SIZE, solutions, stats, NULL, NULL);
439 439
440 free(buf); 440 free(buf);
441 441
diff --git a/src/nissy.c b/src/nissy.c
index 2dd5a41..acf6ebe 100644
--- a/src/nissy.c
+++ b/src/nissy.c
@@ -460,7 +460,9 @@ nissy_solve(
460 const unsigned char data[data_size], 460 const unsigned char data[data_size],
461 unsigned sols_size, 461 unsigned sols_size,
462 char sols[sols_size], 462 char sols[sols_size],
463 long long stats[static NISSY_SIZE_SOLVE_STATS] 463 long long stats[static NISSY_SIZE_SOLVE_STATS],
464 int (*poll_status)(void *),
465 void *poll_status_data
464) 466)
465{ 467{
466 oriented_cube_t oc; 468 oriented_cube_t oc;
@@ -475,14 +477,23 @@ nissy_solve(
475 477
476 oc = readcube(cube); 478 oc = readcube(cube);
477 479
478/* TODO: solve should handle oriented cubes */
479
480 if (!isconsistent(oc)) { 480 if (!isconsistent(oc)) {
481 LOG("[solve] Error: cube is invalid\n"); 481 LOG("[solve] Error: cube is invalid\n");
482 return NISSY_ERROR_INVALID_CUBE; 482 return NISSY_ERROR_INVALID_CUBE;
483 } 483 }
484 484
485/* TODO: checks for minmoves, maxmoves, nissflag */ 485 if (maxmoves > 20) {
486 LOG("[solve] 'maxmoves' larger than 20 not supported yet, "
487 "setting it to 20\n");
488 maxmoves = 20;
489 }
490
491 if (minmoves > maxmoves) {
492 LOG("[solve] value provided for 'minmoves' (%u) is larger "
493 "than that provided for 'maxmoves' (%u), setting "
494 "'minmoves' to %u\n", minmoves, maxmoves, maxmoves);
495 minmoves = maxmoves;
496 }
486 497
487 if (maxsols == 0) { 498 if (maxsols == 0) {
488 LOG("[solve] 'maxsols' is 0, returning no solution\n"); 499 LOG("[solve] 'maxsols' is 0, returning no solution\n");
@@ -505,11 +516,12 @@ nissy_solve(
505 if (parse_ret != NISSY_OK) 516 if (parse_ret != NISSY_OK)
506 return parse_ret; 517 return parse_ret;
507 return solve_h48(oc, minmoves, maxmoves, maxsols, 518 return solve_h48(oc, minmoves, maxmoves, maxsols,
508 optimal, t, data_size, data, sols_size, sols, stats); 519 optimal, t, data_size, data, sols_size, sols, stats,
520 poll_status, poll_status_data);
509 } else if (!strncmp(solver, "coord_", 6)) { 521 } else if (!strncmp(solver, "coord_", 6)) {
510 return solve_coord_dispatch(oc, solver + 6, nissflag, 522 return solve_coord_dispatch(oc, solver + 6, nissflag,
511 minmoves, maxmoves, maxsols, optimal, t, data_size, data, 523 minmoves, maxmoves, maxsols, optimal, t, data_size, data,
512 sols_size, sols); 524 sols_size, sols, poll_status, poll_status_data);
513 } else { 525 } else {
514 LOG("[solve] Error: unknown solver '%s'\n", solver); 526 LOG("[solve] Error: unknown solver '%s'\n", solver);
515 return NISSY_ERROR_INVALID_SOLVER; 527 return NISSY_ERROR_INVALID_SOLVER;
diff --git a/src/nissy.h b/src/nissy.h
index 5800490..2fa4a75 100644
--- a/src/nissy.h
+++ b/src/nissy.h
@@ -37,6 +37,11 @@ for example 'rotation UF' or 'mirrored BL'.
37#define NISSY_NISSFLAG_ALL \ 37#define NISSY_NISSFLAG_ALL \
38 (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE | NISSY_NISSFLAG_MIXED) 38 (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE | NISSY_NISSFLAG_MIXED)
39 39
40/* Status for stopping / pausing / resuming a solver */
41#define NISSY_STATUS_RUN 0
42#define NISSY_STATUS_STOP 1
43#define NISSY_STATUS_PAUSE 2
44
40/* The solved cube */ 45/* The solved cube */
41#define NISSY_SOLVED_CUBE "ABCDEFGH=ABCDEFGHIJKL=A" 46#define NISSY_SOLVED_CUBE "ABCDEFGH=ABCDEFGHIJKL=A"
42 47
@@ -296,24 +301,32 @@ nissy_checkdata(
296Solve the given cube using the given solver and options. 301Solve the given cube using the given solver and options.
297 302
298Parameters: 303Parameters:
299 cube - The cube to solver. 304 cube - The cube to solver.
300 solver - The name of the solver. 305 solver - The name of the solver.
301 nissflag - The flags for NISS (linear, inverse, mixed, or combinations). 306 nissflag - The flags for NISS (linear, inverse, mixed, or
302 minmoves - The minimum number of moves for a solution. 307 combinations; see the constants at the top of this file).
303 maxmoves - The maximum number of moves for a solution. 308 minmoves - The minimum number of moves for a solution.
304 maxsols - The maximum number of solutions. 309 maxmoves - The maximum number of moves for a solution.
305 optimal - The maximum number of moves above the optimal solution length. 310 maxsols - The maximum number of solutions.
306 threads - The number of threads to use. Must be less than or equalt to 311 optimal - The maximum number of moves above the optimal solution.
307 the value of the compile-time constant THREADS. If set to 0, 312 threads - The number of threads to use. Must be less than or equal
308 the default value THREADS will be used. 313 to the value of the compile-time constant THREADS. If set
309 data_size - The size of the data buffer. 314 to 0, the default value THREADS will be used.
310 data - The data for the solver. Can be computed with gendata. 315 data_size - The size of the data buffer.
311 This buffer must have 8-byte alignment. 316 data - The data for the solver. Can be computed with gendata.
312 sols_size - The size of the solutions buffer. 317 This buffer must have 8-byte alignment.
313 sols - The return parameter for the solutions. The solutions are 318 sols_size - The size of the solutions buffer.
314 separated by a '\n' (newline) and a '\0' (NULL character) 319 sols - The return parameter for the solutions. The solutions are
315 terminates the list. 320 separated by a '\n' (newline) and a '\0' (NULL character)
316 stats - An array to store some statistics about the solve. 321 terminates the list.
322 stats - An array to store some statistics about the solve.
323 poll_status - A callback function that should return the current
324 requested status for the solver (e.g. run, stop, pause,
325 resume; see the constants at the top of this file). The
326 way this status is polled and honored is solver-specific.
327 If this parameter is NULL, the status will always assumed
328 to be "run".
329 poll_status_data - Auxiliary data for the poll_status callback function.
317 330
318Return values: 331Return values:
319 NISSY_OK - Cube solved succesfully. 332 NISSY_OK - Cube solved succesfully.
@@ -340,7 +353,9 @@ nissy_solve(
340 const unsigned char data[data_size], 353 const unsigned char data[data_size],
341 unsigned sols_size, 354 unsigned sols_size,
342 char sols[sols_size], 355 char sols[sols_size],
343 long long stats[static NISSY_SIZE_SOLVE_STATS] 356 long long stats[static NISSY_SIZE_SOLVE_STATS],
357 int (*poll_status)(void *),
358 void *poll_status_data
344); 359);
345 360
346/* 361/*
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h
index 48cc704..8eb3e9d 100644
--- a/src/solvers/coord/solve.h
+++ b/src/solvers/coord/solve.h
@@ -14,10 +14,10 @@ typedef struct {
14 14
15STATIC int64_t solve_coord(oriented_cube_t, coord_t [static 1], uint8_t, 15STATIC int64_t solve_coord(oriented_cube_t, coord_t [static 1], uint8_t,
16 uint8_t, uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t, 16 uint8_t, uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t,
17 const unsigned char *, size_t n, char [n]); 17 const unsigned char *, size_t n, char [n], int (*)(void *), void *);
18STATIC int64_t solve_coord_dispatch(oriented_cube_t, const char *, uint8_t, 18STATIC int64_t solve_coord_dispatch(oriented_cube_t, const char *, uint8_t,
19 uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t, 19 uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t,
20 const unsigned char *, size_t n, char [n]); 20 const unsigned char *, size_t n, char [n], int (*)(void *), void *);
21STATIC bool coord_solution_admissible(const dfsarg_solve_coord_t [static 1]); 21STATIC bool coord_solution_admissible(const dfsarg_solve_coord_t [static 1]);
22STATIC bool solve_coord_dfs_stop(const dfsarg_solve_coord_t [static 1]); 22STATIC bool solve_coord_dfs_stop(const dfsarg_solve_coord_t [static 1]);
23STATIC bool coord_continue_onnormal(const dfsarg_solve_coord_t [static 1]); 23STATIC bool coord_continue_onnormal(const dfsarg_solve_coord_t [static 1]);
@@ -211,7 +211,9 @@ solve_coord_dispatch(
211 uint64_t data_size, 211 uint64_t data_size,
212 const unsigned char *data, 212 const unsigned char *data,
213 size_t solutions_size, 213 size_t solutions_size,
214 char sols[solutions_size] 214 char sols[solutions_size],
215 int (*poll_status)(void *),
216 void *poll_status_data
215) 217)
216{ 218{
217 coord_t *coord; 219 coord_t *coord;
@@ -233,7 +235,7 @@ solve_coord_dispatch(
233 235
234 return solve_coord(oc, coord, axis, nissflag, minmoves, maxmoves, 236 return solve_coord(oc, coord, axis, nissflag, minmoves, maxmoves,
235 maxsolutions, optimal, threads, data_size, data, 237 maxsolutions, optimal, threads, data_size, data,
236 solutions_size, sols); 238 solutions_size, sols, poll_status, poll_status_data);
237} 239}
238 240
239STATIC int64_t 241STATIC int64_t
@@ -250,7 +252,9 @@ solve_coord(
250 uint64_t data_size, 252 uint64_t data_size,
251 const unsigned char *data, 253 const unsigned char *data,
252 size_t solutions_size, 254 size_t solutions_size,
253 char sols[solutions_size] 255 char sols[solutions_size],
256 int (*poll_status)(void *),
257 void *poll_status_data
254) 258)
255{ 259{
256 int8_t d; 260 int8_t d;
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h
index e3ef9b9..f2967ed 100644
--- a/src/solvers/h48/solve.h
+++ b/src/solvers/h48/solve.h
@@ -35,6 +35,10 @@ typedef struct {
35 solve_h48_task_t *tasks; 35 solve_h48_task_t *tasks;
36 int thread_id; 36 int thread_id;
37 pthread_mutex_t *solutions_mutex; 37 pthread_mutex_t *solutions_mutex;
38 int (*poll_status)(void *);
39 void *poll_status_data;
40 _Atomic bool cancelled;
41 _Atomic bool cantsleep;
38} dfsarg_solve_h48_t; 42} dfsarg_solve_h48_t;
39 43
40typedef struct { 44typedef struct {
@@ -50,11 +54,12 @@ STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t [static 1]);
50STATIC int64_t solve_h48_maketasks( 54STATIC int64_t solve_h48_maketasks(
51 dfsarg_solve_h48_t [static 1], dfsarg_solve_h48_maketasks_t [static 1], 55 dfsarg_solve_h48_t [static 1], dfsarg_solve_h48_maketasks_t [static 1],
52 solve_h48_task_t [static STARTING_CUBES], int [static 1]); 56 solve_h48_task_t [static STARTING_CUBES], int [static 1]);
57STATIC bool solve_h48_runthread_continue(dfsarg_solve_h48_t *);
53STATIC void *solve_h48_runthread(void *); 58STATIC void *solve_h48_runthread(void *);
54STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); 59STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]);
55STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t, 60STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t,
56 uint8_t, uint64_t, const unsigned char *, size_t n, char [n], 61 uint8_t, uint64_t, const unsigned char *, size_t n, char [n],
57 long long [static NISSY_SIZE_SOLVE_STATS]); 62 long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *);
58 63
59STATIC_INLINE bool 64STATIC_INLINE bool
60solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) 65solve_h48_stop(dfsarg_solve_h48_t arg[static 1])
@@ -232,16 +237,42 @@ solve_h48_dfs(dfsarg_solve_h48_t arg[static 1])
232 return ret; 237 return ret;
233} 238}
234 239
240STATIC bool
241solve_h48_runthread_continue(dfsarg_solve_h48_t *arg)
242{
243 int status;
244
245 for (status = NISSY_STATUS_PAUSE; status == NISSY_STATUS_PAUSE; ) {
246 status = arg->poll_status == NULL ? NISSY_STATUS_RUN :
247 arg->poll_status(arg->poll_status_data);
248 msleep(500);
249 }
250
251 return status == NISSY_STATUS_RUN;
252}
253
235STATIC void * 254STATIC void *
236solve_h48_runthread(void *arg) 255solve_h48_runthread(void *arg)
237{ 256{
238 int i, j; 257 int i, j, status;
239 solve_h48_task_t task; 258 solve_h48_task_t task;
240 dfsarg_solve_h48_t *dfsarg; 259 dfsarg_solve_h48_t *dfsarg;
241 260
242 dfsarg = (dfsarg_solve_h48_t *)arg; 261 dfsarg = (dfsarg_solve_h48_t *)arg;
243 262
244 for (i = dfsarg->thread_id; i < dfsarg->ntasks; i += dfsarg->threads) { 263 for (i = dfsarg->thread_id; i < dfsarg->ntasks; i += dfsarg->threads) {
264 status = dfsarg->poll_status == NULL ? NISSY_STATUS_RUN :
265 dfsarg->poll_status(dfsarg->poll_status_data);
266 switch (status) {
267 case NISSY_STATUS_STOP:
268 goto solve_h48_runthread_cancel;
269 case NISSY_STATUS_PAUSE:
270 if (!NISSY_CANSLEEP)
271 goto solve_h48_runthread_cantsleep;
272 if (!solve_h48_runthread_continue(dfsarg))
273 goto solve_h48_runthread_cancel;
274 }
275
245 task = dfsarg->tasks[i]; 276 task = dfsarg->tasks[i];
246 277
247 solution_moves_reset(dfsarg->solution_moves); 278 solution_moves_reset(dfsarg->solution_moves);
@@ -265,6 +296,12 @@ solve_h48_runthread(void *arg)
265 } 296 }
266 297
267 return NULL; 298 return NULL;
299
300solve_h48_runthread_cantsleep:
301 dfsarg->cantsleep = true;
302solve_h48_runthread_cancel:
303 dfsarg->cancelled = true;
304 return NULL;
268} 305}
269 306
270STATIC int64_t 307STATIC int64_t
@@ -351,9 +388,12 @@ solve_h48(
351 const unsigned char *data, 388 const unsigned char *data,
352 size_t solutions_size, 389 size_t solutions_size,
353 char solutions[solutions_size], 390 char solutions[solutions_size],
354 long long stats[static NISSY_SIZE_SOLVE_STATS] 391 long long stats[static NISSY_SIZE_SOLVE_STATS],
392 int (*poll_status)(void *),
393 void *poll_status_data
355) 394)
356{ 395{
396 bool anycancelled, anycantsleep;
357 int i, ntasks, eoesep_table_index; 397 int i, ntasks, eoesep_table_index;
358 int8_t d; 398 int8_t d;
359 dfsarg_solve_h48_t arg[THREADS]; 399 dfsarg_solve_h48_t arg[THREADS];
@@ -434,6 +474,10 @@ solve_h48(
434 .threads = threads, 474 .threads = threads,
435 .thread_id = i, 475 .thread_id = i,
436 .solutions_mutex = &solutions_mutex, 476 .solutions_mutex = &solutions_mutex,
477 .poll_status = poll_status,
478 .poll_status_data = poll_status_data,
479 .cancelled = false,
480 .cantsleep = false,
437 }; 481 };
438 482
439 } 483 }
@@ -460,9 +504,10 @@ solve_h48(
460 504
461 LOG("[H48 solve] Prepared %d tasks\n", ntasks); 505 LOG("[H48 solve] Prepared %d tasks\n", ntasks);
462 506
507 anycancelled = anycantsleep = false;
463 for ( 508 for (
464 d = MAX(minmoves, STARTING_MOVES + 1); 509 d = MAX(minmoves, STARTING_MOVES + 1);
465 !solutions_done(&sollist, &settings, d); 510 !(solutions_done(&sollist, &settings, d) || anycancelled);
466 d++ 511 d++
467 ) { 512 ) {
468 if (d >= 15) 513 if (d >= 15)
@@ -474,8 +519,22 @@ solve_h48(
474 pthread_create( 519 pthread_create(
475 &thread[i], NULL, solve_h48_runthread, &arg[i]); 520 &thread[i], NULL, solve_h48_runthread, &arg[i]);
476 } 521 }
477 for (i = 0; i < threads; i++) 522 for (i = 0; i < threads; i++) {
478 pthread_join(thread[i], NULL); 523 pthread_join(thread[i], NULL);
524 anycancelled = anycancelled || arg[i].cancelled;
525 anycantsleep = anycantsleep || arg[i].cantsleep;
526 }
527 }
528
529 if (anycantsleep) {
530 LOG("[H48 solve] Received pause request, but this feature is "
531 "not available on this system. "
532 "Taking it as a stop request.\n");
533 }
534
535 if (anycancelled) {
536 LOG("[H48 solve] Received stop request, ending solution "
537 "search early.\n");
479 } 538 }
480 539
481solve_h48_done: 540solve_h48_done:
diff --git a/src/utils/sleep.h b/src/utils/sleep.h
new file mode 100644
index 0000000..d618e9b
--- /dev/null
+++ b/src/utils/sleep.h
@@ -0,0 +1,48 @@
1STATIC void msleep(int);
2
3#if defined(WIN32)
4
5#define NISSY_CANSLEEP true
6
7STATIC void
8msleep(int milliseconds)
9{
10 Sleep(milliseconds);
11}
12
13#elif defined(__wasm__)
14
15#include <emscripten.h>
16
17#define NISSY_CANSLEEP true
18
19STATIC void
20msleep(int milliseconds)
21{
22 emscripten_sleep(milliseconds);
23}
24
25#elif defined(__unix__)
26
27#include <time.h>
28
29#define NISSY_CANSLEEP true
30
31STATIC void
32msleep(int milliseconds)
33{
34 struct timespec t;
35 t.tv_sec = milliseconds / 1000;
36 t.tv_nsec = (milliseconds % 1000) * 1000000;
37 nanosleep(&t, NULL);
38}
39
40#else
41
42#define NISSY_CANSLEEP false
43STATIC void
44msleep(int milliseconds)
45{
46}
47
48#endif
diff --git a/src/utils/utils.h b/src/utils/utils.h
index ce4355e..d14b285 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -1,3 +1,4 @@
1#include "dbg_log.h" 1#include "dbg_log.h"
2#include "constants.h" 2#include "constants.h"
3#include "math.h" 3#include "math.h"
4#include "sleep.h"
diff --git a/tools/300_solve_small/solve_small.c b/tools/300_solve_small/solve_small.c
index dcd47c1..83a712a 100644
--- a/tools/300_solve_small/solve_small.c
+++ b/tools/300_solve_small/solve_small.c
@@ -37,7 +37,8 @@ void run(void) {
37 continue; 37 continue;
38 } 38 }
39 n = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL, 39 n = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL,
40 0, 20, 1, -1, 0, size, buf, SOL_BUFFER_LEN, sol, stats); 40 0, 20, 1, -1, 0, size, buf, SOL_BUFFER_LEN, sol, stats,
41 NULL, NULL);
41 if (n == 0) 42 if (n == 0)
42 printf("No solution found\n"); 43 printf("No solution found\n");
43 else 44 else
diff --git a/tools/301_solve_file/solve_file.c b/tools/301_solve_file/solve_file.c
index d9084fd..be4d1f5 100644
--- a/tools/301_solve_file/solve_file.c
+++ b/tools/301_solve_file/solve_file.c
@@ -24,7 +24,8 @@ void run(void) {
24 continue; 24 continue;
25 } 25 }
26 nsols = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL, 26 nsols = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL,
27 0, 20, 1, -1, 0, size, buf, SOL_BUFFER_LEN, sol, stats); 27 0, 20, 1, -1, 0, size, buf, SOL_BUFFER_LEN, sol, stats,
28 NULL, NULL);
28 if (nsols == 0) 29 if (nsols == 0)
29 printf("No solution found\n"); 30 printf("No solution found\n");
30 else 31 else
diff --git a/tools/302_solve_multisol/solve_multisol.c b/tools/302_solve_multisol/solve_multisol.c
index a2896a9..8f04b5f 100644
--- a/tools/302_solve_multisol/solve_multisol.c
+++ b/tools/302_solve_multisol/solve_multisol.c
@@ -30,7 +30,8 @@ void run(void) {
30 continue; 30 continue;
31 } 31 }
32 n = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL, 32 n = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL,
33 0, 20, nsol, -1, 0, size, buf, SOL_BUFFER_LEN, sol, stats); 33 0, 20, nsol, -1, 0, size, buf, SOL_BUFFER_LEN, sol, stats,
34 NULL, NULL);
34 if (n == 0) 35 if (n == 0)
35 printf("No solution found\n"); 36 printf("No solution found\n");
36 else 37 else
diff --git a/tools/400_solvetest/solve_test.c b/tools/400_solvetest/solve_test.c
index 1bfe851..73e6e8e 100644
--- a/tools/400_solvetest/solve_test.c
+++ b/tools/400_solvetest/solve_test.c
@@ -57,7 +57,8 @@ void run(void) {
57 continue; 57 continue;
58 } 58 }
59 n = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL, 59 n = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL,
60 0, 20, 1, -1, 0, size, buf, SOL_BUFFER_LEN, sol, stats); 60 0, 20, 1, -1, 0, size, buf, SOL_BUFFER_LEN, sol, stats,
61 NULL, NULL);
61 if (n == 0) { 62 if (n == 0) {
62 printf("Error: no solution\n"); 63 printf("Error: no solution\n");
63 return; 64 return;
@@ -78,7 +79,8 @@ void run(void) {
78 continue; 79 continue;
79 } 80 }
80 n = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL, 81 n = nissy_solve(cube, solver, NISSY_NISSFLAG_NORMAL,
81 0, 20, 100, 0, 0, size, buf, SOL_BUFFER_LEN, sol, stats); 82 0, 20, 100, 0, 0, size, buf, SOL_BUFFER_LEN, sol, stats,
83 NULL, NULL);
82 if (check_all(sol, s[i].solutions)) { 84 if (check_all(sol, s[i].solutions)) {
83 printf("All solutions are correct\n"); 85 printf("All solutions are correct\n");
84 } else { 86 } else {

Generated with cgit - Back to sebastiano.tronto.net