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:
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