aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48
diff options
context:
space:
mode:
Diffstat (limited to 'src/solvers/h48')
-rw-r--r--src/solvers/h48/solve.h69
1 files changed, 64 insertions, 5 deletions
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:

Generated with cgit - Back to sebastiano.tronto.net