/* ============================================================================= * TMregion_refine * -- Returns net number of elements added to mesh * ============================================================================= */ long TMregion_refine (TM_ARGDECL region_t* regionPtr, element_t* elementPtr, mesh_t* meshPtr) { long numDelta = 0L; MAP_T* edgeMapPtr = NULL; element_t* encroachElementPtr = NULL; TMELEMENT_ISGARBAGE(elementPtr); /* so we can detect conflicts */ while (1) { edgeMapPtr = MAP_ALLOC(NULL, &element_mapCompareEdge); assert(edgeMapPtr); encroachElementPtr = TMgrowRegion(TM_ARG elementPtr, regionPtr, meshPtr, edgeMapPtr); if (encroachElementPtr) { TMELEMENT_SETISREFERENCED(encroachElementPtr, TRUE); numDelta += TMregion_refine(TM_ARG regionPtr, encroachElementPtr, meshPtr); if (TMELEMENT_ISGARBAGE(elementPtr)) { break; } } else { break; } PMAP_FREE(edgeMapPtr); } /* * Perform retriangulation. */ if (!TMELEMENT_ISGARBAGE(elementPtr)) { numDelta += TMretriangulate(TM_ARG elementPtr, regionPtr, meshPtr, edgeMapPtr); } PMAP_FREE(edgeMapPtr); /* no need to free elements */ return numDelta; }
/* ============================================================================= * TMregion_transferBad * ============================================================================= */ void TMregion_transferBad (TM_ARGDECL region_t* regionPtr, heap_t* workHeapPtr) { vector_t* badVectorPtr = regionPtr->badVectorPtr; long numBad = PVECTOR_GETSIZE(badVectorPtr); long i; for (i = 0; i < numBad; i++) { element_t* badElementPtr = (element_t*)vector_at(badVectorPtr, i); if (TMELEMENT_ISGARBAGE(badElementPtr)) { TMELEMENT_FREE(badElementPtr); } else { bool_t status = TMHEAP_INSERT(workHeapPtr, (void*)badElementPtr); assert(status); } } }
/* ============================================================================= * process * ============================================================================= */ void process () { TM_THREAD_ENTER(); heap_t* workHeapPtr = global_workHeapPtr; mesh_t* meshPtr = global_meshPtr; region_t* regionPtr; long totalNumAdded = 0; long numProcess = 0; regionPtr = PREGION_ALLOC(); assert(regionPtr); while (1) { element_t* elementPtr; AL_LOCK(0); TM_BEGIN(0); elementPtr = TMHEAP_REMOVE(workHeapPtr); TM_END(); if (elementPtr == NULL) { break; } bool_t isGarbage; AL_LOCK(0); TM_BEGIN(1); isGarbage = TMELEMENT_ISGARBAGE(elementPtr); TM_END(); if (isGarbage) { /* * Handle delayed deallocation */ PELEMENT_FREE(elementPtr); continue; } long numAdded; AL_LOCK(0); TM_BEGIN(2); PREGION_CLEARBAD(regionPtr); numAdded = TMREGION_REFINE(regionPtr, elementPtr, meshPtr); TM_END(); AL_LOCK(0); TM_BEGIN(3); TMELEMENT_SETISREFERENCED(elementPtr, FALSE); isGarbage = TMELEMENT_ISGARBAGE(elementPtr); TM_END(); if (isGarbage) { /* * Handle delayed deallocation */ PELEMENT_FREE(elementPtr); } totalNumAdded += numAdded; AL_LOCK(0); TM_BEGIN(4); TMREGION_TRANSFERBAD(regionPtr, workHeapPtr); TM_END(); numProcess++; } AL_LOCK(0); TM_BEGIN(5); TM_SHARED_WRITE(global_totalNumAdded, TM_SHARED_READ(global_totalNumAdded) + totalNumAdded); TM_SHARED_WRITE(global_numProcess, TM_SHARED_READ(global_numProcess) + numProcess); TM_END(); PREGION_FREE(regionPtr); TM_THREAD_EXIT(); }
/* ============================================================================= * TMgrowRegion * -- Return NULL if success, else pointer to encroached boundary * ============================================================================= */ element_t* TMgrowRegion (TM_ARGDECL element_t* centerElementPtr, region_t* regionPtr, mesh_t* meshPtr, MAP_T* edgeMapPtr) { bool_t isBoundary = FALSE; if (element_getNumEdge(centerElementPtr) == 1) { isBoundary = TRUE; } list_t* beforeListPtr = regionPtr->beforeListPtr; list_t* borderListPtr = regionPtr->borderListPtr; queue_t* expandQueuePtr = regionPtr->expandQueuePtr; PLIST_CLEAR(beforeListPtr); PLIST_CLEAR(borderListPtr); PQUEUE_CLEAR(expandQueuePtr); coordinate_t centerCoordinate = TMelement_getNewPoint(TM_ARG centerElementPtr); coordinate_t* centerCoordinatePtr = ¢erCoordinate; PQUEUE_PUSH(expandQueuePtr, (void*)centerElementPtr); while (!PQUEUE_ISEMPTY(expandQueuePtr)) { element_t* currentElementPtr = (element_t*)PQUEUE_POP(expandQueuePtr); PLIST_INSERT(beforeListPtr, (void*)currentElementPtr); /* no duplicates */ list_t* neighborListPtr = TMelement_getNeighborListPtr(TM_ARG currentElementPtr); list_iter_t it; TMLIST_ITER_RESET(&it, neighborListPtr); while (TMLIST_ITER_HASNEXT(&it, neighborListPtr)) { element_t* neighborElementPtr = (element_t*)TMLIST_ITER_NEXT(&it, neighborListPtr); TMELEMENT_ISGARBAGE(neighborElementPtr); /* so we can detect conflicts */ if (!list_find(beforeListPtr, (void*)neighborElementPtr)) { if (element_isInCircumCircle(neighborElementPtr, centerCoordinatePtr)) { /* This is part of the region */ if (!isBoundary && (element_getNumEdge(neighborElementPtr) == 1)) { /* Encroached on mesh boundary so split it and restart */ return neighborElementPtr; } else { /* Continue breadth-first search */ bool_t isSuccess; isSuccess = PQUEUE_PUSH(expandQueuePtr, (void*)neighborElementPtr); assert(isSuccess); } } else { /* This element borders region; save info for retriangulation */ edge_t* borderEdgePtr = TMelement_getCommonEdge(TM_ARG neighborElementPtr, currentElementPtr); if (!borderEdgePtr) { TM_RESTART(); } PLIST_INSERT(borderListPtr, (void*)borderEdgePtr); /* no duplicates */ if (!MAP_CONTAINS(edgeMapPtr, borderEdgePtr)) { PMAP_INSERT(edgeMapPtr, borderEdgePtr, neighborElementPtr); } } } /* not visited before */ } /* for each neighbor */ } /* breadth-first search */ return NULL; }
/* ============================================================================= * process * ============================================================================= */ static void process () { heap_t* workHeapPtr = global_workHeapPtr; mesh_t* meshPtr = global_meshPtr; region_t* regionPtr; long totalNumAdded = 0; long numProcess = 0; regionPtr = PREGION_ALLOC(); assert(regionPtr); while (1) { element_t* elementPtr; __transaction_atomic { elementPtr = (element_t*)TMHEAP_REMOVE(workHeapPtr); } if (elementPtr == NULL) { break; } bool_t isGarbage; __transaction_atomic { isGarbage = TMELEMENT_ISGARBAGE(elementPtr); } if (isGarbage) { /* * Handle delayed deallocation */ TMELEMENT_FREE(elementPtr); continue; } long numAdded; //[wer210] changed the control flow to get rid of self-abort bool_t success = TRUE; while (1) { __transaction_atomic { // TM_SAFE: PVECTOR_CLEAR (regionPtr->badVectorPtr); PREGION_CLEARBAD(regionPtr); //[wer210] problematic function! numAdded = TMREGION_REFINE(regionPtr, elementPtr, meshPtr, &success); if (success) break; else __transaction_cancel; } } __transaction_atomic { TMELEMENT_SETISREFERENCED(elementPtr, FALSE); isGarbage = TMELEMENT_ISGARBAGE(elementPtr); } if (isGarbage) { /* * Handle delayed deallocation */ TMELEMENT_FREE(elementPtr); } totalNumAdded += numAdded; __transaction_atomic { TMREGION_TRANSFERBAD(regionPtr, workHeapPtr); } numProcess++; } __transaction_atomic { TM_SHARED_WRITE(global_totalNumAdded, TM_SHARED_READ(global_totalNumAdded) + totalNumAdded); TM_SHARED_WRITE(global_numProcess, TM_SHARED_READ(global_numProcess) + numProcess); } PREGION_FREE(regionPtr); }
/* ============================================================================= * process * ============================================================================= */ void process () { TM_THREAD_ENTER(); heap_t* workHeapPtr = global_workHeapPtr; mesh_t* meshPtr = global_meshPtr; region_t* regionPtr; long totalNumAdded = 0; long numProcess = 0; regionPtr = PREGION_ALLOC(); assert(regionPtr); while (1) { element_t* elementPtr; __transaction_atomic { elementPtr = TMHEAP_REMOVE(workHeapPtr); } if (elementPtr == NULL) { break; } bool_t isGarbage; __transaction_atomic { isGarbage = TMELEMENT_ISGARBAGE(elementPtr); } if (isGarbage) { /* * Handle delayed deallocation */ PELEMENT_FREE(elementPtr); continue; } long numAdded; __transaction_atomic { PREGION_CLEARBAD(regionPtr); numAdded = TMREGION_REFINE(regionPtr, elementPtr, meshPtr); } __transaction_atomic { TMELEMENT_SETISREFERENCED(elementPtr, FALSE); isGarbage = TMELEMENT_ISGARBAGE(elementPtr); } if (isGarbage) { /* * Handle delayed deallocation */ PELEMENT_FREE(elementPtr); } totalNumAdded += numAdded; __transaction_atomic { TMREGION_TRANSFERBAD(regionPtr, workHeapPtr); } numProcess++; } __transaction_atomic { global_totalNumAdded = global_totalNumAdded + totalNumAdded; global_numProcess = global_numProcess + numProcess; } PREGION_FREE(regionPtr); TM_THREAD_EXIT(); }