aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48/gendata_h48.h
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-05-23 16:48:58 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2025-05-23 16:54:59 +0200
commitc6a77f30f64be73a5e55e06336975f2ecfbb2324 (patch)
tree3c243fbee268b824f18c5dc4d5bff9a9413b9407 /src/solvers/h48/gendata_h48.h
parent62d87e063318cc4c842b1b2d8c184f48aeaf6659 (diff)
downloadnissy-core-c6a77f30f64be73a5e55e06336975f2ecfbb2324.tar.gz
nissy-core-c6a77f30f64be73a5e55e06336975f2ecfbb2324.zip
Do all loggin in main thread
Before this committ, the solver (via the generic solution-appender routines in src/solve/solutions.h) and the H48 data generator did some logging in the worker threads, without using any locks. This was not nice, but in practice it did not cause any problem, because the log messages were rare. However, this turned out to be a problem when building to WASM, because web workers do not have access to the main JS memory, and therefore they cannot call functions from the main JS. This includes not only the callback functions for logging, but also those for polling the status of the solver (run / pause / stop). This commit fixes this at the cost or being somewhat inelegant: the solutions are not logged as they are found, but only every 500ms.
Diffstat (limited to 'src/solvers/h48/gendata_h48.h')
-rw-r--r--src/solvers/h48/gendata_h48.h42
1 files changed, 33 insertions, 9 deletions
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h
index d1ab3bd..4e5daee 100644
--- a/src/solvers/h48/gendata_h48.h
+++ b/src/solvers/h48/gendata_h48.h
@@ -105,7 +105,7 @@ gendata_h48(gendata_h48_arg_t arg[static 1])
105 return size; /* Dry-run */ 105 return size; /* Dry-run */
106 106
107 if (arg->buf_size < size) { 107 if (arg->buf_size < size) {
108 LOG("[H48 gendata] Error data: buffer is too small " 108 LOG("[H48 gendata] Error: buffer is too small "
109 "(needed %" PRId64 " bytes but received %" PRId64 ")\n", 109 "(needed %" PRId64 " bytes but received %" PRId64 ")\n",
110 size, arg->buf_size); 110 size, arg->buf_size);
111 return NISSY_ERROR_BUFFER_SIZE; 111 return NISSY_ERROR_BUFFER_SIZE;
@@ -392,9 +392,11 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
392 }; 392 };
393 393
394 uint8_t t; 394 uint8_t t;
395 int sleeptime;
395 unsigned char *table; 396 unsigned char *table;
396 int64_t j; 397 int64_t j;
397 uint64_t i, ii, inext, count, bufsize; 398 _Atomic uint64_t count;
399 uint64_t i, ii, inext, bufsize, done, nshort, velocity;
398 h48map_t shortcubes; 400 h48map_t shortcubes;
399 gendata_h48short_arg_t shortarg; 401 gendata_h48short_arg_t shortarg;
400 h48k2_dfs_arg_t dfsarg[THREADS]; 402 h48k2_dfs_arg_t dfsarg[THREADS];
@@ -414,7 +416,8 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
414 .map = &shortcubes 416 .map = &shortcubes
415 }; 417 };
416 gendata_h48short(&shortarg); 418 gendata_h48short(&shortarg);
417 LOG("[H48 gendata] Computed %" PRIu64 " positions\n", shortarg.map->n); 419 nshort = shortarg.map->n;
420 LOG("[H48 gendata] Computed %" PRIu64 " positions\n", nshort);
418 421
419 if (arg->base >= 20) 422 if (arg->base >= 20)
420 arg->base = base[arg->h]; 423 arg->base = base[arg->h];
@@ -446,6 +449,31 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
446 &thread[i], NULL, gendata_h48k2_runthread, &dfsarg[i]); 449 &thread[i], NULL, gendata_h48k2_runthread, &dfsarg[i]);
447 } 450 }
448 451
452 if (NISSY_CANSLEEP) {
453 /* Log the progress periodically */
454 LOG("Processing 'short cubes'. This will take a while.\n");
455
456 /* Estimate velocity by checking how much is done after 1s */
457 msleep(1000);
458 velocity = count;
459
460 /* We plan to log 10 times */
461 sleeptime = (100*(nshort-velocity)) / velocity;
462
463 done = count;
464 while (nshort - done > (velocity * sleeptime) / 1000) {
465 msleep(sleeptime);
466 pthread_mutex_lock(&shortcubes_mutex);
467 done = count;
468 pthread_mutex_unlock(&shortcubes_mutex);
469 LOG("Processed %" PRIu64 " / %" PRIu64 " cubes\n",
470 (done / 1000) * 1000, nshort);
471 }
472 } else {
473 LOG("Status updates won't be available because the sleep() "
474 "functionality is not available on this platform.\n");
475 }
476
449 for (i = 0; i < THREADS; i++) 477 for (i = 0; i < THREADS; i++)
450 pthread_join(thread[i], NULL); 478 pthread_join(thread[i], NULL);
451 479
@@ -463,7 +491,7 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
463STATIC void * 491STATIC void *
464gendata_h48k2_runthread(void *arg) 492gendata_h48k2_runthread(void *arg)
465{ 493{
466 uint64_t count, coord, mutex; 494 uint64_t coord, mutex;
467 kvpair_t kv; 495 kvpair_t kv;
468 h48k2_dfs_arg_t *dfsarg; 496 h48k2_dfs_arg_t *dfsarg;
469 497
@@ -477,13 +505,9 @@ gendata_h48k2_runthread(void *arg)
477 pthread_mutex_unlock(dfsarg->shortcubes_mutex); 505 pthread_mutex_unlock(dfsarg->shortcubes_mutex);
478 break; 506 break;
479 } 507 }
480 count = ++(*dfsarg->count); 508 (*dfsarg->count)++;
481 pthread_mutex_unlock(dfsarg->shortcubes_mutex); 509 pthread_mutex_unlock(dfsarg->shortcubes_mutex);
482 510
483 if (count % UINT64_C(1000000) == 0)
484 LOG("[H48 gendata] Processing %" PRIu64
485 "th short cube\n", count);
486
487 if (kv.val < dfsarg->shortdepth) { 511 if (kv.val < dfsarg->shortdepth) {
488 coord = kv.key >> (int64_t)(11 - dfsarg->h); 512 coord = kv.key >> (int64_t)(11 - dfsarg->h);
489 mutex = H48_INDEX(coord, dfsarg->k) % CHUNKS; 513 mutex = H48_INDEX(coord, dfsarg->k) % CHUNKS;

Generated with cgit - Back to sebastiano.tronto.net