/* ============================================================================= * Pregion_alloc * ============================================================================= */ region_t* Pregion_alloc () { region_t* regionPtr; regionPtr = (region_t*)P_MALLOC(sizeof(region_t)); if (regionPtr) { regionPtr->expandQueuePtr = PQUEUE_ALLOC(-1); assert(regionPtr->expandQueuePtr); regionPtr->beforeListPtr = PLIST_ALLOC(®ion_elementlistcompare); assert(regionPtr->beforeListPtr); regionPtr->borderListPtr = PLIST_ALLOC(®ion_listcompareedge); assert(regionPtr->borderListPtr); regionPtr->badVectorPtr = PVECTOR_ALLOC(1); assert(regionPtr->badVectorPtr); } return regionPtr; }
/* ============================================================================= * router_solve * ============================================================================= */ void router_solve (void* argPtr) { TM_THREAD_ENTER(); router_solve_arg_t* routerArgPtr = (router_solve_arg_t*)argPtr; router_t* routerPtr = routerArgPtr->routerPtr; maze_t* mazePtr = routerArgPtr->mazePtr; vector_t* myPathVectorPtr = PVECTOR_ALLOC(1); assert(myPathVectorPtr); queue_t* workQueuePtr = mazePtr->workQueuePtr; grid_t* gridPtr = mazePtr->gridPtr; grid_t* myGridPtr = PGRID_ALLOC(gridPtr->width, gridPtr->height, gridPtr->depth); assert(myGridPtr); long bendCost = routerPtr->bendCost; queue_t* myExpansionQueuePtr = PQUEUE_ALLOC(-1); /* * Iterate over work list to route each path. This involves an * 'expansion' and 'traceback' phase for each source/destination pair. */ while (1) { pair_t* coordinatePairPtr; int mode = 0; TM_BEGIN(0,mode); if (mode == 0) { if (queue_htm::TMqueue_isEmpty(TM_ARG workQueuePtr)) { coordinatePairPtr = NULL; } else { coordinatePairPtr = (pair_t*)queue_htm::TMqueue_pop(TM_ARG workQueuePtr); } } else { if (queue_stm::TMqueue_isEmpty(TM_ARG workQueuePtr)) { coordinatePairPtr = NULL; } else { coordinatePairPtr = (pair_t*)queue_stm::TMqueue_pop(TM_ARG workQueuePtr); } } TM_END(); if (coordinatePairPtr == NULL) { break; } coordinate_t* srcPtr = coordinatePairPtr->firstPtr; coordinate_t* dstPtr = coordinatePairPtr->secondPtr; bool_t success = FALSE; vector_t* pointVectorPtr = NULL; mode = 0; TM_BEGIN(1,mode); if (mode == 0) { grid_copy(myGridPtr, gridPtr); /* ok if not most up-to-date */ if (PdoExpansion(routerPtr, myGridPtr, myExpansionQueuePtr, srcPtr, dstPtr)) { pointVectorPtr = PdoTraceback(gridPtr, myGridPtr, dstPtr, bendCost); /* * TODO: fix memory leak * * pointVectorPtr will be a memory leak if we abort this transaction */ if (pointVectorPtr) { TMGRID_ADDPATH_HTM(gridPtr, pointVectorPtr); TM_LOCAL_WRITE(success, TRUE); } } } else { grid_copy(myGridPtr, gridPtr); /* ok if not most up-to-date */ if (PdoExpansion(routerPtr, myGridPtr, myExpansionQueuePtr, srcPtr, dstPtr)) { pointVectorPtr = PdoTraceback(gridPtr, myGridPtr, dstPtr, bendCost); /* * TODO: fix memory leak * * pointVectorPtr will be a memory leak if we abort this transaction */ if (pointVectorPtr) { TMGRID_ADDPATH_STM(gridPtr, pointVectorPtr); TM_LOCAL_WRITE(success, TRUE); } } } TM_END(); if (success) { bool_t status = PVECTOR_PUSHBACK(myPathVectorPtr, (void*)pointVectorPtr); assert(status); } } /* * Add my paths to global list */ list_t* pathVectorListPtr = routerArgPtr->pathVectorListPtr; int mode = 0; TM_BEGIN(2,mode); if (mode == 0) { list_htm::TMlist_insert(TM_ARG pathVectorListPtr, (void*)myPathVectorPtr); } else { list_stm::TMlist_insert(TM_ARG pathVectorListPtr, (void*)myPathVectorPtr); } TM_END(); PGRID_FREE(myGridPtr); PQUEUE_FREE(myExpansionQueuePtr); #if DEBUG puts("\nFinal Grid:"); grid_print(gridPtr); #endif /* DEBUG */ TM_THREAD_EXIT(); }
/* ============================================================================= * PdoTraceback * ============================================================================= */ static vector_t* PdoTraceback (grid_t* gridPtr, grid_t* myGridPtr, coordinate_t* dstPtr, long bendCost) { vector_t* pointVectorPtr = PVECTOR_ALLOC(1); assert(pointVectorPtr); point_t next; next.x = dstPtr->x; next.y = dstPtr->y; next.z = dstPtr->z; next.value = grid_getPoint(myGridPtr, next.x, next.y, next.z); next.momentum = MOMENTUM_ZERO; while (1) { long* gridPointPtr = grid_getPointRef(gridPtr, next.x, next.y, next.z); PVECTOR_PUSHBACK(pointVectorPtr, (void*)gridPointPtr); grid_setPoint(myGridPtr, next.x, next.y, next.z, GRID_POINT_FULL); /* Check if we are done */ if (next.value == 0) { break; } point_t curr = next; /* * Check 6 neighbors * * Potential Optimization: Only need to check 5 of these */ traceToNeighbor(myGridPtr, &curr, &MOVE_POSX, TRUE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_POSY, TRUE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_POSZ, TRUE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGX, TRUE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGY, TRUE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGZ, TRUE, bendCost, &next); #if DEBUG printf("(%li, %li, %li)\n", next.x, next.y, next.z); #endif /* DEBUG */ /* * Because of bend costs, none of the neighbors may appear to be closer. * In this case, pick a neighbor while ignoring momentum. */ if ((curr.x == next.x) && (curr.y == next.y) && (curr.z == next.z)) { next.value = curr.value; traceToNeighbor(myGridPtr, &curr, &MOVE_POSX, FALSE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_POSY, FALSE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_POSZ, FALSE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGX, FALSE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGY, FALSE, bendCost, &next); traceToNeighbor(myGridPtr, &curr, &MOVE_NEGZ, FALSE, bendCost, &next); if ((curr.x == next.x) && (curr.y == next.y) && (curr.z == next.z)) { PVECTOR_FREE(pointVectorPtr); #if DEBUG puts("[dead]"); #endif return NULL; /* cannot find path */ } } } #if DEBUG puts(""); #endif /* DEBUG */ return pointVectorPtr; }
/* ============================================================================= * router_solve * ============================================================================= */ void router_solve (void* argPtr) { TM_THREAD_ENTER(); router_solve_arg_t* routerArgPtr = (router_solve_arg_t*)argPtr; router_t* routerPtr = routerArgPtr->routerPtr; maze_t* mazePtr = routerArgPtr->mazePtr; vector_t* myPathVectorPtr = PVECTOR_ALLOC(1); assert(myPathVectorPtr); queue_t* workQueuePtr = mazePtr->workQueuePtr; grid_t* gridPtr = mazePtr->gridPtr; grid_t* myGridPtr = PGRID_ALLOC(gridPtr->width, gridPtr->height, gridPtr->depth); assert(myGridPtr); long bendCost = routerPtr->bendCost; queue_t* myExpansionQueuePtr = PQUEUE_ALLOC(-1); /* * Iterate over work list to route each path. This involves an * 'expansion' and 'traceback' phase for each source/destination pair. */ while (1) { pair_t* coordinatePairPtr; TM_BEGIN(); if (TMQUEUE_ISEMPTY(workQueuePtr)) { coordinatePairPtr = NULL; } else { coordinatePairPtr = (pair_t*)TMQUEUE_POP(workQueuePtr); } TM_END(); if (coordinatePairPtr == NULL) { break; } coordinate_t* srcPtr = (coordinate_t*)coordinatePairPtr->firstPtr; coordinate_t* dstPtr = (coordinate_t*)coordinatePairPtr->secondPtr; bool success = false; vector_t* pointVectorPtr = NULL; TM_BEGIN(); grid_copy(myGridPtr, gridPtr); /* ok if not most up-to-date */ if (PdoExpansion(routerPtr, myGridPtr, myExpansionQueuePtr, srcPtr, dstPtr)) { pointVectorPtr = PdoTraceback(gridPtr, myGridPtr, dstPtr, bendCost); /* * TODO: fix memory leak * * pointVectorPtr will be a memory leak if we abort this transaction */ if (pointVectorPtr) { TMGRID_ADDPATH(gridPtr, pointVectorPtr); TM_LOCAL_WRITE_L(success, true); } } TM_END(); if (success) { bool status = PVECTOR_PUSHBACK(myPathVectorPtr, (void*)pointVectorPtr); assert(status); } } /* * Add my paths to global list */ list_t* pathVectorListPtr = routerArgPtr->pathVectorListPtr; TM_BEGIN(); TMLIST_INSERT(pathVectorListPtr, (void*)myPathVectorPtr); TM_END(); PGRID_FREE(myGridPtr); PQUEUE_FREE(myExpansionQueuePtr); #if DEBUG puts("\nFinal Grid:"); grid_print(gridPtr); #endif /* DEBUG */ TM_THREAD_EXIT(); }
/* ============================================================================= * getCount * ============================================================================= */ static long getCount (adtree_node_t* nodePtr, long i, long q, vector_t* queryVectorPtr, long lastQueryIndex, adtree_t* adtreePtr) { if (nodePtr == NULL) { return 0; } long nodeIndex = nodePtr->index; if (nodeIndex >= lastQueryIndex) { return nodePtr->count; } long count = 0L; query_t* queryPtr = (query_t*)vector_at(queryVectorPtr, q); if (!queryPtr) { return nodePtr->count; } long queryIndex = queryPtr->index; assert(queryIndex <= lastQueryIndex); vector_t* varyVectorPtr = nodePtr->varyVectorPtr; adtree_vary_t* varyPtr = (adtree_vary_t*)vector_at(varyVectorPtr, (queryIndex - nodeIndex - 1)); assert(varyPtr); long queryValue = queryPtr->value; if (queryValue == varyPtr->mostCommonValue) { /* * We do not explicitly store the counts for the most common value. * We can calculate it by finding the count of the query without * the current (superCount) and subtracting the count for the * query with the current toggled (invertCount). */ long numQuery = vector_getSize(queryVectorPtr); vector_t* superQueryVectorPtr = PVECTOR_ALLOC(numQuery - 1); assert(superQueryVectorPtr); long qq; for (qq = 0; qq < numQuery; qq++) { if (qq != q) { bool_t status = vector_pushBack(superQueryVectorPtr, vector_at(queryVectorPtr, qq)); assert(status); } } long superCount = adtree_getCount(adtreePtr, superQueryVectorPtr); PVECTOR_FREE(superQueryVectorPtr); long invertCount; if (queryValue == 0) { queryPtr->value = 1; invertCount = getCount(nodePtr, i, q, queryVectorPtr, lastQueryIndex, adtreePtr); queryPtr->value = 0; } else { queryPtr->value = 0; invertCount = getCount(nodePtr, i, q, queryVectorPtr, lastQueryIndex, adtreePtr); queryPtr->value = 1; } count += superCount - invertCount; } else { if (queryValue == 0) { count += getCount(varyPtr->zeroNodePtr, (i + 1), (q + 1), queryVectorPtr, lastQueryIndex, adtreePtr); } else if (queryValue == 1) { count += getCount(varyPtr->oneNodePtr, (i + 1), (q + 1), queryVectorPtr, lastQueryIndex, adtreePtr); } else { /* QUERY_VALUE_WILDCARD */ #if 0 count += getCount(varyPtr->zeroNodePtr, (i + 1), (q + 1), queryVectorPtr, lastQueryIndex, adtreePtr); count += getCount(varyPtr->oneNodePtr, (i + 1), (q + 1), queryVectorPtr, lastQueryIndex, adtreePtr); #else assert(0); /* catch bugs in learner */ #endif } } return count; }
/* ============================================================================= * router_solve * ============================================================================= */ void router_solve (void* argPtr) { TM_THREAD_ENTER(); long threadId = thread_getId(); router_solve_arg_t* routerArgPtr = (router_solve_arg_t*)argPtr; router_t* routerPtr = routerArgPtr->routerPtr; maze_t* mazePtr = routerArgPtr->mazePtr; long* numPathArray = routerArgPtr->numPathArray; vector_t* myPathVectorPtr = PVECTOR_ALLOC(1); assert(myPathVectorPtr); queue_t* workQueuePtr = mazePtr->workQueuePtr; grid_t* gridPtr = mazePtr->gridPtr; grid_t* myGridPtr = PGRID_ALLOC(gridPtr->width, gridPtr->height, gridPtr->depth); assert(myGridPtr); long bendCost = routerPtr->bendCost; queue_t* myExpansionQueuePtr = PQUEUE_ALLOC(-1); long numPath = 0; /* * Iterate over work list to route each path. This involves an * 'expansion' and 'traceback' phase for each source/destination pair. */ while ((global_timedExecution && !global_isTerminated) || (!global_timedExecution)) { //while (1) { wait_for_turn(threadId); if (global_timedExecution && global_isTerminated) break; ulong_t beginTime; pair_t* coordinatePairPtr; TM_BEGIN(); beginTime = get_thread_time(); if (TMQUEUE_ISEMPTY(workQueuePtr)) { if (TMQUEUE_ISEMPTY(workQueuePtr)) coordinatePairPtr = NULL; } else { coordinatePairPtr = (pair_t*)TMQUEUE_POP(workQueuePtr); } TM_END(); //add_throughput(threadId , get_thread_time() - beginTime); if (coordinatePairPtr == NULL) { break; } coordinate_t* srcPtr = (coordinate_t*)coordinatePairPtr->firstPtr; coordinate_t* dstPtr = (coordinate_t*)coordinatePairPtr->secondPtr; bool_t success = FALSE; vector_t* pointVectorPtr = NULL; TM_BEGIN(); beginTime = get_thread_time(); grid_copy(myGridPtr, gridPtr); /* ok if not most up-to-date */ if (PdoExpansion(routerPtr, myGridPtr, myExpansionQueuePtr, srcPtr, dstPtr)) { pointVectorPtr = PdoTraceback(gridPtr, myGridPtr, dstPtr, bendCost); /* * TODO: fix memory leak * * pointVectorPtr will be a memory leak if we abort this transaction */ if (pointVectorPtr) { TMGRID_ADDPATH(gridPtr, pointVectorPtr); TM_LOCAL_WRITE_L(success, TRUE); } } TM_END(); add_throughput(threadId , get_thread_time() - beginTime); numPath++; if (success) { bool_t status = PVECTOR_PUSHBACK(myPathVectorPtr, (void*)pointVectorPtr); assert(status); } } numPathArray[threadId] = numPath; /* * Add my paths to global list */ list_t* pathVectorListPtr = routerArgPtr->pathVectorListPtr; TM_BEGIN(); TMLIST_INSERT(pathVectorListPtr, (void*)myPathVectorPtr); TM_END(); PGRID_FREE(myGridPtr); PQUEUE_FREE(myExpansionQueuePtr); #if DEBUG puts("\nFinal Grid:"); grid_print(gridPtr); #endif /* DEBUG */ TM_THREAD_EXIT(); }