aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48/solve.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/solvers/h48/solve.h')
-rw-r--r--src/solvers/h48/solve.h136
1 files changed, 79 insertions, 57 deletions
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h
index 2818c09..4d3c451 100644
--- a/src/solvers/h48/solve.h
+++ b/src/solvers/h48/solve.h
@@ -35,10 +35,8 @@ 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 *); 38 _Atomic int *status;
39 void *poll_status_data; 39 _Atomic bool thread_done;
40 _Atomic bool cancelled;
41 _Atomic bool cantsleep;
42} dfsarg_solve_h48_t; 40} dfsarg_solve_h48_t;
43 41
44typedef struct { 42typedef struct {
@@ -58,9 +56,9 @@ STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t [static 1]);
58STATIC int64_t solve_h48_maketasks( 56STATIC int64_t solve_h48_maketasks(
59 dfsarg_solve_h48_t [static 1], dfsarg_solve_h48_maketasks_t [static 1], 57 dfsarg_solve_h48_t [static 1], dfsarg_solve_h48_maketasks_t [static 1],
60 solve_h48_task_t [static STARTING_CUBES], int [static 1]); 58 solve_h48_task_t [static STARTING_CUBES], int [static 1]);
61STATIC bool solve_h48_runthread_continue(dfsarg_solve_h48_t *);
62STATIC void *solve_h48_runthread(void *); 59STATIC void *solve_h48_runthread(void *);
63STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); 60STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]);
61STATIC void solve_h48_log_solutions(solution_list_t [static 1], size_t);
64STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t, 62STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t,
65 uint8_t, uint64_t, const unsigned char *, size_t n, char [n], 63 uint8_t, uint64_t, const unsigned char *, size_t n, char [n],
66 long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *); 64 long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *);
@@ -201,7 +199,7 @@ solve_h48_dfs(dfsarg_solve_h48_t arg[static 1])
201 return 0; 199 return 0;
202 pthread_mutex_lock(arg->solutions_mutex); 200 pthread_mutex_lock(arg->solutions_mutex);
203 ret = appendsolution(arg->solution_moves, 201 ret = appendsolution(arg->solution_moves,
204 arg->solution_settings, arg->solution_list, true, "H48"); 202 arg->solution_settings, arg->solution_list);
205 pthread_mutex_unlock(arg->solutions_mutex); 203 pthread_mutex_unlock(arg->solutions_mutex);
206 return ret; 204 return ret;
207 } 205 }
@@ -271,41 +269,20 @@ solve_h48_dfs(dfsarg_solve_h48_t arg[static 1])
271 return ret; 269 return ret;
272} 270}
273 271
274STATIC bool
275solve_h48_runthread_continue(dfsarg_solve_h48_t *arg)
276{
277 int status;
278
279 for (status = NISSY_STATUS_PAUSE; status == NISSY_STATUS_PAUSE; ) {
280 status = arg->poll_status == NULL ? NISSY_STATUS_RUN :
281 arg->poll_status(arg->poll_status_data);
282 msleep(500);
283 }
284
285 return status == NISSY_STATUS_RUN;
286}
287
288STATIC void * 272STATIC void *
289solve_h48_runthread(void *arg) 273solve_h48_runthread(void *arg)
290{ 274{
291 int i, j, status; 275 int i, j;
292 solve_h48_task_t task; 276 solve_h48_task_t task;
293 dfsarg_solve_h48_t *dfsarg; 277 dfsarg_solve_h48_t *dfsarg;
294 278
295 dfsarg = (dfsarg_solve_h48_t *)arg; 279 dfsarg = (dfsarg_solve_h48_t *)arg;
296 280
297 for (i = dfsarg->thread_id; i < dfsarg->ntasks; i += dfsarg->threads) { 281 for (i = dfsarg->thread_id; i < dfsarg->ntasks; i += dfsarg->threads) {
298 status = dfsarg->poll_status == NULL ? NISSY_STATUS_RUN : 282 if (*dfsarg->status == NISSY_STATUS_STOP)
299 dfsarg->poll_status(dfsarg->poll_status_data); 283 goto solve_h48_runthread_end;
300 switch (status) { 284 while (*dfsarg->status == NISSY_STATUS_PAUSE)
301 case NISSY_STATUS_STOP: 285 msleep(BASE_SLEEP_TIME);
302 goto solve_h48_runthread_cancel;
303 case NISSY_STATUS_PAUSE:
304 if (!NISSY_CANSLEEP)
305 goto solve_h48_runthread_cantsleep;
306 if (!solve_h48_runthread_continue(dfsarg))
307 goto solve_h48_runthread_cancel;
308 }
309 286
310 task = dfsarg->tasks[i]; 287 task = dfsarg->tasks[i];
311 288
@@ -329,12 +306,8 @@ solve_h48_runthread(void *arg)
329 solve_h48_dfs(dfsarg); 306 solve_h48_dfs(dfsarg);
330 } 307 }
331 308
332 return NULL; 309solve_h48_runthread_end:
333 310 dfsarg->thread_done = true;
334solve_h48_runthread_cantsleep:
335 dfsarg->cantsleep = true;
336solve_h48_runthread_cancel:
337 dfsarg->cancelled = true;
338 return NULL; 311 return NULL;
339} 312}
340 313
@@ -366,7 +339,7 @@ solve_h48_maketasks(
366 maketasks_arg->moves, maketasks_arg->nmoves); 339 maketasks_arg->moves, maketasks_arg->nmoves);
367 340
368 appret = appendsolution(&moves, solve_arg->solution_settings, 341 appret = appendsolution(&moves, solve_arg->solution_settings,
369 solve_arg->solution_list, true, "H48"); 342 solve_arg->solution_list);
370 return appret < 0 ? appret : NISSY_OK; 343 return appret < 0 ? appret : NISSY_OK;
371 } 344 }
372 345
@@ -410,6 +383,22 @@ solve_h48_maketasks(
410 return NISSY_OK; 383 return NISSY_OK;
411} 384}
412 385
386STATIC void
387solve_h48_log_solutions(solution_list_t s[static 1], size_t e)
388{
389 size_t i;
390 char b;
391 while (e != s->used) {
392 LOG("[h48 solve] Found solution: ");
393 for (i = e; s->buf[i] != '\n' && s->buf[i] != '\0'; i++) ;
394 b = s->buf[i];
395 s->buf[i] = '\0';
396 LOG("%s\n", s->buf + e);
397 s->buf[i] = b;
398 e = i + 1;
399 }
400}
401
413STATIC int64_t 402STATIC int64_t
414solve_h48( 403solve_h48(
415 oriented_cube_t oc, 404 oriented_cube_t oc,
@@ -427,8 +416,10 @@ solve_h48(
427 void *poll_status_data 416 void *poll_status_data
428) 417)
429{ 418{
430 bool anycancelled, anycantsleep;
431 int i, ntasks, eoesep_table_index; 419 int i, ntasks, eoesep_table_index;
420 bool td, fp;
421 _Atomic int status;
422 size_t lastused;
432 int8_t d; 423 int8_t d;
433 dfsarg_solve_h48_t arg[THREADS]; 424 dfsarg_solve_h48_t arg[THREADS];
434 solve_h48_task_t tasks[STARTING_CUBES]; 425 solve_h48_task_t tasks[STARTING_CUBES];
@@ -508,10 +499,7 @@ solve_h48(
508 .threads = threads, 499 .threads = threads,
509 .thread_id = i, 500 .thread_id = i,
510 .solutions_mutex = &solutions_mutex, 501 .solutions_mutex = &solutions_mutex,
511 .poll_status = poll_status, 502 .status = &status,
512 .poll_status_data = poll_status_data,
513 .cancelled = false,
514 .cantsleep = false,
515 }; 503 };
516 504
517 } 505 }
@@ -538,35 +526,69 @@ solve_h48(
538 526
539 LOG("[H48 solve] Prepared %d tasks\n", ntasks); 527 LOG("[H48 solve] Prepared %d tasks\n", ntasks);
540 528
541 anycancelled = anycantsleep = false; 529 solve_h48_log_solutions(&sollist, 0);
530 lastused = sollist.used;
531 status = poll_status == NULL ? NISSY_STATUS_RUN :
532 poll_status(poll_status_data);
533 if (!NISSY_CANSLEEP) {
534 LOG("[solve h48] Pause / Stop / Resume functionality won't "
535 "be available on this system (can't sleep()).\n");
536 }
542 for ( 537 for (
543 d = MAX(minmoves, STARTING_MOVES + 1); 538 d = MAX(minmoves, STARTING_MOVES + 1);
544 !(solutions_done(&sollist, &settings, d) || anycancelled); 539 !(solutions_done(&sollist, &settings, d)) &&
540 status != NISSY_STATUS_STOP;
545 d++ 541 d++
546 ) { 542 ) {
547 if (d >= 15) 543 if (d >= 15) {
548 LOG("[H48 solve] Found %" PRId64 " solutions, " 544 LOG("[H48 solve] Found %" PRId64 " solutions, "
549 "searching at depth %" PRId8 "\n", 545 "searching at depth %" PRId8 "\n",
550 sollist.nsols, d); 546 sollist.nsols, d);
547 }
548
551 for (i = 0; i < threads; i++) { 549 for (i = 0; i < threads; i++) {
552 arg[i].target_depth = d; 550 arg[i].target_depth = d;
551 arg[i].thread_done = false;
553 pthread_create( 552 pthread_create(
554 &thread[i], NULL, solve_h48_runthread, &arg[i]); 553 &thread[i], NULL, solve_h48_runthread, &arg[i]);
555 } 554 }
556 for (i = 0; i < threads; i++) { 555
557 pthread_join(thread[i], NULL); 556 /* Log solutions and handle pause / stop / resume */
558 anycancelled = anycancelled || arg[i].cancelled; 557 if (d >= 15 && NISSY_CANSLEEP) {
559 anycantsleep = anycantsleep || arg[i].cantsleep; 558 td = false;
559 fp = true;
560 while (!td && status != NISSY_STATUS_STOP) {
561 msleep(BASE_SLEEP_TIME);
562
563 pthread_mutex_lock(&solutions_mutex);
564 solve_h48_log_solutions(&sollist, lastused);
565 lastused = sollist.used;
566 pthread_mutex_unlock(&solutions_mutex);
567
568 if (poll_status == NULL)
569 continue;
570
571 status = poll_status(poll_status_data);
572 if (status == NISSY_STATUS_PAUSE && fp) {
573 LOG("[H48 solve] Paused\n");
574 fp = false;
575 }
576 if (status == NISSY_STATUS_RUN)
577 fp = true;
578
579 for (td = true, i = 0; i < threads; i++)
580 td = td && arg[i].thread_done;
581 }
560 } 582 }
561 }
562 583
563 if (anycantsleep) { 584 for (i = 0; i < threads; i++)
564 LOG("[H48 solve] Received pause request, but this feature is " 585 pthread_join(thread[i], NULL);
565 "not available on this system. " 586
566 "Taking it as a stop request.\n"); 587 solve_h48_log_solutions(&sollist, lastused);
588 lastused = sollist.used;
567 } 589 }
568 590
569 if (anycancelled) { 591 if (status == NISSY_STATUS_STOP) {
570 LOG("[H48 solve] Received stop request, ending solution " 592 LOG("[H48 solve] Received stop request, ending solution "
571 "search early.\n"); 593 "search early.\n");
572 } 594 }

Generated with cgit - Back to sebastiano.tronto.net