star-enclosures-3d

Extract enclosures from 3D geometry
git clone git://git.meso-star.fr/star-enclosures-3d.git
Log | Files | Refs | README | LICENSE

commit e9de0bee60f464b9cb95cd3db93422bd0d1ec071
parent 547224f7e576f922fb164e10895824c491e22f3b
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed, 18 Apr 2018 10:21:19 +0200

BugFix: possible omp runtime error.

Race condition could lead to some threads not involved in some omp constructs.

Diffstat:
Msrc/senc_scene_analyze.c | 68+++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 35 insertions(+), 33 deletions(-)

diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c @@ -475,11 +475,11 @@ extract_connex_components if(s3d_scn) S3D(scene_ref_put(s3d_scn)); if(s3d_shp) S3D(shape_ref_put(s3d_shp)); } - if(*res != RES_OK) return; #ifndef NDEBUG /* Need to wait for all threads done to be able to check stuff */ #pragma omp barrier + if(*res != RES_OK) return; #pragma omp single { ASSERT(*component_count == @@ -1078,6 +1078,7 @@ senc_scene_analyze(struct senc_scene* scn, struct senc_descriptor** out_desc) /* Used as args to have shared vars between threads in functions */ struct cc_descriptor* infinity_first_cc = NULL; res_T res = RES_OK; + res_T res2 = RES_OK; if(!scn || !out_desc) return RES_BAD_ARG; @@ -1110,17 +1111,6 @@ senc_scene_analyze(struct senc_scene* scn, struct senc_descriptor** out_desc) * released / data produced by step 1 cannot be used * until next sync point */ - if(res != RES_OK) { - { - #pragma omp single nowait - { - log_err(scn->dev, - "%s: could not build neighbourhoods from scene.\n", FUNC_NAME); - } /* No barrier here */ - } - } - if(res != RES_OK) goto error_; - /* The first thread here allocates some data. * Barrier needed at the end to ensure data created before any use. */ #pragma omp single @@ -1136,10 +1126,22 @@ senc_scene_analyze(struct senc_scene* scn, struct senc_descriptor** out_desc) triangles_comp_initialized = 1; OK2(darray_triangle_comp_resize(&triangles_comp, scn->nutris)); tmp_error: - if(tmp_res != RES_OK) res = tmp_res; + if(tmp_res != RES_OK) res2 = tmp_res; } /* Implicit barrier here: constraints on step 1 data are now met */ - if(res != RES_OK) goto error_; + + if(res != RES_OK || res2 != RES_OK) { + #pragma omp single nowait + { + if(res != RES_OK) { + log_err(scn->dev, + "%s: could not build neighbourhoods from scene.\n", FUNC_NAME); + } else { + res = res2; + } + } + goto error_; + } /* Step 2: extract triangle connex components */ extract_connex_components(desc, trgsides, &connex_components, @@ -1148,17 +1150,17 @@ senc_scene_analyze(struct senc_scene* scn, struct senc_descriptor** out_desc) * released / data produced by step 2 cannot be used * until next sync point */ + #pragma omp barrier + /* Constraints on step 2 data are now met */ + if(res != RES_OK) { #pragma omp single nowait { log_err(scn->dev, "%s: could not extract connex components from scene.\n", FUNC_NAME); } /* No barrier here */ + goto error_; } - if(res != RES_OK) goto error_; - - #pragma omp barrier - /* Constraints on step 2 data are now met */ /* One thread releases some data before going to step 3, * the others go to step 3 without sync */ @@ -1175,22 +1177,22 @@ senc_scene_analyze(struct senc_scene* scn, struct senc_descriptor** out_desc) /* Barrier at the end of step 3: data used in step 3 can be released / * data produced by step 3 can be used */ - /* One thread releases some data before going to step 4, - * the others go to step 4 without sync */ - #pragma omp single nowait - { - if(s3d_view) S3D(scene_view_ref_put(s3d_view)); - s3d_view = NULL; - } /* No barrier here */ - if(res != RES_OK) { #pragma omp single nowait { log_err(scn->dev, "%s: could not group connex components from scene.\n", FUNC_NAME); - } /* No barrier here */ + } + goto error_; } - if(res != RES_OK) goto error_; + + /* One thread releases some data before going to step 4, + * the others go to step 4 without sync */ + #pragma omp single nowait + { + if(s3d_view) S3D(scene_view_ref_put(s3d_view)); + s3d_view = NULL; + } /* No barrier here */ /* Step 4: Build result */ build_result(desc, &connex_components, &triangles_comp, &res); @@ -1198,16 +1200,16 @@ senc_scene_analyze(struct senc_scene* scn, struct senc_descriptor** out_desc) * released / data produced by step 4 cannot be used * until next sync point */ + #pragma omp barrier + /* Constraints on step 4 data are now met */ + if(res != RES_OK) { #pragma omp single nowait { log_err(scn->dev, "%s: could not build result.\n", FUNC_NAME); - } /* No barrier here */ + } + goto error_; } - if(res != RES_OK) goto error_; - - #pragma omp barrier - /* Constraints on step 4 data are now met */ /* Some threads release data */ #pragma omp sections nowait