star-enclosures-2d

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

commit 0074dd1030cc7230ca66f006dac00e0d5ac92953
parent 0bb41786faccbbf806512a7bf5a0dfc6493d774a
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri,  6 Apr 2018 17:40:24 +0200

BugFix: some static vars were reused without reset.

No static vars anymore

Fix error management too

Diffstat:
Msrc/senc2d_scene_analyze.c | 373+++++++++++++++++++++++++++++++++++++++----------------------------------------
1 file changed, 184 insertions(+), 189 deletions(-)

diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c @@ -193,18 +193,21 @@ self_hit_filter return (hit_component == *origin_component); } -static res_T +static void extract_connex_components (struct senc2d_descriptor* desc, struct segside* segsides, struct darray_ptr_component_descriptor* connex_components, const struct darray_segment_tmp* segments_tmp_array, struct darray_segment_comp* segments_comp, - struct s2d_scene_view** s2d_view) + struct s2d_scene_view** s2d_view, + ATOMIC* component_count, + /* Shared error status. + * We accept to overwritte an error with a different error */ + res_T* res) { /* This function is called from an omp parallel block and executed * concurrently. */ - res_T res = RES_OK; const struct senc2d_scene* scn; struct mem_allocator* alloc; int64_t mm; @@ -213,11 +216,9 @@ extract_connex_components seg_id_t s_; component_id_t c; #endif - /* shared between threads */ - static ATOMIC component_count = 0; - static volatile int exit_for = 0; - ASSERT(segsides && desc && connex_components && segments_tmp_array); + ASSERT(segsides && desc && connex_components && segments_tmp_array + && s2d_view && component_count && res); alloc = descriptor_get_allocator(desc); scn = desc->scene; @@ -248,7 +249,7 @@ extract_connex_components /* Any not-already-used side is used as a starting point */ side_id_t first_side_not_in_component; - if(exit_for) continue; + if(*res != RES_OK) continue; first_side_not_in_component = darray_side_range_cdata_get(&scn->media_use)[m].first; if(first_side_not_in_component == SIDE_NULL__) @@ -278,12 +279,12 @@ extract_connex_components /* Create and init a new component */ cc = MEM_ALLOC(alloc, sizeof(struct cc_descriptor)); if(!cc) { - res = RES_MEM_ERR; - goto error1; + *res = RES_MEM_ERR; + continue; } cc_descriptor_init(alloc, cc); ASSERT(m == segsides[start_side_id].medium); - cc->cc_id = (component_id_t)(ATOMIC_INCR(&component_count) - 1); + cc->cc_id = (component_id_t)(ATOMIC_INCR(component_count) - 1); cc->medium = m; cc->side_range.first = start_side_id; @@ -406,8 +407,8 @@ extract_connex_components SPLIT2(positions[segments_in[nbour_seg_id].vertice_id[1]].vec)); log_err(desc->scene->dev, "Media: %lu VS %lu\n", (unsigned long)neighbour->medium, (unsigned long)crt_side->medium); - res = RES_BAD_ARG; - goto error1; + *res = RES_BAD_ARG; + continue; } if(neighbour->list_id == FLAG_LIST_COMPONENT) { /* Already processed */ @@ -437,9 +438,9 @@ extract_connex_components if(sz <= cc->cc_id) { res_T tmp_res = darray_ptr_component_descriptor_resize(connex_components, 1 + cc->cc_id); - if(tmp_res != RES_OK) res = tmp_res; + if(tmp_res != RES_OK) *res = tmp_res; } - if(res == RES_OK) { + if(*res == RES_OK) { /* Don't set the pointer before resize as this can lead to move data */ components = darray_ptr_component_descriptor_data_get(connex_components); @@ -447,19 +448,15 @@ extract_connex_components components[cc->cc_id] = cc; } } - OK2(res, error1); } - continue; - error1: - /* Cannot goto out of openmp block */ - exit_for = 1; - continue; - } - /* No barrier here (nowait clause). - * The first thread here creates the s2d view */ + } /* No barrier here */ + darray_side_id_release(&stack); + + /* The first thread here creates the s2d view */ #pragma omp single nowait - if(res == RES_OK) { + if(*res == RES_OK) { + res_T tmp_res = RES_OK; struct s2d_device* s2d = NULL; struct s2d_scene* s2d_scn = NULL; struct s2d_shape* s2d_shp = NULL; @@ -470,77 +467,76 @@ extract_connex_components attribs.get = get_scn_position; /* Put geometry in a 2D view */ - OK(s2d_device_create(desc->scene->dev->logger, alloc, 0, &s2d)); - OK(s2d_scene_create(s2d, &s2d_scn)); - OK(s2d_shape_create_line_segments(s2d, &s2d_shp)); + OK2(s2d_device_create(desc->scene->dev->logger, alloc, 0, &s2d)); + OK2(s2d_scene_create(s2d, &s2d_scn)); + OK2(s2d_shape_create_line_segments(s2d, &s2d_shp)); /* Back to API type for ntris and nverts */ ASSERT(desc->scene->nusegs < UINT_MAX); ASSERT(desc->scene->nuverts < UINT_MAX); - OK(s2d_line_segments_setup_indexed_vertices(s2d_shp, + OK2(s2d_line_segments_setup_indexed_vertices(s2d_shp, (unsigned)desc->scene->nusegs, get_scn_indices, (unsigned)desc->scene->nuverts, &attribs, 1, desc->scene)); s2d_line_segments_set_hit_filter_function(s2d_shp, self_hit_filter, segments_comp); - OK(s2d_scene_attach_shape(s2d_scn, s2d_shp)); - OK(s2d_scene_view_create(s2d_scn, S2D_TRACE, s2d_view)); - error: + OK2(s2d_scene_attach_shape(s2d_scn, s2d_shp)); + OK2(s2d_scene_view_create(s2d_scn, S2D_TRACE, s2d_view)); + tmp_error: + if(tmp_res != RES_OK) *res = tmp_res; if(s2d) S2D(device_ref_put(s2d)); if(s2d_scn) S2D(scene_ref_put(s2d_scn)); if(s2d_shp) S2D(shape_ref_put(s2d_shp)); } - OK2(res, error_); + if(*res != RES_OK) return; #ifndef NDEBUG /* Need to wait for all threads done to be able to check stuff */ #pragma omp barrier - ASSERT(component_count == - (int)darray_ptr_component_descriptor_size_get(connex_components)); - FOR_EACH(s_, 0, scn->nusegs) { - struct segment_comp* seg_comp = - darray_segment_comp_data_get(segments_comp) + s_; - ASSERT(seg_comp->component[SIDE_FRONT] != COMPONENT_NULL__); - ASSERT(seg_comp->component[SIDE_BACK] != COMPONENT_NULL__); - } - FOR_EACH(c, 0, component_count) { - struct cc_descriptor** components = - darray_ptr_component_descriptor_data_get(connex_components); - ASSERT(components[c] != NULL && - components[c]->cc_id == c); - } - ASSERT(desc->segment_count - == darray_segment_comp_size_get(segments_comp)); + #pragma omp single + { + ASSERT(*component_count == + (int)darray_ptr_component_descriptor_size_get(connex_components)); + FOR_EACH(s_, 0, scn->nusegs) { + struct segment_comp* seg_comp = + darray_segment_comp_data_get(segments_comp) + s_; + ASSERT(seg_comp->component[SIDE_FRONT] != COMPONENT_NULL__); + ASSERT(seg_comp->component[SIDE_BACK] != COMPONENT_NULL__); + } + FOR_EACH(c, 0, *component_count) { + struct cc_descriptor** components = + darray_ptr_component_descriptor_data_get(connex_components); + ASSERT(components[c] != NULL && + components[c]->cc_id == c); + } + ASSERT(desc->segment_count + == darray_segment_comp_size_get(segments_comp)); + } /* Implicit barrier here */ #endif - -exit: - return res; -error_: - exit_for = 1; - goto exit; } -static res_T +static void group_connex_components (struct senc2d_descriptor* desc, struct segside* segsides, struct darray_segment_comp* segments_comp, struct darray_ptr_component_descriptor* connex_components, - struct s2d_scene_view* s2d_view) + struct s2d_scene_view* s2d_view, + ATOMIC* next_enclosure_id, + struct cc_descriptor** infinity_first_cc, + /* Shared error status. + * We accept to overwritte an error with a different error */ + res_T* res) { /* This function is called from an omp parallel block and executed * concurrently. */ - res_T res = RES_OK; struct cc_descriptor** descriptors; size_t tmp; component_id_t cc_count; int64_t ccc; - /* shared between threads */ - static struct cc_descriptor* infinity_first_cc = NULL; - static volatile int exit_for = 0; - static ATOMIC next_enclosure_id = 1; (void)segsides; - ASSERT(desc && segsides && segments_comp && connex_components); + ASSERT(desc && segsides && segments_comp && connex_components + && next_enclosure_id && infinity_first_cc && res); ASSERT(desc->enclosures_count == 1); descriptors = darray_ptr_component_descriptor_data_get(connex_components); @@ -551,6 +547,7 @@ group_connex_components /* Cast rays to find links between connex components */ #pragma omp for for(ccc = 0; ccc < (int64_t)cc_count; ccc++) { + res_T tmp_res = RES_OK; component_id_t c = (component_id_t)ccc; struct s2d_hit hit = S2D_HIT_NULL; float origin[2]; @@ -562,7 +559,7 @@ group_connex_components component_id_t self_hit_component = origin_seg->component[1 - SEGSIDE_2_SIDE(cc->max_y_side_id)]; - if(exit_for) continue; + if(*res != RES_OK) continue; ASSERT(cc->cc_id == c); ASSERT(cc->cc_group_root == CC_GROUP_ID_NONE); @@ -570,7 +567,7 @@ group_connex_components int64_t id; /* Don't need to cast a ray */ cc->cc_group_root = cc->cc_id; /* New group with self as root */ - id = ATOMIC_INCR(&next_enclosure_id) - 1; + id = ATOMIC_INCR(next_enclosure_id) - 1; ASSERT(id < ENCLOSURE_MAX__); cc->enclosure_id = (enclosure_id_t)id; continue; @@ -586,17 +583,21 @@ group_connex_components == SEGSIDE_OPPOSITE(cc->max_y_side_id)))); f2_set_d2(origin, cc->max_vrtx); /* Self-hit data: self hit if hit this component "on the other side" */ - OK2(s2d_scene_view_trace_ray(s2d_view, origin, dir, range, - &self_hit_component, &hit), error_); + tmp_res = s2d_scene_view_trace_ray(s2d_view, origin, dir, range, + &self_hit_component, &hit); + if(tmp_res != RES_OK) { + *res = tmp_res; + continue; + } /* If no hit, the component is facing an infinite medium */ if(S2D_HIT_NONE(&hit)) { cc->cc_group_root = CC_GROUP_ROOT_INFINITE; cc->enclosure_id = 0; /* Keep track of the first component facing infinity */ - ATOMIC_CAS_PTR(&infinity_first_cc, cc, NULL); - if(infinity_first_cc->medium != cc->medium) { - const side_id_t infinity_first_side = infinity_first_cc->max_y_side_id; - const medium_id_t infinity_medium = infinity_first_cc->medium; + ATOMIC_CAS_PTR(infinity_first_cc, cc, NULL); + if((*infinity_first_cc)->medium != cc->medium) { + const side_id_t infinity_first_side = (*infinity_first_cc)->max_y_side_id; + const medium_id_t infinity_medium = (*infinity_first_cc)->medium; /* Medium mismatch! Model topology is broken. */ const seg_id_t t1 = SEGSIDE_2_SEG(infinity_first_side); const seg_id_t t2 = SEGSIDE_2_SEG(cc->max_y_side_id); @@ -623,11 +624,9 @@ group_connex_components SPLIT2(positions[segments_in[t2].vertice_id[1]].vec)); log_err(desc->scene->dev, "Media: %lu VS %lu\n", (unsigned long)infinity_medium, (unsigned long)cc->medium); - res = RES_BAD_ARG; - goto error_; + *res = RES_BAD_ARG; } /* Same medium as previous members of the group: OK */ - continue; } else { /* If hit, group this component */ const seg_id_t hit_seg_id = (seg_id_t)hit.prim.prim_id; @@ -681,78 +680,70 @@ group_connex_components (unsigned long)hit_seg_in->medium[hit_side], (unsigned long)cc->medium); - res = RES_BAD_ARG; - goto error_; + *res = RES_BAD_ARG; } } - continue; - error_: - /* Cannot goto out of openmp block */ - exit_for = 1; - continue; } /* Implicit barrier here */ - ASSERT(next_enclosure_id < ENCLOSURE_MAX__); - OK(res); + ASSERT(*next_enclosure_id < ENCLOSURE_MAX__); + if(*res != RES_OK) return; /* One thread post-processes links to group connex components */ #pragma omp single { - desc->enclosures_count = (enclosure_id_t)next_enclosure_id; - res = darray_enclosure_resize(&desc->enclosures, desc->enclosures_count); - if(res == RES_OK) { - FOR_EACH(ccc, 0, cc_count) { - component_id_t c = (component_id_t)ccc; - struct cc_descriptor* const cc = descriptors[c]; - const struct cc_descriptor* other_desc = cc; - struct enclosure_data* enclosures - = darray_enclosure_data_get(&desc->enclosures); - component_id_t fst; - - while(other_desc->enclosure_id == CC_GROUP_ID_NONE) { - other_desc = *(darray_ptr_component_descriptor_cdata_get(connex_components) - + other_desc->cc_group_root); - } - ASSERT(other_desc->cc_group_root != CC_GROUP_ROOT_NONE); - ASSERT(other_desc->enclosure_id != CC_GROUP_ID_NONE); - ASSERT(cc->medium == other_desc->medium); - cc->cc_group_root = other_desc->cc_group_root; - cc->enclosure_id = other_desc->enclosure_id; - ++enclosures[cc->enclosure_id].cc_count; - /* Linked list of componnents */ - fst = enclosures[cc->enclosure_id].first_component; - cc->enclosure_next_component = fst; - enclosures[cc->enclosure_id].first_component = cc->cc_id; - enclosures[cc->enclosure_id].side_range.first - = MMIN(enclosures[cc->enclosure_id].side_range.first, cc->side_range.first); - enclosures[cc->enclosure_id].side_range.last - = MMAX(enclosures[cc->enclosure_id].side_range.last, cc->side_range.last); - enclosures[cc->enclosure_id].side_count += cc->side_count; + res_T tmp_res = RES_OK; + desc->enclosures_count = (enclosure_id_t)*next_enclosure_id; + tmp_res = darray_enclosure_resize(&desc->enclosures, desc->enclosures_count); + if(tmp_res != RES_OK) { + *res = tmp_res; + return; + } + FOR_EACH(ccc, 0, cc_count) { + component_id_t c = (component_id_t)ccc; + struct cc_descriptor* const cc = descriptors[c]; + const struct cc_descriptor* other_desc = cc; + struct enclosure_data* enclosures + = darray_enclosure_data_get(&desc->enclosures); + component_id_t fst; + + while(other_desc->enclosure_id == CC_GROUP_ID_NONE) { + other_desc = *(darray_ptr_component_descriptor_cdata_get(connex_components) + + other_desc->cc_group_root); } + ASSERT(other_desc->cc_group_root != CC_GROUP_ROOT_NONE); + ASSERT(other_desc->enclosure_id != CC_GROUP_ID_NONE); + ASSERT(cc->medium == other_desc->medium); + cc->cc_group_root = other_desc->cc_group_root; + cc->enclosure_id = other_desc->enclosure_id; + ++enclosures[cc->enclosure_id].cc_count; + /* Linked list of componnents */ + fst = enclosures[cc->enclosure_id].first_component; + cc->enclosure_next_component = fst; + enclosures[cc->enclosure_id].first_component = cc->cc_id; + enclosures[cc->enclosure_id].side_range.first + = MMIN(enclosures[cc->enclosure_id].side_range.first, cc->side_range.first); + enclosures[cc->enclosure_id].side_range.last + = MMAX(enclosures[cc->enclosure_id].side_range.last, cc->side_range.last); + enclosures[cc->enclosure_id].side_count += cc->side_count; } } /* Implicit barrier here */ - OK(res); - -exit: - return res; -error: - exit_for = 1; - goto exit; } -static res_T +static void collect_and_link_neighbours (struct senc2d_scene* scn, struct segside* segsides, struct darray_segment_tmp* segments_tmp_array, - struct darray_neighbourhood* neighbourhood_by_vertex) + struct darray_neighbourhood* neighbourhood_by_vertex, + /* Shared error status. + * We accept to overwritte an error with a different error */ + res_T* res) { /* This function is called from an omp parallel block and executed * concurrently. * Resize / Push operations on neighbourhood_by_vertex are valid * because each neighbourhood is processes by an unique thread */ - res_T res = RES_OK; const struct segment_in *segments_in; struct segment_tmp *segments_tmp; const union double2* vertices; @@ -760,10 +751,9 @@ collect_and_link_neighbours const int rank = omp_get_thread_num(); vrtx_id_t v; seg_id_t s; - /* shared between threads */ - static volatile int exit_for = 0; - ASSERT(scn && segsides && segments_tmp_array); + ASSERT(scn && segsides && segments_tmp_array + && neighbourhood_by_vertex && res); ASSERT((size_t)scn->nuverts + (size_t)scn->nusegs + 2 <= EDGE_MAX__); segments_in = darray_segment_in_cdata_get(&scn->segments_in); @@ -781,8 +771,9 @@ collect_and_link_neighbours struct neighbour_info* info; const vrtx_id_t vertex = segments_in[s].vertice_id[vv]; size_t sz; + res_T tmp_res = RES_OK; ASSERT(vertex < scn->nuverts); - if(exit_for) continue; + if(*res != RES_OK) continue; /* Process only "my" vertices! */ if((int64_t)vertex % thread_count != rank) continue; /* Find neighbourhood */ @@ -794,9 +785,17 @@ collect_and_link_neighbours if(darray_neighbour_capacity(neighbourhood) == sz) { /* 2 seems to be a good guess for initial capacity */ size_t new_sz = sz ? sz + 1 : 2; - OK(darray_neighbour_reserve(neighbourhood, new_sz)); + tmp_res = darray_neighbour_reserve(neighbourhood, new_sz); + if(tmp_res != RES_OK) { + *res = tmp_res; + return; + } + } + tmp_res = darray_neighbour_resize(neighbourhood, 1 + sz); + if(tmp_res != RES_OK) { + *res = tmp_res; + return; } - OK(darray_neighbour_resize(neighbourhood, 1 + sz)); /* Add neighbour info to vertex's neighbour list */ info = darray_neighbour_data_get(neighbourhood) + sz; info->seg_id = s; @@ -807,6 +806,8 @@ collect_and_link_neighbours * it can process them whithout waiting for other threads * (no barrier needed here). */ + if(*res != RES_OK) return; + /* For each of "my" vertices sort segments sides by rotation angle * and connect neighbours. * All threads considering all the vertices and processing some */ @@ -890,24 +891,20 @@ collect_and_link_neighbours p_ccw_side->list_id = FLAG_LIST_SIDE_LIST; } } -end: /* Threads are allowed to return whitout sync. */ - return res; -error: - /* Cannot goto out of openmp block */ - exit_for = 1; - goto end; } -static res_T +static void build_result (struct senc2d_descriptor* desc, const struct darray_ptr_component_descriptor* connex_components, - const struct darray_segment_comp* segments_comp_array) + const struct darray_segment_comp* segments_comp_array, + /* Shared error status. + * We accept to overwritte an error with a different error */ + res_T* res) { /* This function is called from an omp parallel block and executed * concurrently. */ - res_T res = RES_OK; struct mem_allocator* alloc; struct cc_descriptor* const* cc_descriptors; struct enclosure_data* enclosures; @@ -917,22 +914,23 @@ build_result struct htable_vrtx_id vtable; int64_t sg; int64_t ee; - /* shared between threads */ - static volatile int exit_for = 0; - ASSERT(desc && connex_components && segments_comp_array); + ASSERT(desc && connex_components && segments_comp_array && res); alloc = descriptor_get_allocator(desc); - ASSERT(darray_ptr_component_descriptor_size_get(connex_components) < COMPONENT_MAX__); + ASSERT(darray_ptr_component_descriptor_size_get(connex_components) + < COMPONENT_MAX__); cc_descriptors = darray_ptr_component_descriptor_cdata_get(connex_components); enclosures = darray_enclosure_data_get(&desc->enclosures); segments_in = darray_segment_in_cdata_get(&desc->scene->segments_in); segments_comp = darray_segment_comp_cdata_get(segments_comp_array); #pragma omp single { - res = darray_segment_enc_resize(&desc->segments_enc, desc->scene->nusegs); + res_T tmp_res = + darray_segment_enc_resize(&desc->segments_enc, desc->scene->nusegs); + if(tmp_res != RES_OK) *res = tmp_res; }/* Implicit barrier here. */ - OK2(res, error_); + if(*res != RES_OK) return; segments_enc = darray_segment_enc_data_get(&desc->segments_enc); /* Build global enclosure information */ @@ -965,11 +963,12 @@ build_result seg_id_t fst_idx = 0; seg_id_t sgd_idx = enc->side_count; seg_id_t s; + res_T tmp_res = RES_OK; ASSERT(enc->first_component < darray_ptr_component_descriptor_size_get(connex_components)); ASSERT(current->cc_id == enc->first_component); - if(exit_for) continue; + if(*res != RES_OK) continue; ASSERT(e <= UINT_MAX); enc->header.enclosure_id = (unsigned)e; /* Back to API type */ ASSERT(current->enclosure_id == enc->header.enclosure_id); @@ -979,9 +978,11 @@ build_result ASSERT(enc->header.enclosed_medium < desc->scene->nmeds); /* Build side and vertex lists. */ - OK(darray_segment_in_resize(&enc->sides, enc->side_count)); + tmp_res = darray_segment_in_resize(&enc->sides, enc->side_count); + if(*res != RES_OK) continue; /* Size is just a int */ - OK(darray_vrtx_id_reserve(&enc->vertices, enc->side_count + 1)); + tmp_res = darray_vrtx_id_reserve(&enc->vertices, enc->side_count + 1); + if(*res != RES_OK) continue; /* New vertex numbering scheme local to the enclosure */ htable_vrtx_id_clear(&vtable); ASSERT(desc->scene->nusegs @@ -1011,9 +1012,8 @@ build_result ASSERT(tmp == darray_vrtx_id_size_get(&enc->vertices)); ASSERT(tmp < VRTX_MAX__); vertice_id[i] = (vrtx_id_t)tmp; - OK(htable_vrtx_id_set(&vtable, seg_in->vertice_id + i, - vertice_id + i)); - OK(darray_vrtx_id_push_back(&enc->vertices, seg_in->vertice_id + i)); + OK2(htable_vrtx_id_set(&vtable, seg_in->vertice_id + i, vertice_id + i)); + OK2(darray_vrtx_id_push_back(&enc->vertices, seg_in->vertice_id + i)); ++enc->header.vertices_count; } } @@ -1039,27 +1039,21 @@ build_result if(fst_idx == sgd_idx) break; } continue; - error: - /* Cannot goto out of openmp block */ - exit_for = 1; + tmp_error: + ASSERT(tmp_res != RES_OK); + *res = tmp_res; } /* No barrier here */ htable_vrtx_id_release(&vtable); - - OK2(res, error_); - -exit: - return res; -error_: - goto exit; } /******************************************************************************* * Exported functions ******************************************************************************/ res_T -senc2d_scene_analyze(struct senc2d_scene* scn, struct senc2d_descriptor** out_desc) +senc2d_scene_analyze + (struct senc2d_scene* scn, + struct senc2d_descriptor** out_desc) { - res_T res = RES_OK; struct senc2d_descriptor* desc = NULL; /* By segment tmp data */ struct darray_segment_tmp segments_tmp; @@ -1077,6 +1071,12 @@ senc2d_scene_analyze(struct senc2d_scene* scn, struct senc2d_descriptor** out_de /* Array to keep neighbourhood of vertices */ struct darray_neighbourhood neighbourhood_by_vertex; char neighbourhood_by_vertex_initialized = 0; + /* Atomic counters to share beetwen threads */ + ATOMIC component_count = 0; + ATOMIC next_enclosure_id = 1; + /* Used as args to have shared vars between threads in functions */ + struct cc_descriptor* infinity_first_cc = NULL; + res_T res = RES_OK; if(!scn || !out_desc) return RES_BAD_ARG; @@ -1110,42 +1110,40 @@ senc2d_scene_analyze(struct senc2d_scene* scn, struct senc2d_descriptor** out_de /* The end of the analyze is multithreaded */ #pragma omp parallel { - res_T thread_res = RES_OK; - /* Step 1: build neighbourhoods */ - thread_res = collect_and_link_neighbours(scn, segsides, &segments_tmp, - &neighbourhood_by_vertex); + collect_and_link_neighbours(scn, segsides, &segments_tmp, + &neighbourhood_by_vertex, &res); /* No barrier at the end of step 1: data used in step 1 cannot be * released / data produced by step 1 cannot be used * until next sync point */ - if(thread_res != RES_OK) { - res = thread_res; + 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 */ } - OK2(res, error_); + if(res != RES_OK) goto error_; /* The first thread here allocates some data */ #pragma omp single { + res_T tmp_res = RES_OK; darray_ptr_component_descriptor_init(scn->dev->allocator, &connex_components); connex_components_initialized = 1; /* Just a hint; to limit contention */ - thread_res = darray_ptr_component_descriptor_reserve(&connex_components, - 2 * scn->nmeds); - if(thread_res != RES_OK) res = thread_res; + OK2(darray_ptr_component_descriptor_reserve(&connex_components, + 2 * scn->nmeds)); darray_segment_comp_init(scn->dev->allocator, &segments_comp); segments_comp_initialized = 1; - thread_res = darray_segment_comp_resize(&segments_comp, scn->nusegs); - if(thread_res != RES_OK) res = thread_res; + OK2(darray_segment_comp_resize(&segments_comp, scn->nusegs)); + tmp_error: + if(tmp_res != RES_OK) res = tmp_res; } /* Implicit barrier here: constraints on step 1 data are now met */ - OK2(res, error_); + if(res != RES_OK) goto error_; /* One thread releases some data before going to step 2, * the others go to step 2 without sync */ @@ -1153,24 +1151,23 @@ senc2d_scene_analyze(struct senc2d_scene* scn, struct senc2d_descriptor** out_de { darray_neighbourhood_release(&neighbourhood_by_vertex); neighbourhood_by_vertex_initialized = 0; - } /* Barrier here */ + } /* No barrier here */ /* Step 2: extract segment connex components */ - thread_res = extract_connex_components(desc, segsides, &connex_components, - &segments_tmp, &segments_comp, &s2d_view); + extract_connex_components(desc, segsides, &connex_components, + &segments_tmp, &segments_comp, &s2d_view, &component_count, &res); /* No barrier at the end of step 2: data used in step 2 cannot be * released / data produced by step 2 cannot be used * until next sync point */ - if(thread_res != RES_OK) { - res = thread_res; + 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 */ } - OK2(res, error_); + if(res != RES_OK) goto error_; #pragma omp barrier /* Constraints on step 2 data are now met */ @@ -1184,8 +1181,8 @@ senc2d_scene_analyze(struct senc2d_scene* scn, struct senc2d_descriptor** out_de } /* No barrier here */ /* Step 3: group components */ - thread_res = group_connex_components(desc, segsides, &segments_comp, - &connex_components, s2d_view); + group_connex_components(desc, segsides, &segments_comp, &connex_components, + s2d_view, &next_enclosure_id, &infinity_first_cc, &res); /* Barrier at the end of step 3: data used in step 3 can be released / * data produced by step 2 can be used */ @@ -1198,29 +1195,27 @@ senc2d_scene_analyze(struct senc2d_scene* scn, struct senc2d_descriptor** out_de } /* No barrier here */ if(res != RES_OK) { - res = thread_res; #pragma omp single nowait { log_err(scn->dev, "%s: could not group connex components from scene.\n", FUNC_NAME); } /* No barrier here */ } - OK2(res, error_); + if(res != RES_OK) goto error_; /* Step 4: Build result */ - thread_res = build_result(desc, &connex_components, &segments_comp); + build_result(desc, &connex_components, &segments_comp, &res); /* No barrier at the end of step 4: data used in step 4 cannot be * released / data produced by step 4 cannot be used * until next sync point */ - if(thread_res != RES_OK) { - res = thread_res; + if(res, res != RES_OK) { #pragma omp single nowait { log_err(scn->dev, "%s: could not build result.\n", FUNC_NAME); } /* No barrier here */ } - OK2(res, error_); + if(res != RES_OK) goto error_; #pragma omp barrier /* Constraints on step 4 data are now met */