diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-05-23 16:48:58 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-05-23 16:54:59 +0200 |
| commit | c6a77f30f64be73a5e55e06336975f2ecfbb2324 (patch) | |
| tree | 3c243fbee268b824f18c5dc4d5bff9a9413b9407 /src/solvers/h48/gendata_h48.h | |
| parent | 62d87e063318cc4c842b1b2d8c184f48aeaf6659 (diff) | |
| download | nissy-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.h | 42 |
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]) | |||
| 463 | STATIC void * | 491 | STATIC void * |
| 464 | gendata_h48k2_runthread(void *arg) | 492 | gendata_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; |
