diff options
Diffstat (limited to 'src/solvers/h48')
| -rw-r--r-- | src/solvers/h48/solve.h | 69 |
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 | ||
| 40 | typedef struct { | 44 | typedef struct { |
| @@ -50,11 +54,12 @@ STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t [static 1]); | |||
| 50 | STATIC int64_t solve_h48_maketasks( | 54 | STATIC 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]); |
| 57 | STATIC bool solve_h48_runthread_continue(dfsarg_solve_h48_t *); | ||
| 53 | STATIC void *solve_h48_runthread(void *); | 58 | STATIC void *solve_h48_runthread(void *); |
| 54 | STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); | 59 | STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); |
| 55 | STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t, | 60 | STATIC 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 | ||
| 59 | STATIC_INLINE bool | 64 | STATIC_INLINE bool |
| 60 | solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) | 65 | solve_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 | ||
| 240 | STATIC bool | ||
| 241 | solve_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 | |||
| 235 | STATIC void * | 254 | STATIC void * |
| 236 | solve_h48_runthread(void *arg) | 255 | solve_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 | |||
| 300 | solve_h48_runthread_cantsleep: | ||
| 301 | dfsarg->cantsleep = true; | ||
| 302 | solve_h48_runthread_cancel: | ||
| 303 | dfsarg->cancelled = true; | ||
| 304 | return NULL; | ||
| 268 | } | 305 | } |
| 269 | 306 | ||
| 270 | STATIC int64_t | 307 | STATIC 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 | ||
| 481 | solve_h48_done: | 540 | solve_h48_done: |
