/* ============================================================================= * PdoExpansion * ============================================================================= */ static bool_t PdoExpansion (router_t* routerPtr, grid_t* myGridPtr, queue_t* queuePtr, coordinate_t* srcPtr, coordinate_t* dstPtr) { long xCost = routerPtr->xCost; long yCost = routerPtr->yCost; long zCost = routerPtr->zCost; /* * Potential Optimization: Make 'src' the one closest to edge. * This will likely decrease the area of the emitted wave. */ PQUEUE_CLEAR(queuePtr); long* srcGridPointPtr = grid_getPointRef(myGridPtr, srcPtr->x, srcPtr->y, srcPtr->z); PQUEUE_PUSH(queuePtr, (void*)srcGridPointPtr); grid_setPoint(myGridPtr, srcPtr->x, srcPtr->y, srcPtr->z, 0); grid_setPoint(myGridPtr, dstPtr->x, dstPtr->y, dstPtr->z, GRID_POINT_EMPTY); long* dstGridPointPtr = grid_getPointRef(myGridPtr, dstPtr->x, dstPtr->y, dstPtr->z); bool_t isPathFound = FALSE; while (!PQUEUE_ISEMPTY(queuePtr)) { long* gridPointPtr = (long*)PQUEUE_POP(queuePtr); if (gridPointPtr == dstGridPointPtr) { isPathFound = TRUE; break; } long x; long y; long z; grid_getPointIndices(myGridPtr, gridPointPtr, &x, &y, &z); long value = (*gridPointPtr); /* * Check 6 neighbors * * Potential Optimization: Only need to check 5 of these */ PexpandToNeighbor(myGridPtr, x+1, y, z, (value + xCost), queuePtr); PexpandToNeighbor(myGridPtr, x-1, y, z, (value + xCost), queuePtr); PexpandToNeighbor(myGridPtr, x, y+1, z, (value + yCost), queuePtr); PexpandToNeighbor(myGridPtr, x, y-1, z, (value + yCost), queuePtr); PexpandToNeighbor(myGridPtr, x, y, z+1, (value + zCost), queuePtr); PexpandToNeighbor(myGridPtr, x, y, z-1, (value + zCost), queuePtr); } /* iterate over work queue */ #if DEBUG printf("Expansion (%li, %li, %li) -> (%li, %li, %li):\n", srcPtr->x, srcPtr->y, srcPtr->z, dstPtr->x, dstPtr->y, dstPtr->z); grid_print(myGridPtr); #endif /* DEBUG */ return isPathFound; }
static void bfs_do (bfs_t* b, const grid_t* ini_grid, const rule_t* r) { grid_t g; bfs_node_t* n; b->head = NULL; b->tail = NULL; b->trash = NULL; b->dist = (unsigned int)-1; grid_init_with_grid(&g, ini_grid); bfs_do_one(b, NULL, &g); while ((n = bfs_pop_node(b))) { redo_grid(n, &g); if (r->try_match(r, &g) == 0) { #if 1 printf("found\n"); grid_print(&g); printf("\n"); fflush(stdout); #endif for (b->dist = 1; n->parent; n = n->parent, ++b->dist) ; break ; } bfs_do_one(b, n, &g); undo_grid(n, &g); } grid_fini(&g); for (n = b->trash; n; ) { bfs_node_t* const tmp = n; n = n->next; bfs_free_node(tmp); } }
/* * Solves the puzzle and prints results. * Returns 1 on success and 0 on nonexistence of a solution. */ static int solve(int *start, int *end) { Grid *root, *goal, *cur, *child, *iter, **result; Pqueue *pq; Set *visited; int goal_grid_code, child_code; int i, ch; int path_length; root = (Grid *) malloc(sizeof(Grid)); memcpy(root->g, start, sizeof(int) * 9); root->parent = NULL; root->hole = 1; root->depth = 0; goal = (Grid *) malloc(sizeof(Grid)); memcpy(goal->g, end, sizeof(int) * 9); goal_grid_code = grid_code(goal); get_correct_positions(goal); path_length = 0; i = 0; pq = pqueue_new(); visited = set_new(4); pqueue_insert(pq, root); set_insert(visited, grid_code(root)); while (!empty(pq)) { cur = pqueue_extract_min(pq); if (verbose) { fprintf(output, "%d.\n", ++i); fprintf(output, "Depth: %d\n", cur->depth); fprintf(output, "Grid:\n"); grid_print(output, cur); fprintf(output, "f: %2d\n", weight(cur)); fprintf(output, "\n"); } if (grid_code(cur) == goal_grid_code) break; ch = 0; #define ADD_CHILD() { \ child_code = grid_code(child); \ if (!set_contains(visited, child_code)) { \ set_insert(visited, child_code); \ pqueue_insert(pq, child); \ cur->child[ch++] = child; \ } else \ free(child); \ } /* Hole not on the left wall. */ if (cur->hole % 3 > 0) { child = make_child(cur); grid_move_hole(child, child->hole - 1); ADD_CHILD(); } /* Hole not on the right wall. */ if (cur->hole % 3 < 2) { child = make_child(cur); grid_move_hole(child, child->hole + 1); ADD_CHILD(); } /* Hole not on the top wall. */ if (cur->hole / 3 > 0) { child = make_child(cur); grid_move_hole(child, child->hole - 3); ADD_CHILD(); } /* Hole not on the bottom wall. */ if (cur->hole / 3 < 2) { child = make_child(cur); grid_move_hole(child, child->hole + 3); ADD_CHILD(); } #undef ADD_CHILD /* End of children character. */ cur->child[ch] = NULL; if (verbose) { fprintf(output, "Children:\n"); grid_children(output, cur); fprintf(output, "------------------------\n"); fprintf(output, "\n"); STEP(); } } if (grid_code(cur) != goal_grid_code) return 0; /* Collect result path. */ for (iter = cur; iter != NULL; iter = iter->parent) path_length ++; result = (Grid**) malloc(sizeof(Grid*) * path_length); i = path_length - 1; for (iter = cur; iter != NULL; iter = iter->parent) result[i--] = iter; if (verbose) fprintf(output, "Solution sequence:\n"); for (i = 0; i < path_length; i++) { grid_print(output, result[i]); STEP(); fprintf(output, "\n"); } /* Clean up. */ grid_dispose(root); set_dispose(visited); pqueue_dispose(pq); free(result); free(goal); return 1; }
/* ============================================================================= * 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(); }
int main(int ac, char** av) { grid_t g; state_t state; bfs_t b; cmdline_t cmd; rulset_t rulset; const rule_t* ru; unsigned int i; grid_init(&g, 5); state_init(&state); rulset_init(&rulset); /* start with first rule */ state.cur_rule = rulset.rules; while (state.is_done == 0) { cmdline_get(&cmd); switch (cmd.op) { case CMDLINE_OP_PUT_BLOCK: if (state.items[state.cur_color]) { if (*grid_at(&g, cmd.x, cmd.y) == BLOCK_COLOR_INVALID) { *grid_at(&g, cmd.x, cmd.y) = state.cur_color; --state.items[state.cur_color]; } } break ; case CMDLINE_OP_GET_BLOCK: if (*grid_at(&g, cmd.x, cmd.y) != BLOCK_COLOR_INVALID) { ++state.items[*grid_at(&g, cmd.x, cmd.y)]; *grid_at(&g, cmd.x, cmd.y) = BLOCK_COLOR_INVALID; } break ; case CMDLINE_OP_SEL_COLOR: state.cur_color = cmd.color; break ; case CMDLINE_OP_SEL_RULE: ru = rulset.rules; for (i = 0; ru && (i < cmd.rule); ++i, ru = ru->next) ; state.cur_rule = (rule_t*)ru; if (ru == NULL) { printf("no such rule\n"); break ; } goto eval_rule_case; break ; case CMDLINE_OP_LIST_RULES: ru = rulset.rules; for (i = 0; ru; ++i, ru = ru->next) printf("[%u] %u\n", i, ru->outcome); break ; case CMDLINE_OP_LIST_ITEMS: for (i = 0; i < 3; ++i) printf(" %u", state.items[i]); printf("\n"); break ; case CMDLINE_OP_EVAL_RULE: eval_rule_case: if (state.cur_rule == NULL) { printf("no rule selected\n"); break ; } bfs_do(&b, &g, state.cur_rule); state.cur_dist = b.dist; printf("distance: %u\n", state.cur_dist); break ; case CMDLINE_OP_PRINT_GRID: grid_print(&g); break ; case CMDLINE_OP_QUIT: state.is_done = 1; break ; case CMDLINE_OP_INVALID: default: break ; } } grid_fini(&g); rulset_fini(&rulset); return 0; }
Datum LWGEOM_snaptogrid_pointoff(PG_FUNCTION_ARGS) { Datum datum; GSERIALIZED *in_geom, *in_point; LWGEOM *in_lwgeom; LWPOINT *in_lwpoint; GSERIALIZED *out_geom = NULL; LWGEOM *out_lwgeom; gridspec grid; /* BOX3D box3d; */ POINT4D offsetpoint; if ( PG_ARGISNULL(0) ) PG_RETURN_NULL(); datum = PG_GETARG_DATUM(0); in_geom = (GSERIALIZED *)PG_DETOAST_DATUM(datum); if ( PG_ARGISNULL(1) ) PG_RETURN_NULL(); datum = PG_GETARG_DATUM(1); in_point = (GSERIALIZED *)PG_DETOAST_DATUM(datum); in_lwpoint = lwgeom_as_lwpoint(lwgeom_from_gserialized(in_point)); if ( in_lwpoint == NULL ) { lwerror("Offset geometry must be a point"); } if ( PG_ARGISNULL(2) ) PG_RETURN_NULL(); grid.xsize = PG_GETARG_FLOAT8(2); if ( PG_ARGISNULL(3) ) PG_RETURN_NULL(); grid.ysize = PG_GETARG_FLOAT8(3); if ( PG_ARGISNULL(4) ) PG_RETURN_NULL(); grid.zsize = PG_GETARG_FLOAT8(4); if ( PG_ARGISNULL(5) ) PG_RETURN_NULL(); grid.msize = PG_GETARG_FLOAT8(5); /* Take offsets from point geometry */ getPoint4d_p(in_lwpoint->point, 0, &offsetpoint); grid.ipx = offsetpoint.x; grid.ipy = offsetpoint.y; if (FLAGS_GET_Z(in_lwpoint->flags) ) grid.ipz = offsetpoint.z; else grid.ipz=0; if (FLAGS_GET_M(in_lwpoint->flags) ) grid.ipm = offsetpoint.m; else grid.ipm=0; #if POSTGIS_DEBUG_LEVEL >= 4 grid_print(&grid); #endif /* Return input geometry if grid is null */ if ( grid_isNull(&grid) ) { PG_RETURN_POINTER(in_geom); } in_lwgeom = lwgeom_from_gserialized(in_geom); POSTGIS_DEBUGF(3, "SnapToGrid got a %s", lwtype_name(in_lwgeom->type)); out_lwgeom = lwgeom_grid(in_lwgeom, &grid); if ( out_lwgeom == NULL ) PG_RETURN_NULL(); /* COMPUTE_BBOX TAINTING */ if ( in_lwgeom->bbox ) lwgeom_add_bbox(out_lwgeom); POSTGIS_DEBUGF(3, "SnapToGrid made a %s", lwtype_name(out_lwgeom->type)); out_geom = geometry_serialize(out_lwgeom); PG_RETURN_POINTER(out_geom); }
grid* grid_create(void* p, int id) { gridprm* prm = (gridprm*) p; grid* g = calloc(1, sizeof(grid)); char* fname = prm->fname; int ncid; int dimid_x, dimid_y, dimid_z; int varid_x, varid_y, varid_z; int ndims_x, ndims_y, ndims_z; size_t nx, ny, nz; int varid_depth, varid_numlevels; g->name = strdup(prm->name); g->id = id; g->vtype = gridprm_getvtype(prm); g->sfactor = prm->sfactor; #if !defined(NO_GRIDUTILS) #if !defined(GRIDMAP_TYPE_DEF) #error("GRIDMAP_TYPE_DEF not defined; please update gridutils-c"); #endif if (prm->maptype == 'b' || prm->maptype == 'B') g->maptype = GRIDMAP_TYPE_BINARY; else if (prm->maptype == 'k' || prm->maptype == 'K') g->maptype = GRIDMAP_TYPE_KDTREE; else enkf_quit("unknown grid map type \"%c\"", prm->maptype); #endif ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(ncid, prm->xdimname, &dimid_x); ncw_inq_dimid(ncid, prm->ydimname, &dimid_y); ncw_inq_dimid(ncid, prm->zdimname, &dimid_z); ncw_inq_dimlen(ncid, dimid_x, &nx); ncw_inq_dimlen(ncid, dimid_y, &ny); ncw_inq_dimlen(ncid, dimid_z, &nz); ncw_inq_varid(ncid, prm->xvarname, &varid_x); ncw_inq_varid(ncid, prm->yvarname, &varid_y); ncw_inq_varid(ncid, prm->zvarname, &varid_z); ncw_inq_varndims(ncid, varid_x, &ndims_x); ncw_inq_varndims(ncid, varid_y, &ndims_y); ncw_inq_varndims(ncid, varid_z, &ndims_z); if (ndims_x == 1 && ndims_y == 1) { double* x; double* y; double* z; x = malloc(nx * sizeof(double)); y = malloc(ny * sizeof(double)); z = malloc(nz * sizeof(double)); ncw_get_var_double(ncid, varid_x, x); ncw_get_var_double(ncid, varid_y, y); ncw_get_var_double(ncid, varid_z, z); grid_setcoords(g, GRIDHTYPE_LATLON, NT_NONE, nx, ny, nz, x, y, z); } #if !defined(NO_GRIDUTILS) else if (ndims_x == 2 && ndims_y == 2) { double** x; double** y; double* z; x = gu_alloc2d(ny, nx, sizeof(double)); y = gu_alloc2d(ny, nx, sizeof(double)); z = malloc(nz * sizeof(double)); ncw_get_var_double(ncid, varid_x, x[0]); ncw_get_var_double(ncid, varid_y, y[0]); ncw_get_var_double(ncid, varid_z, z); grid_setcoords(g, GRIDHTYPE_CURVILINEAR, NT_COR, nx, ny, nz, x, y, z); } #endif else enkf_quit("%s: could not determine the grid type", fname); if (prm->depthvarname != NULL) { float** depth = alloc2d(ny, nx, sizeof(float)); ncw_inq_varid(ncid, prm->depthvarname, &varid_depth); ncw_get_var_float(ncid, varid_depth, depth[0]); g->depth = depth; } if (prm->levelvarname != NULL) { g->numlevels = alloc2d(ny, nx, sizeof(int)); ncw_inq_varid(ncid, prm->levelvarname, &varid_numlevels); ncw_get_var_int(ncid, varid_numlevels, g->numlevels[0]); if (g->vtype == GRIDVTYPE_SIGMA) { int i, j; for (j = 0; j < ny; ++j) for (i = 0; i < nx; ++i) g->numlevels[j][i] *= nz; } } ncw_close(ncid); if (g->numlevels == NULL) { g->numlevels = alloc2d(ny, nx, sizeof(int)); if (g->vtype == GRIDVTYPE_SIGMA) { int i, j; for (j = 0; j < ny; ++j) for (i = 0; i < nx; ++i) if (g->depth == NULL || g->depth[j][i] > 0.0) g->numlevels[j][i] = nz; } else { int i, j; assert(g->depth != NULL); for (j = 0; j < ny; ++j) { for (i = 0; i < nx; ++i) { double depth = g->depth[j][i]; double fk = NaN; if (depth > 0.0) { z2fk(g, j, i, depth, &fk); g->numlevels[j][i] = ceil(fk + 0.5); } } } } } gridprm_print(prm, " "); grid_print(g, " "); return g; }
grid* grid_create(void* p, int id) { gridprm* prm = (gridprm*) p; grid* g = calloc(1, sizeof(grid)); char* fname = prm->fname; int ncid; int dimid_x, dimid_y, dimid_z; int varid_x, varid_y, varid_z; int ndims_x, ndims_y, ndims_z; size_t nx, ny, nz; int varid_depth, varid_numlevels; g->name = strdup(prm->name); g->id = id; g->vtype = gridprm_getvtype(prm); ncw_open(fname, NC_NOWRITE, &ncid); ncw_inq_dimid(fname, ncid, prm->xdimname, &dimid_x); ncw_inq_dimid(fname, ncid, prm->ydimname, &dimid_y); ncw_inq_dimid(fname, ncid, prm->zdimname, &dimid_z); ncw_inq_dimlen(fname, ncid, dimid_x, &nx); ncw_inq_dimlen(fname, ncid, dimid_y, &ny); ncw_inq_dimlen(fname, ncid, dimid_z, &nz); ncw_inq_varid(fname, ncid, prm->xvarname, &varid_x); ncw_inq_varid(fname, ncid, prm->yvarname, &varid_y); ncw_inq_varid(fname, ncid, prm->zvarname, &varid_z); ncw_inq_varndims(fname, ncid, varid_x, &ndims_x); ncw_inq_varndims(fname, ncid, varid_y, &ndims_y); ncw_inq_varndims(fname, ncid, varid_z, &ndims_z); if (ndims_x == 1 && ndims_y == 1) { double* x; double* y; double* z; int i; double dx, dy; int periodic_x; x = malloc(nx * sizeof(double)); y = malloc(ny * sizeof(double)); z = malloc(nz * sizeof(double)); ncw_get_var_double(fname, ncid, varid_x, x); ncw_get_var_double(fname, ncid, varid_y, y); ncw_get_var_double(fname, ncid, varid_z, z); periodic_x = fabs(fmod(2.0 * x[nx - 1] - x[nx - 2], 360.0) - x[0]) < EPS_LON; dx = (x[nx - 1] - x[0]) / (double) (nx - 1); for (i = 1; i < (int) nx; ++i) if (fabs(x[i] - x[i - 1] - dx) / fabs(dx) > EPS_LON) break; if (i != (int) nx) grid_setcoords(g, GRIDHTYPE_LATLON_IRREGULAR, NT_NONE, periodic_x, 0, nx, ny, nz, x, y, z); else { dy = (y[ny - 1] - y[0]) / (double) (ny - 1); for (i = 1; i < (int) ny; ++i) if (fabs(y[i] - y[i - 1] - dy) / fabs(dy) > EPS_LON) break; if (i != (int) ny) grid_setcoords(g, GRIDHTYPE_LATLON_IRREGULAR, NT_NONE, periodic_x, 0, nx, ny, nz, x, y, z); else grid_setcoords(g, GRIDHTYPE_LATLON_REGULAR, NT_NONE, periodic_x, 0, nx, ny, nz, x, y, z); } } #if !defined(NO_GRIDUTILS) else if (ndims_x == 2 && ndims_y == 2) { double** x; double** y; double* z; x = alloc2d(ny, nx, sizeof(double)); y = alloc2d(ny, nx, sizeof(double)); z = malloc(nz * sizeof(double)); ncw_get_var_double(fname, ncid, varid_x, x[0]); ncw_get_var_double(fname, ncid, varid_y, y[0]); ncw_get_var_double(fname, ncid, varid_z, z); grid_setcoords(g, GRIDHTYPE_CURVILINEAR, NT_COR, 0, 0, nx, ny, nz, x, y, z); } #endif else enkf_quit("%s: could not determine the grid type", fname); if (prm->depthvarname != NULL) { float** depth = alloc2d(ny, nx, sizeof(float)); ncw_inq_varid(fname, ncid, prm->depthvarname, &varid_depth); ncw_get_var_float(fname, ncid, varid_depth, depth[0]); g->depth = depth; } if (prm->levelvarname != NULL) { g->numlevels = alloc2d(ny, nx, sizeof(int)); ncw_inq_varid(fname, ncid, prm->levelvarname, &varid_numlevels); ncw_get_var_int(fname, ncid, varid_numlevels, g->numlevels[0]); if (g->vtype == GRIDVTYPE_SIGMA) { int i, j; for (j = 0; j < ny; ++j) for (i = 0; i < nx; ++i) g->numlevels[j][i] *= nz; } } ncw_close(fname, ncid); if (g->numlevels == NULL && g->depth != NULL) { g->numlevels = alloc2d(ny, nx, sizeof(int)); if (g->vtype == GRIDVTYPE_SIGMA) { int i, j; for (j = 0; j < ny; ++j) for (i = 0; i < nx; ++i) if (g->depth[j][i] > 0.0) g->numlevels[j][i] = nz; } else { int i, j; for (j = 0; j < ny; ++j) { for (i = 0; i < nx; ++i) { double depth = g->depth[j][i]; double fk = NaN; if (depth > 0.0) { z2fk(g, j, i, depth, &fk); g->numlevels[j][i] = ceil(fk + 0.5); } } } } } gridprm_print(prm, " "); grid_print(g, " "); return g; }
/* ============================================================================= * 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(); }
/* ============================================================================= * maze_checkPaths * ============================================================================= */ bool_t maze_checkPaths (maze_t* mazePtr, list_t* pathVectorListPtr, bool_t doPrintPaths) { grid_t* gridPtr = mazePtr->gridPtr; long width = gridPtr->width; long height = gridPtr->height; long depth = gridPtr->depth; long i; /* Mark walls */ grid_t* testGridPtr = grid_alloc(width, height, depth); grid_addPath(testGridPtr, mazePtr->wallVectorPtr); /* Mark sources */ vector_t* srcVectorPtr = mazePtr->srcVectorPtr; long numSrc = vector_getSize(srcVectorPtr); for (i = 0; i < numSrc; i++) { coordinate_t* srcPtr = (coordinate_t*)vector_at(srcVectorPtr, i); grid_setPoint(testGridPtr, srcPtr->x, srcPtr->y, srcPtr->z, 0); } /* Mark destinations */ vector_t* dstVectorPtr = mazePtr->dstVectorPtr; long numDst = vector_getSize(dstVectorPtr); for (i = 0; i < numDst; i++) { coordinate_t* dstPtr = (coordinate_t*)vector_at(dstVectorPtr, i); grid_setPoint(testGridPtr, dstPtr->x, dstPtr->y, dstPtr->z, 0); } /* Make sure path is contiguous and does not overlap */ long id = 0; list_iter_t it; list_iter_reset(&it, pathVectorListPtr); while (list_iter_hasNext(&it)) { vector_t* pathVectorPtr = (vector_t*)list_iter_next(&it); long numPath = vector_getSize(pathVectorPtr); long i; for (i = 0; i < numPath; i++) { id++; vector_t* pointVectorPtr = (vector_t*)vector_at(pathVectorPtr, i); /* Check start */ long* prevGridPointPtr = (long*)vector_at(pointVectorPtr, 0); long x; long y; long z; grid_getPointIndices(gridPtr, prevGridPointPtr, &x, &y, &z); if (grid_getPoint(testGridPtr, x, y, z) != 0) { grid_free(testGridPtr); return FALSE; } coordinate_t prevCoordinate; grid_getPointIndices(gridPtr, prevGridPointPtr, &prevCoordinate.x, &prevCoordinate.y, &prevCoordinate.z); long numPoint = vector_getSize(pointVectorPtr); long j; for (j = 1; j < (numPoint-1); j++) { /* no need to check endpoints */ long* currGridPointPtr = (long*)vector_at(pointVectorPtr, j); coordinate_t currCoordinate; grid_getPointIndices(gridPtr, currGridPointPtr, &currCoordinate.x, &currCoordinate.y, &currCoordinate.z); if (!coordinate_areAdjacent(&currCoordinate, &prevCoordinate)) { grid_free(testGridPtr); return FALSE; } prevCoordinate = currCoordinate; long x = currCoordinate.x; long y = currCoordinate.y; long z = currCoordinate.z; if (grid_getPoint(testGridPtr, x, y, z) != GRID_POINT_EMPTY) { grid_free(testGridPtr); return FALSE; } else { grid_setPoint(testGridPtr, x, y, z, id); } } /* Check end */ long* lastGridPointPtr = (long*)vector_at(pointVectorPtr, j); grid_getPointIndices(gridPtr, lastGridPointPtr, &x, &y, &z); if (grid_getPoint(testGridPtr, x, y, z) != 0) { grid_free(testGridPtr); return FALSE; } } /* iteratate over pathVector */ } /* iterate over pathVectorList */ if (doPrintPaths) { puts("\nRouted Maze:"); grid_print(testGridPtr); } grid_free(testGridPtr); return TRUE; }
/* ============================================================================= * 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(); }