commit 1272e304b6367c7dd94d25acf88b2843adabb93a
parent 6f338b97a222dee630c9b13896cf443254667dfb
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Sat, 5 Oct 2024 23:00:08 +0200
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:
5 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/src/nissy.c b/src/nissy.c
@@ -75,7 +75,7 @@ checkdata(const void *buf, const tableinfo_t *info)
getdistribution_cocsep(
(uint32_t *)((char *)buf + INFOSIZE), distr);
} else if (!strncmp(info->solver, "h48", 3)) {
- getdistribution_h48((uint8_t *)buf + INFOSIZE, distr,
+ getdistribution_h48((_Atomic uint8_t *)buf + INFOSIZE, distr,
info->h48h, info->bits);
} else {
LOG("checkdata: unknown solver %s\n", info->solver);
diff --git 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 *);
STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t *);
STATIC void getdistribution_cocsep(const uint32_t *, uint64_t [static 21]);
-STATIC_INLINE int8_t get_h48_cdata(cube_t, const uint32_t *, uint32_t *);
+STATIC_INLINE int8_t get_h48_cdata(
+ cube_t, _Atomic const uint32_t *, uint32_t *);
/*
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)
}
STATIC_INLINE int8_t
-get_h48_cdata(cube_t cube, const uint32_t *cocsepdata, uint32_t *cdata)
+get_h48_cdata(cube_t cube, _Atomic const uint32_t *cocsepdata, uint32_t *cdata)
{
int64_t coord;
diff --git 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 *);
STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg);
STATIC void * gendata_h48k2_runthread(void *);
STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *);
-STATIC void getdistribution_h48(const uint8_t *,
+STATIC void getdistribution_h48(_Atomic const uint8_t *,
uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t);
-STATIC const uint32_t *get_cocsepdata_constptr(const void *);
-STATIC const uint8_t *get_h48data_constptr(const void *);
+STATIC _Atomic const uint32_t *get_cocsepdata_constptr(const void *);
+STATIC _Atomic const uint8_t *get_h48data_constptr(const void *);
-STATIC_INLINE uint8_t get_h48_pval(const uint8_t *, int64_t, uint8_t);
+STATIC_INLINE uint8_t get_h48_pval(_Atomic const uint8_t *, int64_t, uint8_t);
STATIC_INLINE void set_h48_pval(_Atomic uint8_t *, int64_t, uint8_t, uint8_t);
STATIC_INLINE uint8_t get_h48_bound(
- cube_t, uint32_t, uint8_t, uint8_t, const uint8_t *);
+ cube_t, uint32_t, uint8_t, uint8_t, _Atomic const uint8_t *);
size_t gendata_h48_derive(uint8_t, const void *, void *);
@@ -196,7 +196,7 @@ gendata_h48h0k4(gendata_h48_arg_t *arg)
pthread_join(thread[t], NULL);
for (i = 0, cc = 0; i < h48max; i++) {
- val = get_h48_pval((uint8_t *)table, i, 4);
+ val = get_h48_pval(table, i, 4);
cc += val == d;
}
@@ -242,7 +242,7 @@ gendata_h48h0k4_runthread(void *arg)
* Otherwise, scan all neighbors of unvisited coordinates.
*/
for (i = bfsarg->start; i < bfsarg->end; i++) {
- c = get_h48_pval((uint8_t *)bfsarg->table, i, 4);
+ c = get_h48_pval(bfsarg->table, i, 4);
if ((bfsarg->depth < breakpoint && c != bfsarg->depth - 1) ||
(bfsarg->depth >= breakpoint && c != 0xF))
@@ -252,7 +252,7 @@ gendata_h48h0k4_runthread(void *arg)
for (m = 0; m < 18; m++) {
moved = move(cube, m);
j = coord_h48(moved, bfsarg->cocsepdata, 0);
- c = get_h48_pval((uint8_t *)bfsarg->table, j, 4);
+ c = get_h48_pval(bfsarg->table, j, 4);
if (bfsarg->depth < breakpoint) {
if (c <= bfsarg->depth)
continue;
@@ -356,7 +356,7 @@ gendata_h48k2(gendata_h48_arg_t *arg)
h48map_destroy(&shortcubes);
for (j = 0; j < H48_COORDMAX(arg->h); j++) {
- t = get_h48_pval((uint8_t *)table, j, 2);
+ t = get_h48_pval(table, j, 2);
arg->info.distribution[t]++;
}
@@ -491,7 +491,7 @@ gendata_h48_mark(gendata_h48_mark_t *arg)
FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim,
coord = coord_h48(arg->cube, arg->cocsepdata, arg->h);
- oldval = get_h48_pval((uint8_t *)arg->table, coord, arg->k);
+ oldval = get_h48_pval(arg->table, coord, arg->k);
newval = (uint8_t)MAX(arg->depth, 0);
if (newval < oldval) {
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)
coord = coord_h48(cube, arg->cocsepdata, arg->h);
mutex = H48_INDEX(coord, arg->k) % CHUNKS;
pthread_mutex_lock(arg->table_mutex[mutex]);
- oldval = get_h48_pval((uint8_t *)arg->table, coord, arg->k);
+ oldval = get_h48_pval(arg->table, coord, arg->k);
pthread_mutex_unlock(arg->table_mutex[mutex]);
return oldval <= depth;
} else {
@@ -570,7 +570,7 @@ makeinfo_h48k2(gendata_h48_arg_t *arg)
STATIC void
getdistribution_h48(
- const uint8_t *table,
+ _Atomic const uint8_t *table,
uint64_t distr[static INFO_DISTRIBUTION_LEN],
uint8_t h,
uint8_t k
@@ -587,20 +587,20 @@ getdistribution_h48(
}
}
-STATIC const uint32_t *
+STATIC _Atomic const uint32_t *
get_cocsepdata_constptr(const void *data)
{
- return (uint32_t *)((char *)data + INFOSIZE);
+ return (_Atomic uint32_t *)((char *)data + INFOSIZE);
}
-STATIC const uint8_t *
+STATIC _Atomic const uint8_t *
get_h48data_constptr(const void *data)
{
- return (uint8_t *)data + COCSEP_FULLSIZE + INFOSIZE;
+ return (_Atomic uint8_t *)data + COCSEP_FULLSIZE + INFOSIZE;
}
STATIC_INLINE uint8_t
-get_h48_pval(const uint8_t *table, int64_t i, uint8_t k)
+get_h48_pval(_Atomic const uint8_t *table, int64_t i, uint8_t k)
{
return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k);
}
@@ -618,7 +618,7 @@ get_h48_bound(
uint32_t cdata,
uint8_t h,
uint8_t k,
- const uint8_t *table
+ _Atomic const uint8_t *table
) {
int64_t coord;
@@ -631,7 +631,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
{
size_t cocsepsize, h48size;
uint8_t val_full, val_derive;
- const uint8_t *h48full;
+ _Atomic const uint8_t *h48full;
_Atomic uint8_t *h48derive;
int64_t i, j, h48max;
gendata_h48_arg_t arg;
@@ -672,7 +672,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
goto gendata_h48_derive_error;
}
- h48full = (const uint8_t *)fulltable + cocsepsize + INFOSIZE;
+ h48full = (_Atomic const uint8_t *)fulltable + cocsepsize + INFOSIZE;
h48derive = (_Atomic uint8_t *)arg.h48buf + INFOSIZE;
memset(h48derive, 0xFF, H48_TABLESIZE(h, arg.k));
memset(arg.info.distribution, 0,
@@ -684,13 +684,12 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
LOG("Processing %" PRId64 "th coordinate\n", i);
j = i >> (int64_t)(fulltableinfo.h48h - h);
val_full = get_h48_pval(h48full, i, arg.k);
- val_derive = get_h48_pval((uint8_t *)h48derive, j, arg.k);
+ val_derive = get_h48_pval(h48derive, j, arg.k);
set_h48_pval(
h48derive, j, arg.k, MIN(val_full, val_derive));
}
- getdistribution_h48(
- (uint8_t *)h48derive, arg.info.distribution, h, arg.k);
+ getdistribution_h48(h48derive, arg.info.distribution, h, arg.k);
if (!writetableinfo(&arg.info, arg.h48buf)) {
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
@@ -8,8 +8,8 @@ typedef struct {
int64_t maxsolutions;
uint8_t h;
uint8_t k;
- const uint32_t *cocsepdata;
- const uint8_t *h48data;
+ _Atomic const uint32_t *cocsepdata;
+ _Atomic const uint8_t *h48data;
char **nextsol;
uint8_t nissbranch;
int8_t npremoves;
diff --git a/src/solvers/h48/stats.h b/src/solvers/h48/stats.h
@@ -10,8 +10,8 @@ typedef struct {
int8_t nmoves;
int8_t depth;
uint8_t moves[MAXLEN];
- const uint32_t *cocsepdata;
- const uint8_t *h48data;
+ _Atomic const uint32_t *cocsepdata;
+ _Atomic const uint8_t *h48data;
char *s;
} dfsarg_solveh48stats_t;