diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2024-10-05 23:00:08 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2024-10-05 23:00:08 +0200 |
| commit | 1272e304b6367c7dd94d25acf88b2843adabb93a (patch) | |
| tree | e269e86cf131f3d5ed7c03a201418804257be06d | |
| parent | 6f338b97a222dee630c9b13896cf443254667dfb (diff) | |
| download | nissy-core-1272e304b6367c7dd94d25acf88b2843adabb93a.tar.gz nissy-core-1272e304b6367c7dd94d25acf88b2843adabb93a.zip | |
Fix rare data race
I had some misconception about how _Atomic and const worked.
This means the previous commit (expected distribution) could
be incorrect.
Diffstat (limited to '')
| -rw-r--r-- | src/nissy.c | 2 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_cocsep.h | 5 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_h48.h | 45 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 4 | ||||
| -rw-r--r-- | src/solvers/h48/stats.h | 4 |
5 files changed, 30 insertions, 30 deletions
diff --git a/src/nissy.c b/src/nissy.c index 44efb83..561ef53 100644 --- a/src/nissy.c +++ b/src/nissy.c | |||
| @@ -75,7 +75,7 @@ checkdata(const void *buf, const tableinfo_t *info) | |||
| 75 | getdistribution_cocsep( | 75 | getdistribution_cocsep( |
| 76 | (uint32_t *)((char *)buf + INFOSIZE), distr); | 76 | (uint32_t *)((char *)buf + INFOSIZE), distr); |
| 77 | } else if (!strncmp(info->solver, "h48", 3)) { | 77 | } else if (!strncmp(info->solver, "h48", 3)) { |
| 78 | getdistribution_h48((uint8_t *)buf + INFOSIZE, distr, | 78 | getdistribution_h48((_Atomic uint8_t *)buf + INFOSIZE, distr, |
| 79 | info->h48h, info->bits); | 79 | info->h48h, info->bits); |
| 80 | } else { | 80 | } else { |
| 81 | LOG("checkdata: unknown solver %s\n", info->solver); | 81 | LOG("checkdata: unknown solver %s\n", info->solver); |
diff --git a/src/solvers/h48/gendata_cocsep.h b/src/solvers/h48/gendata_cocsep.h index a8142b4..fd483ce 100644 --- a/src/solvers/h48/gendata_cocsep.h +++ b/src/solvers/h48/gendata_cocsep.h | |||
| @@ -5,7 +5,8 @@ STATIC size_t gendata_cocsep(void *, uint64_t *, cube_t *); | |||
| 5 | STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t *); | 5 | STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t *); |
| 6 | STATIC void getdistribution_cocsep(const uint32_t *, uint64_t [static 21]); | 6 | STATIC void getdistribution_cocsep(const uint32_t *, uint64_t [static 21]); |
| 7 | 7 | ||
| 8 | STATIC_INLINE int8_t get_h48_cdata(cube_t, const uint32_t *, uint32_t *); | 8 | STATIC_INLINE int8_t get_h48_cdata( |
| 9 | cube_t, _Atomic const uint32_t *, uint32_t *); | ||
| 9 | 10 | ||
| 10 | /* | 11 | /* |
| 11 | Each element of the cocsep table is a uint32_t used as follows: | 12 | Each element of the cocsep table is a uint32_t used as follows: |
| @@ -158,7 +159,7 @@ set_visited(uint8_t *a, int64_t i) | |||
| 158 | } | 159 | } |
| 159 | 160 | ||
| 160 | STATIC_INLINE int8_t | 161 | STATIC_INLINE int8_t |
| 161 | get_h48_cdata(cube_t cube, const uint32_t *cocsepdata, uint32_t *cdata) | 162 | get_h48_cdata(cube_t cube, _Atomic const uint32_t *cocsepdata, uint32_t *cdata) |
| 162 | { | 163 | { |
| 163 | int64_t coord; | 164 | int64_t coord; |
| 164 | 165 | ||
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h index 5da9dc3..17c594f 100644 --- a/src/solvers/h48/gendata_h48.h +++ b/src/solvers/h48/gendata_h48.h | |||
| @@ -28,16 +28,16 @@ STATIC size_t gendata_h48k2_realcoord(gendata_h48_arg_t *); | |||
| 28 | STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); | 28 | STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); |
| 29 | STATIC void * gendata_h48k2_runthread(void *); | 29 | STATIC void * gendata_h48k2_runthread(void *); |
| 30 | STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *); | 30 | STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *); |
| 31 | STATIC void getdistribution_h48(const uint8_t *, | 31 | STATIC void getdistribution_h48(_Atomic const uint8_t *, |
| 32 | uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t); | 32 | uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t); |
| 33 | 33 | ||
| 34 | STATIC const uint32_t *get_cocsepdata_constptr(const void *); | 34 | STATIC _Atomic const uint32_t *get_cocsepdata_constptr(const void *); |
| 35 | STATIC const uint8_t *get_h48data_constptr(const void *); | 35 | STATIC _Atomic const uint8_t *get_h48data_constptr(const void *); |
| 36 | 36 | ||
| 37 | STATIC_INLINE uint8_t get_h48_pval(const uint8_t *, int64_t, uint8_t); | 37 | STATIC_INLINE uint8_t get_h48_pval(_Atomic const uint8_t *, int64_t, uint8_t); |
| 38 | STATIC_INLINE void set_h48_pval(_Atomic uint8_t *, int64_t, uint8_t, uint8_t); | 38 | STATIC_INLINE void set_h48_pval(_Atomic uint8_t *, int64_t, uint8_t, uint8_t); |
| 39 | STATIC_INLINE uint8_t get_h48_bound( | 39 | STATIC_INLINE uint8_t get_h48_bound( |
| 40 | cube_t, uint32_t, uint8_t, uint8_t, const uint8_t *); | 40 | cube_t, uint32_t, uint8_t, uint8_t, _Atomic const uint8_t *); |
| 41 | 41 | ||
| 42 | size_t gendata_h48_derive(uint8_t, const void *, void *); | 42 | size_t gendata_h48_derive(uint8_t, const void *, void *); |
| 43 | 43 | ||
| @@ -196,7 +196,7 @@ gendata_h48h0k4(gendata_h48_arg_t *arg) | |||
| 196 | pthread_join(thread[t], NULL); | 196 | pthread_join(thread[t], NULL); |
| 197 | 197 | ||
| 198 | for (i = 0, cc = 0; i < h48max; i++) { | 198 | for (i = 0, cc = 0; i < h48max; i++) { |
| 199 | val = get_h48_pval((uint8_t *)table, i, 4); | 199 | val = get_h48_pval(table, i, 4); |
| 200 | cc += val == d; | 200 | cc += val == d; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| @@ -242,7 +242,7 @@ gendata_h48h0k4_runthread(void *arg) | |||
| 242 | * Otherwise, scan all neighbors of unvisited coordinates. | 242 | * Otherwise, scan all neighbors of unvisited coordinates. |
| 243 | */ | 243 | */ |
| 244 | for (i = bfsarg->start; i < bfsarg->end; i++) { | 244 | for (i = bfsarg->start; i < bfsarg->end; i++) { |
| 245 | c = get_h48_pval((uint8_t *)bfsarg->table, i, 4); | 245 | c = get_h48_pval(bfsarg->table, i, 4); |
| 246 | 246 | ||
| 247 | if ((bfsarg->depth < breakpoint && c != bfsarg->depth - 1) || | 247 | if ((bfsarg->depth < breakpoint && c != bfsarg->depth - 1) || |
| 248 | (bfsarg->depth >= breakpoint && c != 0xF)) | 248 | (bfsarg->depth >= breakpoint && c != 0xF)) |
| @@ -252,7 +252,7 @@ gendata_h48h0k4_runthread(void *arg) | |||
| 252 | for (m = 0; m < 18; m++) { | 252 | for (m = 0; m < 18; m++) { |
| 253 | moved = move(cube, m); | 253 | moved = move(cube, m); |
| 254 | j = coord_h48(moved, bfsarg->cocsepdata, 0); | 254 | j = coord_h48(moved, bfsarg->cocsepdata, 0); |
| 255 | c = get_h48_pval((uint8_t *)bfsarg->table, j, 4); | 255 | c = get_h48_pval(bfsarg->table, j, 4); |
| 256 | if (bfsarg->depth < breakpoint) { | 256 | if (bfsarg->depth < breakpoint) { |
| 257 | if (c <= bfsarg->depth) | 257 | if (c <= bfsarg->depth) |
| 258 | continue; | 258 | continue; |
| @@ -356,7 +356,7 @@ gendata_h48k2(gendata_h48_arg_t *arg) | |||
| 356 | h48map_destroy(&shortcubes); | 356 | h48map_destroy(&shortcubes); |
| 357 | 357 | ||
| 358 | for (j = 0; j < H48_COORDMAX(arg->h); j++) { | 358 | for (j = 0; j < H48_COORDMAX(arg->h); j++) { |
| 359 | t = get_h48_pval((uint8_t *)table, j, 2); | 359 | t = get_h48_pval(table, j, 2); |
| 360 | arg->info.distribution[t]++; | 360 | arg->info.distribution[t]++; |
| 361 | } | 361 | } |
| 362 | 362 | ||
| @@ -491,7 +491,7 @@ gendata_h48_mark(gendata_h48_mark_t *arg) | |||
| 491 | 491 | ||
| 492 | FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim, | 492 | FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim, |
| 493 | coord = coord_h48(arg->cube, arg->cocsepdata, arg->h); | 493 | coord = coord_h48(arg->cube, arg->cocsepdata, arg->h); |
| 494 | oldval = get_h48_pval((uint8_t *)arg->table, coord, arg->k); | 494 | oldval = get_h48_pval(arg->table, coord, arg->k); |
| 495 | newval = (uint8_t)MAX(arg->depth, 0); | 495 | newval = (uint8_t)MAX(arg->depth, 0); |
| 496 | if (newval < oldval) { | 496 | if (newval < oldval) { |
| 497 | mutex = H48_INDEX(coord, arg->k) % CHUNKS; | 497 | mutex = H48_INDEX(coord, arg->k) % CHUNKS; |
| @@ -515,7 +515,7 @@ gendata_h48k2_dfs_stop(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg) | |||
| 515 | coord = coord_h48(cube, arg->cocsepdata, arg->h); | 515 | coord = coord_h48(cube, arg->cocsepdata, arg->h); |
| 516 | mutex = H48_INDEX(coord, arg->k) % CHUNKS; | 516 | mutex = H48_INDEX(coord, arg->k) % CHUNKS; |
| 517 | pthread_mutex_lock(arg->table_mutex[mutex]); | 517 | pthread_mutex_lock(arg->table_mutex[mutex]); |
| 518 | oldval = get_h48_pval((uint8_t *)arg->table, coord, arg->k); | 518 | oldval = get_h48_pval(arg->table, coord, arg->k); |
| 519 | pthread_mutex_unlock(arg->table_mutex[mutex]); | 519 | pthread_mutex_unlock(arg->table_mutex[mutex]); |
| 520 | return oldval <= depth; | 520 | return oldval <= depth; |
| 521 | } else { | 521 | } else { |
| @@ -570,7 +570,7 @@ makeinfo_h48k2(gendata_h48_arg_t *arg) | |||
| 570 | 570 | ||
| 571 | STATIC void | 571 | STATIC void |
| 572 | getdistribution_h48( | 572 | getdistribution_h48( |
| 573 | const uint8_t *table, | 573 | _Atomic const uint8_t *table, |
| 574 | uint64_t distr[static INFO_DISTRIBUTION_LEN], | 574 | uint64_t distr[static INFO_DISTRIBUTION_LEN], |
| 575 | uint8_t h, | 575 | uint8_t h, |
| 576 | uint8_t k | 576 | uint8_t k |
| @@ -587,20 +587,20 @@ getdistribution_h48( | |||
| 587 | } | 587 | } |
| 588 | } | 588 | } |
| 589 | 589 | ||
| 590 | STATIC const uint32_t * | 590 | STATIC _Atomic const uint32_t * |
| 591 | get_cocsepdata_constptr(const void *data) | 591 | get_cocsepdata_constptr(const void *data) |
| 592 | { | 592 | { |
| 593 | return (uint32_t *)((char *)data + INFOSIZE); | 593 | return (_Atomic uint32_t *)((char *)data + INFOSIZE); |
| 594 | } | 594 | } |
| 595 | 595 | ||
| 596 | STATIC const uint8_t * | 596 | STATIC _Atomic const uint8_t * |
| 597 | get_h48data_constptr(const void *data) | 597 | get_h48data_constptr(const void *data) |
| 598 | { | 598 | { |
| 599 | return (uint8_t *)data + COCSEP_FULLSIZE + INFOSIZE; | 599 | return (_Atomic uint8_t *)data + COCSEP_FULLSIZE + INFOSIZE; |
| 600 | } | 600 | } |
| 601 | 601 | ||
| 602 | STATIC_INLINE uint8_t | 602 | STATIC_INLINE uint8_t |
| 603 | get_h48_pval(const uint8_t *table, int64_t i, uint8_t k) | 603 | get_h48_pval(_Atomic const uint8_t *table, int64_t i, uint8_t k) |
| 604 | { | 604 | { |
| 605 | return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k); | 605 | return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k); |
| 606 | } | 606 | } |
| @@ -618,7 +618,7 @@ get_h48_bound( | |||
| 618 | uint32_t cdata, | 618 | uint32_t cdata, |
| 619 | uint8_t h, | 619 | uint8_t h, |
| 620 | uint8_t k, | 620 | uint8_t k, |
| 621 | const uint8_t *table | 621 | _Atomic const uint8_t *table |
| 622 | ) { | 622 | ) { |
| 623 | int64_t coord; | 623 | int64_t coord; |
| 624 | 624 | ||
| @@ -631,7 +631,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf) | |||
| 631 | { | 631 | { |
| 632 | size_t cocsepsize, h48size; | 632 | size_t cocsepsize, h48size; |
| 633 | uint8_t val_full, val_derive; | 633 | uint8_t val_full, val_derive; |
| 634 | const uint8_t *h48full; | 634 | _Atomic const uint8_t *h48full; |
| 635 | _Atomic uint8_t *h48derive; | 635 | _Atomic uint8_t *h48derive; |
| 636 | int64_t i, j, h48max; | 636 | int64_t i, j, h48max; |
| 637 | gendata_h48_arg_t arg; | 637 | gendata_h48_arg_t arg; |
| @@ -672,7 +672,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf) | |||
| 672 | goto gendata_h48_derive_error; | 672 | goto gendata_h48_derive_error; |
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | h48full = (const uint8_t *)fulltable + cocsepsize + INFOSIZE; | 675 | h48full = (_Atomic const uint8_t *)fulltable + cocsepsize + INFOSIZE; |
| 676 | h48derive = (_Atomic uint8_t *)arg.h48buf + INFOSIZE; | 676 | h48derive = (_Atomic uint8_t *)arg.h48buf + INFOSIZE; |
| 677 | memset(h48derive, 0xFF, H48_TABLESIZE(h, arg.k)); | 677 | memset(h48derive, 0xFF, H48_TABLESIZE(h, arg.k)); |
| 678 | memset(arg.info.distribution, 0, | 678 | memset(arg.info.distribution, 0, |
| @@ -684,13 +684,12 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf) | |||
| 684 | LOG("Processing %" PRId64 "th coordinate\n", i); | 684 | LOG("Processing %" PRId64 "th coordinate\n", i); |
| 685 | j = i >> (int64_t)(fulltableinfo.h48h - h); | 685 | j = i >> (int64_t)(fulltableinfo.h48h - h); |
| 686 | val_full = get_h48_pval(h48full, i, arg.k); | 686 | val_full = get_h48_pval(h48full, i, arg.k); |
| 687 | val_derive = get_h48_pval((uint8_t *)h48derive, j, arg.k); | 687 | val_derive = get_h48_pval(h48derive, j, arg.k); |
| 688 | set_h48_pval( | 688 | set_h48_pval( |
| 689 | h48derive, j, arg.k, MIN(val_full, val_derive)); | 689 | h48derive, j, arg.k, MIN(val_full, val_derive)); |
| 690 | } | 690 | } |
| 691 | 691 | ||
| 692 | getdistribution_h48( | 692 | getdistribution_h48(h48derive, arg.info.distribution, h, arg.k); |
| 693 | (uint8_t *)h48derive, arg.info.distribution, h, arg.k); | ||
| 694 | 693 | ||
| 695 | if (!writetableinfo(&arg.info, arg.h48buf)) { | 694 | if (!writetableinfo(&arg.info, arg.h48buf)) { |
| 696 | LOG("gendata_h48_derive: could not write info for table\n"); | 695 | LOG("gendata_h48_derive: could not write info for table\n"); |
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index 3948b15..c6fe8b7 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -8,8 +8,8 @@ typedef struct { | |||
| 8 | int64_t maxsolutions; | 8 | int64_t maxsolutions; |
| 9 | uint8_t h; | 9 | uint8_t h; |
| 10 | uint8_t k; | 10 | uint8_t k; |
| 11 | const uint32_t *cocsepdata; | 11 | _Atomic const uint32_t *cocsepdata; |
| 12 | const uint8_t *h48data; | 12 | _Atomic const uint8_t *h48data; |
| 13 | char **nextsol; | 13 | char **nextsol; |
| 14 | uint8_t nissbranch; | 14 | uint8_t nissbranch; |
| 15 | int8_t npremoves; | 15 | int8_t npremoves; |
diff --git a/src/solvers/h48/stats.h b/src/solvers/h48/stats.h index ca4b72e..5f96189 100644 --- a/src/solvers/h48/stats.h +++ b/src/solvers/h48/stats.h | |||
| @@ -10,8 +10,8 @@ typedef struct { | |||
| 10 | int8_t nmoves; | 10 | int8_t nmoves; |
| 11 | int8_t depth; | 11 | int8_t depth; |
| 12 | uint8_t moves[MAXLEN]; | 12 | uint8_t moves[MAXLEN]; |
| 13 | const uint32_t *cocsepdata; | 13 | _Atomic const uint32_t *cocsepdata; |
| 14 | const uint8_t *h48data; | 14 | _Atomic const uint8_t *h48data; |
| 15 | char *s; | 15 | char *s; |
| 16 | } dfsarg_solveh48stats_t; | 16 | } dfsarg_solveh48stats_t; |
| 17 | 17 | ||
