/* ============================================================================= * TMaddToBadVector * ============================================================================= */ void TMaddToBadVector (TM_ARGDECL vector_t* badVectorPtr, element_t* badElementPtr) { bool_t status = PVECTOR_PUSHBACK(badVectorPtr, (void*)badElementPtr); assert(status); TMELEMENT_SETISREFERENCED(badElementPtr, TRUE); }
/* ============================================================================= * 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; }
/* ============================================================================= * processPackets * ============================================================================= */ void processPackets (void* argPtr) { TM_THREAD_ENTER(); long threadId = thread_getId(); stream_t* streamPtr = ((arg_t*)argPtr)->streamPtr; decoder_t* decoderPtr = ((arg_t*)argPtr)->decoderPtr; vector_t** errorVectors = ((arg_t*)argPtr)->errorVectors; detector_t* detectorPtr = PDETECTOR_ALLOC(); assert(detectorPtr); PDETECTOR_ADDPREPROCESSOR(detectorPtr, &preprocessor_toLower); vector_t* errorVectorPtr = errorVectors[threadId]; while (1) { char* bytes; unsigned int locks[1]; TM_BEGIN(); SINGLE_LOCK(streamPtr); bytes = TMSTREAM_GETPACKET(streamPtr); SINGLE_UNLOCK(streamPtr); TM_END(); if (!bytes) { break; } packet_t* packetPtr = (packet_t*)bytes; long flowId = packetPtr->flowId; error_t error; TM_BEGIN(); error = TMDECODER_PROCESS(decoderPtr, bytes, (PACKET_HEADER_LENGTH + packetPtr->length)); TM_END(); if (error) { /* * Currently, stream_generate() does not create these errors. */ assert(0); bool_t status = PVECTOR_PUSHBACK(errorVectorPtr, (void*)flowId); assert(status); } char* data; long decodedFlowId; TM_BEGIN(); SINGLE_LOCK(decoderPtr); data = TMDECODER_GETCOMPLETE(decoderPtr, &decodedFlowId); SINGLE_UNLOCK(decoderPtr); TM_END(); if (data) { error_t error = PDETECTOR_PROCESS(detectorPtr, data); P_FREE(data); if (error) { bool_t status = PVECTOR_PUSHBACK(errorVectorPtr, (void*)decodedFlowId); assert(status); } } } PDETECTOR_FREE(detectorPtr); TM_THREAD_EXIT(); }
/* ============================================================================= * 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(); }
/* ============================================================================= * 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(); }