/* * Set Handle Features */ int nvmed_handle_feature_set(NVMED_HANDLE* nvmed_handle, int feature, int value) { switch(feature) { case HANDLE_DIRECT_IO: if(value) FLAG_SET(nvmed_handle, HANDLE_DIRECT_IO); else FLAG_UNSET(nvmed_handle, HANDLE_DIRECT_IO); break; case HANDLE_SYNC_IO: if(value) FLAG_SET(nvmed_handle, HANDLE_SYNC_IO); else FLAG_UNSET(nvmed_handle, HANDLE_SYNC_IO); break; case HANDLE_HINT_DMEM: if(value) FLAG_SET(nvmed_handle, HANDLE_HINT_DMEM); else FLAG_UNSET(nvmed_handle, HANDLE_HINT_DMEM); break; } return value; }
void HardwareIdList::removeItem(sarch_t id) { uarch_t rwFlags; sarch_t maxIndex; arr.lock.readAcquire(&rwFlags); maxIndex = arr.rsrc.maxIndex; arr.lock.readRelease(rwFlags); if (id > maxIndex) { return; }; arr.lock.writeAcquire(); // If removing first item: if (arr.rsrc.firstValidIndex == id) { arr.rsrc.firstValidIndex = arr.rsrc.arr[id].next; // If is also last item, don't forget to update maxIndex. if (id == arr.rsrc.maxIndex) { arr.rsrc.maxIndex = HWIDLIST_INDEX_INVALID; }; FLAG_UNSET( arr.rsrc.arr[id].flags, HWIDLIST_FLAGS_INDEX_VALID); arr.lock.writeRelease(); return; }; for (sarch_t i=arr.rsrc.firstValidIndex; i != HWIDLIST_INDEX_INVALID; i = arr.rsrc.arr[i].next) { if (arr.rsrc.arr[i].next == id) { if (id == arr.rsrc.maxIndex) { arr.rsrc.maxIndex = i; }; arr.rsrc.arr[i].next = arr.rsrc.arr[id].next; FLAG_UNSET( arr.rsrc.arr[id].flags, HWIDLIST_FLAGS_INDEX_VALID); arr.lock.writeRelease(); return; }; }; arr.lock.writeRelease(); }
void clientInitFocusFlag (Client * c) { ScreenInfo *screen_info; Client *c2; GList *list; guint workspace; g_return_if_fail (c != NULL); TRACE ("client \"%s\" (0x%lx)", c->name, c->window); if (!clientAcceptFocus (c) || (c->type & WINDOW_TYPE_DONT_FOCUS)) { return; } screen_info = c->screen_info; workspace = c->win_workspace; for (list = screen_info->windows_stack; list; list = g_list_next (list)) { c2 = (Client *) list->data; if ((c2->win_workspace == workspace) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_FOCUS)) { FLAG_UNSET (c2->xfwm_flags, XFWM_FLAG_FOCUS); } } FLAG_SET (c->xfwm_flags, XFWM_FLAG_FOCUS); }
int esys_release(struct esys* esys, ocn_entity_token_t token) { if(token >= OCN_MAX_ENTITIES) return OCN_ENTITY_ERR_RANGE; pthread_spin_lock(&esys->lock); struct entityslot* slot = &esys->slots[token]; if(!FLAG_GET(slot->flags, ENTITYSLOT_FLAG_USED)) { pthread_spin_unlock(&esys->lock); return OCN_ENTITY_ERR_NONEXIST; } if(!FLAG_GET(slot->flags, ENTITYSLOT_FLAG_ISOLATED)) { pthread_spin_unlock(&esys->lock); return OCN_ENTITY_ERR_ISOLATED; } /* --- */ FLAG_UNSET(slot->flags, ENTITYSLOT_FLAG_ISOLATED); /* --- */ pthread_spin_unlock(&esys->lock); return OCN_OK; }
void clientUpdateFocus (ScreenInfo *screen_info, Client * c, unsigned short flags) { Client *c2; gboolean restacked; TRACE ("entering"); c2 = ((client_focus != c) ? client_focus : NULL); if ((c) && !clientAcceptFocus (c)) { TRACE ("SKIP_FOCUS set for client \"%s\" (0x%lx)", c->name, c->window); pending_focus = NULL; return; } if ((c) && (c == client_focus) && !(flags & FOCUS_FORCE)) { TRACE ("client \"%s\" (0x%lx) is already focused, ignoring request", c->name, c->window); pending_focus = NULL; return; } client_focus = c; if (c2) { clientSetNetState (c2); clientAdjustFullscreenLayer (c2, FALSE); frameQueueDraw (c2, FALSE); clientUpdateOpacity (c2); } if (c) { user_focus = c; clientInstallColormaps (c); if (flags & FOCUS_SORT) { clientSortRing(c); } if (FLAG_TEST(c->flags, CLIENT_FLAG_DEMANDS_ATTENTION)) { TRACE ("un-setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window); FLAG_UNSET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION); } clientSetNetState (c); restacked = clientAdjustFullscreenLayer (c, TRUE); if (!restacked && screen_info->params->click_to_focus) { clientRaise (c, None); clientSetLastRaise (c); } frameQueueDraw (c, FALSE); clientUpdateOpacity (c); } clientSetNetActiveWindow (screen_info, c, 0); pending_focus = NULL; }
int loop_hook(t_env *e) { if (FLAG_GET(e->flag, MASK_RECALC)) { recalc_scene(e); ft_post_processing(e); ft_printelapsed(e); FLAG_UNSET(e->flag, MASK_RECALC); } mlx_put_image_to_window(e->mlx, e->win, e->screen->img, 0, 0); return (0); }
void I8254Pit::disable(void) { ubit16 disableDelayClks=1000; /** EXPLANATION: * 1. Program the i8254 to stop interrupting. * 2. Unregister our ISR from Interrupt Trib. * InterruptTrib will automatically mask the IRQ pin off if * it determines that there are no more devices actively signaling * on the pin. * * Linux sets the i8254 to mode 0 (i.e, "oneshot"), with a 0 CLK pulse * timeout when it wants to disable it. On two laptops from HP that I * own, this approach generates a spurious IRQ. * * My own approach is to set the chip to mode 0 as well, but with a * non-zero timeout (1000 CLKs {approx 1ms} specifically), forcing it * to generate one last IRQ, and when that IRQ has come in, the device * is effectively "disabled", in the sense that it was a oneshot * timeout, so no more IRQs will be generated. **/ state.lock.acquire(); if (i8254State.smpModeSwitchInProgress) { disableDelayClks = 50000; }; // Write out the oneshot mode (mode 0) control byte. io::write8( i8254_CHAN0_IO_CONTROL, i8254_CHAN0_CONTROL_SELECT_COUNTER | i8254_CHAN0_CONTROL_MODE0_ONESHOT | i8254_CHAN0_CONTROL_COUNTER_WRITE_LOWHIGH); atomicAsm::memoryBarrier(); io::write8(i8254_CHAN0_IO_COUNTER, disableDelayClks & 0xFF); io::write8(i8254_CHAN0_IO_COUNTER, disableDelayClks >> 8); FLAG_UNSET( state.rsrc.flags, ZKCM_TIMERDEV_STATE_FLAGS_ENABLED | ZKCM_TIMERDEV_STATE_FLAGS_SOFT_ENABLED); i8254State.irqState = sI8254State::DISABLING; state.lock.release(); // We unregister the ISR, etc in the ISR when the final IRQ comes in. }
error_t ibmPc_rtc_initialize(void) { error_t ret; ubit8 status1; ret = ibmPc_rtccmos_initialize(); if (ret != ERROR_SUCCESS) { return ret; }; rtccmos::lock(); rtccmos::writeAddressRegister(RTC_REG_STATUS1); status1 = rtccmos::readDataRegister(); // Clear all IRQs. FLAG_UNSET(status1, RTC_STATUS1_FLAGS_PERIODIC_IRQ_ENABLED | RTC_STATUS1_FLAGS_ALARM_IRQ_ENABLED | RTC_STATUS1_FLAGS_UPDATEEND_IRQ_ENABLED); rtccmos::writeAddressRegister(RTC_REG_STATUS1); rtccmos::writeDataRegister(status1); rtccmos::resetAddressRegister(); rtccmos::unlock(); rtccmos24HourTime = FLAG_TEST(status1, RTC_STATUS1_FLAGS_TIME_FORMAT_24HRS); if (!rtccmos24HourTime) { printf(ERROR RTCCMOS"Chip reports 12 hour format time.\n"); }; rtccmosBcdDateTime = !FLAG_TEST(status1, RTC_STATUS1_FLAGS_DATETIME_FORMAT_BIN); if (!rtccmosBcdDateTime) { printf(WARNING RTCCMOS"Date/Time is not in BCD. Possibly " "unstable or non-compliant chip.\n"); }; return ERROR_SUCCESS; }
void clientSetFocus (ScreenInfo *screen_info, Client *c, guint32 timestamp, unsigned short flags) { Client *c2; TRACE ("entering"); c2 = NULL; if ((c) && !(flags & FOCUS_IGNORE_MODAL)) { c2 = clientGetModalFor (c); if (c2) { c = c2; } } c2 = ((client_focus != c) ? client_focus : NULL); if ((c) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)) { TRACE ("setting focus to client \"%s\" (0x%lx) with timestamp %u", c->name, c->window, (unsigned int) timestamp); user_focus = c; if (FLAG_TEST(c->flags, CLIENT_FLAG_DEMANDS_ATTENTION)) { TRACE ("un-setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window); FLAG_UNSET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION); clientSetNetState (c); } if ((c == client_focus) && !(flags & FOCUS_FORCE)) { TRACE ("client \"%s\" (0x%lx) is already focused, ignoring request", c->name, c->window); return; } if (!clientAcceptFocus (c)) { TRACE ("SKIP_FOCUS set for client \"%s\" (0x%lx)", c->name, c->window); return; } if (FLAG_TEST (c->wm_flags, WM_FLAG_INPUT) || !(screen_info->params->focus_hint)) { pending_focus = c; /* * When shaded, the client window is unmapped, so it can not be focused. * Instead, we focus the frame that is still mapped. */ if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED)) { XSetInputFocus (myScreenGetXDisplay (screen_info), c->frame, RevertToPointerRoot, timestamp); } else { XSetInputFocus (myScreenGetXDisplay (screen_info), c->window, RevertToPointerRoot, timestamp); } } else if (flags & FOCUS_TRANSITION) { /* * If we are relying only on the client application to take focus, we need to set the focus * explicitely on our own fallback window otherwise there is a race condition between the * application and the window manager. If the application does not take focus before the * the previously focused window is unmapped (when iconifying or closing for example), the focus * will be reverted to the root window and focus transition will fail. */ clientFocusNone (screen_info, c2, timestamp); } if (FLAG_TEST(c->wm_flags, WM_FLAG_TAKEFOCUS)) { pending_focus = c; sendClientMessage (c->screen_info, c->window, WM_TAKE_FOCUS, timestamp); } } else { TRACE ("setting focus to none"); client_focus = NULL; clientFocusNone (screen_info, c2, timestamp); clientClearDelayedFocus (); } }
static int check_reg_size(struct globals *globals, int minsize, int row, int col) { int rown, coln, n; int neighbors[8][2]; int this_id; int ngbr_id; LARGEINT reg_size; struct RB_TREE *visited; struct rc next, ngbr_rc; struct rclist rilist; int no_check; if (!(FLAG_GET(globals->candidate_flag, row, col))) return minsize; FLAG_UNSET(globals->candidate_flag, row, col); visited = rbtree_create(cmp_rc, sizeof(struct rc)); ngbr_rc.row = row; ngbr_rc.col = col; rbtree_insert(visited, &ngbr_rc); /* get this ID */ Segment_get(&globals->rid_seg, (void *) &this_id, row, col); /* breadth-first search */ next.row = row; next.col = col; rclist_init(&rilist); reg_size = 1; do { globals->find_neighbors(next.row, next.col, neighbors); n = globals->nn - 1; do { rown = neighbors[n][0]; coln = neighbors[n][1]; no_check = 0; if (rown < globals->row_min || rown >= globals->row_max || coln < globals->col_min || coln >= globals->col_max) no_check = 1; if (!no_check && (FLAG_GET(globals->null_flag, rown, coln))) no_check = 1; ngbr_rc.row = rown; ngbr_rc.col = coln; if (!no_check && !rbtree_find(visited, &ngbr_rc)) { rbtree_insert(visited, &ngbr_rc); /* get neighbour ID */ Segment_get(&globals->rid_seg, (void *) &ngbr_id, rown, coln); /* same neighbour */ if (ngbr_id == this_id) { reg_size++; rclist_add(&rilist, rown, coln); FLAG_UNSET(globals->candidate_flag, rown, coln); } } } while (n--); /* end do loop - next neighbor */ } while (rclist_drop(&rilist, &next)); /* while there are cells to check */ rclist_destroy(&rilist); rbtree_destroy(visited); return reg_size; }
static int find_best_neighbour(struct globals *globals, int row, int col, int this_id, struct NB_TREE *nbtree, int *reg_size, struct ngbr_stats **Rbest, int *best_n_row, int *best_n_col) { int rown, coln, n, count; int neighbors[8][2]; struct rc next, ngbr_rc; struct rclist rilist; int no_check; int ngbr_id; struct RB_TREE *visited; struct ngbr_stats Ri, Rk, *Rfound; double sim, best_sim; int best_n_id; int have_Ri; Ri.mean = G_malloc(globals->datasize); Rk.mean = G_malloc(globals->datasize); nbtree_clear(nbtree); FLAG_UNSET(globals->candidate_flag, row, col); visited = rbtree_create(cmp_rc, sizeof(struct rc)); ngbr_rc.row = row; ngbr_rc.col = col; rbtree_insert(visited, &ngbr_rc); /* breadth-first search */ next.row = row; next.col = col; rclist_init(&rilist); count = 1; best_n_id = -1; best_sim = 2; do { have_Ri = 0; globals->find_neighbors(next.row, next.col, neighbors); n = globals->nn - 1; do { rown = neighbors[n][0]; coln = neighbors[n][1]; no_check = 0; if (rown < globals->row_min || rown >= globals->row_max || coln < globals->col_min || coln >= globals->col_max) no_check = 1; if (!no_check && (FLAG_GET(globals->null_flag, rown, coln))) no_check = 1; ngbr_rc.row = rown; ngbr_rc.col = coln; if (!no_check && !rbtree_find(visited, &ngbr_rc)) { rbtree_insert(visited, &ngbr_rc); /* get neighbor ID */ Segment_get(&globals->rid_seg, (void *) &ngbr_id, rown, coln); /* same neighbour */ if (ngbr_id == this_id) { count++; rclist_add(&rilist, rown, coln); FLAG_UNSET(globals->candidate_flag, rown, coln); } else { /* different neighbour */ /* compare to this cell next.row, next.col */ if (!have_Ri) { Segment_get(globals->bands_out, (void *) Ri.mean, next.row, next.col); have_Ri = 1; } Segment_get(globals->bands_out, (void *) Rk.mean, rown, coln); sim = globals->calculate_similarity(&Ri, &Rk, globals); if (best_sim > sim) { best_sim = sim; best_n_id = ngbr_id; *best_n_row = rown; *best_n_col = coln; } /* find in neighbor tree */ Rk.id = ngbr_id; if ((Rfound = nbtree_find(nbtree, &Rk))) { Rfound->count++; if (*Rbest && (*Rbest)->count < Rfound->count) *Rbest = Rfound; } else { Rk.count = 1; Rk.row = rown; Rk.col = coln; nbtree_insert(nbtree, &Rk); if (!(*Rbest)) *Rbest = nbtree_find(nbtree, &Rk); } } } } while (n--); /* end do loop - next neighbor */ } while (rclist_drop(&rilist, &next)); /* while there are cells to check */ rclist_destroy(&rilist); rbtree_destroy(visited); G_free(Ri.mean); G_free(Rk.mean); *reg_size = count; return best_n_id; }
void workspaceSwitch (ScreenInfo *screen_info, gint new_ws, Client * c2, gboolean update_focus, guint32 timestamp) { DisplayInfo *display_info; Client *c, *new_focus; Client *previous; GList *list; Window dr, window; gint rx, ry, wx, wy; unsigned int mask; g_return_if_fail (screen_info != NULL); TRACE ("entering workspaceSwitch"); display_info = screen_info->display_info; if ((new_ws == (gint) screen_info->current_ws) && (screen_info->params->toggle_workspaces)) { new_ws = (gint) screen_info->previous_ws; } if (new_ws == (gint) screen_info->current_ws) { return; } if (screen_info->params->wrap_cycle) { if (new_ws > (gint) screen_info->workspace_count - 1) { new_ws = 0; } if (new_ws < 0) { new_ws = (gint) screen_info->workspace_count - 1; } } else if ((new_ws > (gint) screen_info->workspace_count - 1) || (new_ws < 0)) { return; } screen_info->previous_ws = screen_info->current_ws; screen_info->current_ws = new_ws; new_focus = NULL; previous = NULL; c = clientGetFocus (); if (c2) { clientSetWorkspace (c2, new_ws, FALSE); } if (c) { if (c->type & WINDOW_REGULAR_FOCUSABLE) { previous = c; } if (c2 == c) { new_focus = c2; } } /* First pass: Show, from top to bottom */ for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list)) { c = (Client *) list->data; if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { clientSetWorkspace (c, new_ws, TRUE); } else if (new_ws == (gint) c->win_workspace) { if (!FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED) && !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)) { if (!clientIsTransientOrModal (c) || !clientTransientOrModalHasAncestor (c, new_ws)) { clientShow (c, FALSE); } } } } /* Second pass: Hide from bottom to top */ for (list = screen_info->windows_stack; list; list = g_list_next (list)) { c = (Client *) list->data; if (new_ws != (gint) c->win_workspace) { if (c == previous) { FLAG_SET (previous->xfwm_flags, XFWM_FLAG_FOCUS); clientSetFocus (screen_info, NULL, timestamp, FOCUS_IGNORE_MODAL); } if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { if (!clientIsTransientOrModal (c) || !clientTransientOrModalHasAncestor (c, new_ws)) { clientWithdraw (c, new_ws, FALSE); } } } } /* Third pass: Check for focus, from top to bottom */ for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list)) { c = (Client *) list->data; if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { if ((!new_focus) && (c == previous) && clientSelectMask (c, NULL, 0, WINDOW_REGULAR_FOCUSABLE)) { new_focus = c; } FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_FOCUS); } else if (new_ws == (gint) c->win_workspace) { if ((!new_focus) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_FOCUS)) { new_focus = c; } FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_FOCUS); } } setNetCurrentDesktop (display_info, screen_info->xroot, new_ws); if (!(screen_info->params->click_to_focus)) { if (!(c2) && (XQueryPointer (myScreenGetXDisplay (screen_info), screen_info->xroot, &dr, &window, &rx, &ry, &wx, &wy, &mask))) { c = clientAtPosition (screen_info, rx, ry, NULL); if (c) { new_focus = c; } } } if (update_focus) { if (new_focus) { if ((screen_info->params->click_to_focus) && (screen_info->params->raise_on_click)) { if (!(screen_info->params->raise_on_focus) && !clientIsTopMost (new_focus)) { clientRaise (new_focus, None); } } clientSetFocus (screen_info, new_focus, timestamp, FOCUS_SORT); } else { clientFocusTop (screen_info, WIN_LAYER_FULLSCREEN, timestamp); } } }
int find_con(int r, int c, double *d1, double *d2, DCELL * con1, DCELL * con2) { int ct, low_ct, node_ct; int rr, cc, dor, doc; double dd, shortest; DCELL value; G_set_d_null_value(con1, 1); G_set_d_null_value(con2, 1); *d1 = *d2 = 1.0; shortest = nrows * ncols; for (rr = minr; rr <= maxr; rr++) { for (cc = minc; cc <= maxc; cc++) FLAG_UNSET(seen, rr, cc); } minr = nrows; minc = ncols; maxr = maxc = -1; FLAG_SET(seen, r, c); if (r < minr) minr = r; if (r > maxr) maxr = r; if (c < minc) minc = c; if (c > maxc) maxc = c; node_ct = 0; zero = addpts(zero, r, c, r, c, &node_ct); low_ct = 0; while (1) { ct = low_ct++; if (node_ct <= ct) return 1; rr = zero[ct].r; cc = zero[ct].c; dor = ABS(rr - r); doc = ABS(cc - c); if (rr >= 0 && cc >= 0 && rr < nrows && cc < ncols && zero[ct].d < shortest && !flag_get(mask, rr, cc)) { dseg_get(&con, rr, cc, &value); if (G_is_d_null_value(&value)) zero = addpts(zero, r, c, rr, cc, &node_ct); else if (G_is_d_null_value(con1)) { *con1 = value; *d1 = MIN(dor, doc) * 1.414 + ABS(dor - doc); shortest = *d1 * 2.0 * i_val_l_f; } else if (*con1 == value) { dd = MIN(dor, doc) * 1.414 + ABS(dor - doc); if (dd < *d1) { *d1 = dd; shortest = dd * 2.0 * i_val_l_f; } } else if (G_is_d_null_value(con2)) { *con2 = value; *d2 = MIN(dor, doc) * 1.414 + ABS(dor - doc); shortest = *d2; } else { dd = MIN(dor, doc) * 1.414 + ABS(dor - doc); shortest = MIN(shortest, dd); } } } return 0; }
int do_cum(void) { int r, c, dr, dc; char asp_val, asp_val_down; char is_swale, this_flag_value, flag_value; DCELL value, valued; POINT point; int killer, threshold; int asp_r[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 }; int asp_c[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 }; WAT_ALT wa, wadown; G_message(_("SECTION 3: Accumulating Surface Flow with SFD.")); if (bas_thres <= 0) threshold = 60; else threshold = bas_thres; for (killer = 0; killer < do_points; killer++) { G_percent(killer, do_points, 1); seg_get(&astar_pts, (char *)&point, 0, killer); r = point.r; c = point.c; bseg_get(&asp, &asp_val, r, c); if (asp_val) { dr = r + asp_r[ABS(asp_val)]; dc = c + asp_c[ABS(asp_val)]; } /* skip user-defined depressions */ else dr = dc = -1; bseg_get(&bitflags, &this_flag_value, r, c); FLAG_UNSET(this_flag_value, WORKEDFLAG); if (dr >= 0 && dr < nrows && dc >= 0 && dc < ncols) { /* TODO: do not distribute flow along edges, this causes artifacts */ seg_get(&watalt, (char *)&wa, r, c); value = wa.wat; is_swale = FLAG_GET(this_flag_value, SWALEFLAG); if (fabs(value) >= threshold && !is_swale) { is_swale = 1; FLAG_SET(this_flag_value, SWALEFLAG); } seg_get(&watalt, (char *)&wadown, dr, dc); valued = wadown.wat; if (value > 0) { if (valued > 0) valued += value; else valued -= value; } else { if (valued < 0) valued += value; else valued = value - valued; } wadown.wat = valued; seg_put(&watalt, (char *)&wadown, dr, dc); /* update asp for depression */ if (is_swale || fabs(valued) >= threshold) { bseg_get(&bitflags, &flag_value, dr, dc); FLAG_SET(flag_value, SWALEFLAG); bseg_put(&bitflags, &flag_value, dr, dc); is_swale = 1; } else { if (er_flag && !is_swale && !FLAG_GET(this_flag_value, RUSLEBLOCKFLAG)) slope_length(r, c, dr, dc); } } bseg_put(&bitflags, &this_flag_value, r, c); } G_percent(do_points, do_points, 1); /* finish it */ seg_close(&astar_pts); return 0; }
int do_cum_mfd(void) { int r, c, dr, dc; DCELL value, valued, *wat_nbr; POINT point; WAT_ALT wa; int killer, threshold; /* MFD */ int mfd_cells, stream_cells, swale_cells, astar_not_set, is_null; double *dist_to_nbr, *weight, sum_weight, max_weight; int r_nbr, c_nbr, r_max, c_max, ct_dir, np_side, max_side; double dx, dy; CELL ele, *ele_nbr; char asp_val, asp_val_down; double prop, max_acc; int workedon, edge, is_swale, flat; char *flag_nbr, this_flag_value, flag_value; int asp_r[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 }; int asp_c[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 }; G_message(_("SECTION 3: Accumulating Surface Flow with MFD.")); G_debug(1, "MFD convergence factor set to %d.", c_fac); /* distances to neighbours */ dist_to_nbr = (double *)G_malloc(sides * sizeof(double)); weight = (double *)G_malloc(sides * sizeof(double)); for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (r_nbr, c_nbr) for neighbours */ r_nbr = nextdr[ct_dir]; c_nbr = nextdc[ct_dir]; /* account for rare cases when ns_res != ew_res */ dy = ABS(r_nbr) * window.ns_res; dx = ABS(c_nbr) * window.ew_res; if (ct_dir < 4) dist_to_nbr[ct_dir] = dx + dy; else dist_to_nbr[ct_dir] = sqrt(dx * dx + dy * dy); } flag_nbr = (char *)G_malloc(sides * sizeof(char)); wat_nbr = (DCELL *)G_malloc(sides * sizeof(DCELL)); ele_nbr = (CELL *)G_malloc(sides * sizeof(CELL)); workedon = 0; if (bas_thres <= 0) threshold = 60; else threshold = bas_thres; for (killer = 0; killer < do_points; killer++) { G_percent(killer, do_points, 1); seg_get(&astar_pts, (char *)&point, 0, killer); r = point.r; c = point.c; bseg_get(&asp, &asp_val, r, c); if (asp_val) { dr = r + asp_r[ABS(asp_val)]; dc = c + asp_c[ABS(asp_val)]; } /* skip user-defined depressions */ else dr = dc = -1; /* WORKEDFLAG has been set during A* Search * reversed meaning here: 0 = done, 1 = not yet done */ bseg_get(&bitflags, &this_flag_value, r, c); FLAG_UNSET(this_flag_value, WORKEDFLAG); if (dr >= 0 && dr < nrows && dc >= 0 && dc < ncols) { r_max = dr; c_max = dc; seg_get(&watalt, (char *)&wa, r, c); value = wa.wat; /* get weights */ max_weight = 0; sum_weight = 0; np_side = -1; mfd_cells = 0; stream_cells = 0; swale_cells = 0; astar_not_set = 1; ele = wa.ele; is_null = 0; edge = 0; flat = 1; /* this loop is needed to get the sum of weights */ for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (r_nbr, c_nbr) for neighbours */ r_nbr = r + nextdr[ct_dir]; c_nbr = c + nextdc[ct_dir]; weight[ct_dir] = -1; wat_nbr[ct_dir] = 0; ele_nbr[ct_dir] = 0; /* check if neighbour is within region */ if (r_nbr >= 0 && r_nbr < nrows && c_nbr >= 0 && c_nbr < ncols) { if (dr == r_nbr && dc == c_nbr) np_side = ct_dir; bseg_get(&bitflags, &flag_nbr[ct_dir], r_nbr, c_nbr); seg_get(&watalt, (char *)&wa, r_nbr, c_nbr); wat_nbr[ct_dir] = wa.wat; ele_nbr[ct_dir] = wa.ele; /* check for swale or stream cells */ is_swale = FLAG_GET(flag_nbr[ct_dir], SWALEFLAG); if (is_swale) swale_cells++; if ((ABS(wat_nbr[ct_dir]) + 0.5) >= threshold && ct_dir != np_side && ele_nbr[ct_dir] > ele) stream_cells++; if (FLAG_GET(flag_nbr[ct_dir], WORKEDFLAG)) { if (ele_nbr[ct_dir] != ele) flat = 0; edge = is_null = FLAG_GET(flag_nbr[ct_dir], NULLFLAG); if (!is_null && ele_nbr[ct_dir] <= ele) { if (ele_nbr[ct_dir] < ele) { weight[ct_dir] = mfd_pow(((ele - ele_nbr[ct_dir]) / dist_to_nbr[ct_dir]), c_fac); } if (ele_nbr[ct_dir] == ele) { weight[ct_dir] = mfd_pow((0.5 / dist_to_nbr[ct_dir]), c_fac); } sum_weight += weight[ct_dir]; mfd_cells++; if (weight[ct_dir] > max_weight) { max_weight = weight[ct_dir]; } if (dr == r_nbr && dc == c_nbr) { astar_not_set = 0; } } } } else edge = 1; if (edge) break; } /* do not continue streams along edges, this causes artifacts */ if (edge) { is_swale = FLAG_GET(this_flag_value, SWALEFLAG); if (is_swale && asp_val > 0) { asp_val = -1 * drain[r - r_nbr + 1][c - c_nbr + 1]; bseg_put(&asp, &asp_val, r, c); } bseg_put(&bitflags, &this_flag_value, r, c); continue; } /* honour A * path * mfd_cells == 0: fine, SFD along A * path * mfd_cells == 1 && astar_not_set == 0: fine, SFD along A * path * mfd_cells > 0 && astar_not_set == 1: A * path not included, add to mfd_cells */ /* MFD, A * path not included, add to mfd_cells */ if (mfd_cells > 0 && astar_not_set == 1) { mfd_cells++; sum_weight += max_weight; weight[np_side] = max_weight; max_side = np_side; } /* set flow accumulation for neighbours */ max_acc = -1; max_side = np_side; if (mfd_cells > 1) { prop = 0.0; for (ct_dir = 0; ct_dir < sides; ct_dir++) { r_nbr = r + nextdr[ct_dir]; c_nbr = c + nextdc[ct_dir]; /* check if neighbour is within region */ if (r_nbr >= 0 && r_nbr < nrows && c_nbr >= 0 && c_nbr < ncols && weight[ct_dir] > -0.5) { if (FLAG_GET(flag_nbr[ct_dir], WORKEDFLAG)) { weight[ct_dir] = weight[ct_dir] / sum_weight; /* check everything adds up to 1.0 */ prop += weight[ct_dir]; if (value > 0) { if (wat_nbr[ct_dir] > 0) wat_nbr[ct_dir] += value * weight[ct_dir]; else wat_nbr[ct_dir] -= value * weight[ct_dir]; } else { if (wat_nbr[ct_dir] < 0) wat_nbr[ct_dir] += value * weight[ct_dir]; else wat_nbr[ct_dir] = value * weight[ct_dir] - wat_nbr[ct_dir]; } valued = wat_nbr[ct_dir]; wa.wat = valued; wa.ele = ele_nbr[ct_dir]; seg_put(&watalt, (char *)&wa, r_nbr, c_nbr); /* get main drainage direction */ if (ABS(wat_nbr[ct_dir]) >= max_acc) { max_acc = ABS(wat_nbr[ct_dir]); r_max = r_nbr; c_max = c_nbr; max_side = ct_dir; } } else if (ct_dir == np_side) { /* check for consistency with A * path */ workedon++; } } } /* adjust main drainage direction to A* path if possible */ /*if (fabs(wat_nbr[np_side]) >= max_acc) { max_acc = fabs(wat_nbr[np_side]); r_max = dr; c_max = dc; } */ if (ABS(prop - 1.0) > 5E-6f) { G_warning(_("MFD: cumulative proportion of flow distribution not 1.0 but %f"), prop); } } /* SFD-like accumulation */ else { valued = wat_nbr[np_side]; if (value > 0) { if (valued > 0) valued += value; else valued -= value; } else { if (valued < 0) valued += value; else valued = value - valued; } wa.wat = valued; wa.ele = ele_nbr[np_side]; seg_put(&watalt, (char *)&wa, dr, dc); } /* update asp */ if (dr != r_max || dc != c_max) { if (asp_val < 0) { asp_val = -1 * drain[r - r_max + 1][c - c_max + 1]; } else asp_val = drain[r - r_max + 1][c - c_max + 1]; bseg_put(&asp, &asp_val, r, c); } is_swale = FLAG_GET(this_flag_value, SWALEFLAG); /* start new stream */ value = ABS(value) + 0.5; if (!is_swale && (int)value >= threshold && stream_cells < 1 && swale_cells < 1 && !flat) { FLAG_SET(this_flag_value, SWALEFLAG); is_swale = 1; } /* continue stream */ if (is_swale) { flag_value = flag_nbr[max_side]; FLAG_SET(flag_value, SWALEFLAG); bseg_put(&bitflags, &flag_value, r_max, c_max); } else { if (er_flag && !is_swale && !FLAG_GET(this_flag_value, RUSLEBLOCKFLAG)) slope_length(r, c, r_max, c_max); } } bseg_put(&bitflags, &this_flag_value, r, c); } G_percent(do_points, do_points, 1); /* finish it */ if (workedon) G_warning(_("MFD: A * path already processed when distributing flow: %d of %d cells"), workedon, do_points); seg_close(&astar_pts); G_free(dist_to_nbr); G_free(weight); G_free(wat_nbr); G_free(ele_nbr); G_free(flag_nbr); return 0; }
int do_cum_mfd(void) { int r, c, dr, dc; CELL is_swale; DCELL value, valued, tci_div, sum_contour, cell_size; int killer, threshold; /* MFD */ int mfd_cells, stream_cells, swale_cells, astar_not_set, is_null; double *dist_to_nbr, *contour, *weight, sum_weight, max_weight; int r_nbr, c_nbr, r_max, c_max, ct_dir, np_side; CELL ele, ele_nbr, aspect, is_worked; double prop, max_val; int workedon, edge, flat; int asp_r[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 }; int asp_c[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 }; int this_index, down_index, nbr_index; G_message(_("SECTION 3a: Accumulating Surface Flow with MFD.")); G_debug(1, "MFD convergence factor set to %d.", c_fac); /* distances to neighbours, weights, contour lengths */ dist_to_nbr = (double *)G_malloc(sides * sizeof(double)); weight = (double *)G_malloc(sides * sizeof(double)); contour = (double *)G_malloc(sides * sizeof(double)); cell_size = get_dist(dist_to_nbr, contour); flag_clear_all(worked); workedon = 0; if (bas_thres <= 0) threshold = 60; else threshold = bas_thres; for (killer = 1; killer <= do_points; killer++) { G_percent(killer, do_points, 1); this_index = astar_pts[killer]; seg_index_rc(alt_seg, this_index, &r, &c); FLAG_SET(worked, r, c); aspect = asp[this_index]; if (aspect) { dr = r + asp_r[ABS(aspect)]; dc = c + asp_c[ABS(aspect)]; } else dr = dc = -1; if (dr >= 0 && dr < nrows && dc >= 0 && dc < ncols) { /* if ((dr = astar_pts[killer].downr) > -1) { */ value = wat[this_index]; down_index = SEG_INDEX(wat_seg, dr, dc); /* get weights */ max_weight = 0; sum_weight = 0; np_side = -1; mfd_cells = 0; astar_not_set = 1; ele = alt[this_index]; is_null = 0; edge = 0; /* this loop is needed to get the sum of weights */ for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (r_nbr, c_nbr) for neighbours */ r_nbr = r + nextdr[ct_dir]; c_nbr = c + nextdc[ct_dir]; weight[ct_dir] = -1; if (dr == r_nbr && dc == c_nbr) np_side = ct_dir; /* check that neighbour is within region */ if (r_nbr >= 0 && r_nbr < nrows && c_nbr >= 0 && c_nbr < ncols) { nbr_index = SEG_INDEX(wat_seg, r_nbr, c_nbr); valued = wat[nbr_index]; ele_nbr = alt[nbr_index]; is_worked = FLAG_GET(worked, r_nbr, c_nbr); if (is_worked == 0) { is_null = Rast_is_c_null_value(&ele_nbr); edge = is_null; if (!is_null && ele_nbr <= ele) { if (ele_nbr < ele) { weight[ct_dir] = mfd_pow(((ele - ele_nbr) / dist_to_nbr[ct_dir]), c_fac); } if (ele_nbr == ele) { weight[ct_dir] = mfd_pow((0.5 / dist_to_nbr[ct_dir]), c_fac); } sum_weight += weight[ct_dir]; mfd_cells++; if (weight[ct_dir] > max_weight) { max_weight = weight[ct_dir]; } if (dr == r_nbr && dc == c_nbr) { astar_not_set = 0; } if (value < 0 && valued > 0) wat[nbr_index] = -valued; } } } else edge = 1; if (edge) break; } /* do not distribute flow along edges, this causes artifacts */ if (edge) { continue; } /* honour A * path * mfd_cells == 0: fine, SFD along A * path * mfd_cells == 1 && astar_not_set == 0: fine, SFD along A * path * mfd_cells > 0 && astar_not_set == 1: A * path not included, add to mfd_cells */ /* MFD, A * path not included, add to mfd_cells */ if (mfd_cells > 0 && astar_not_set == 1) { mfd_cells++; sum_weight += max_weight; weight[np_side] = max_weight; } /* set flow accumulation for neighbours */ max_val = -1; tci_div = sum_contour = 0.; if (mfd_cells > 1) { prop = 0.0; for (ct_dir = 0; ct_dir < sides; ct_dir++) { r_nbr = r + nextdr[ct_dir]; c_nbr = c + nextdc[ct_dir]; /* check that neighbour is within region */ if (r_nbr >= 0 && r_nbr < nrows && c_nbr >= 0 && c_nbr < ncols && weight[ct_dir] > -0.5) { is_worked = FLAG_GET(worked, r_nbr, c_nbr); if (is_worked == 0) { nbr_index = SEG_INDEX(wat_seg, r_nbr, c_nbr); weight[ct_dir] = weight[ct_dir] / sum_weight; /* check everything adds up to 1.0 */ prop += weight[ct_dir]; if (atanb_flag) { sum_contour += contour[ct_dir]; tci_div += get_slope_tci(ele, alt[nbr_index], dist_to_nbr[ct_dir]) * weight[ct_dir]; } valued = wat[nbr_index]; if (value > 0) { if (valued > 0) valued += value * weight[ct_dir]; else valued -= value * weight[ct_dir]; } else { if (valued < 0) valued += value * weight[ct_dir]; else valued = value * weight[ct_dir] - valued; } wat[nbr_index] = valued; } else if (ct_dir == np_side) { /* check for consistency with A * path */ workedon++; } } } if (ABS(prop - 1.0) > 5E-6f) { G_warning(_("MFD: cumulative proportion of flow distribution not 1.0 but %f"), prop); } } /* SFD-like accumulation */ else { valued = wat[down_index]; if (value > 0) { if (valued > 0) valued += value; else valued -= value; } else { if (valued < 0) valued += value; else valued = value - valued; } wat[down_index] = valued; if (atanb_flag) { sum_contour = contour[np_side]; tci_div = get_slope_tci(ele, alt[down_index], dist_to_nbr[np_side]); } } /* topographic wetness index ln(a / tan(beta)) and * stream power index a * tan(beta) */ if (atanb_flag) { sca[this_index] = fabs(wat[this_index]) * (cell_size / sum_contour); tanb[this_index] = tci_div; } } } if (workedon) G_warning(n_("MFD: A * path already processed when distributing flow: %d of %d cell", "MFD: A * path already processed when distributing flow: %d of %d cells", do_points), workedon, do_points); G_message(_("SECTION 3b: Adjusting drainage directions.")); for (killer = 1; killer <= do_points; killer++) { G_percent(killer, do_points, 1); this_index = astar_pts[killer]; seg_index_rc(alt_seg, this_index, &r, &c); FLAG_UNSET(worked, r, c); aspect = asp[this_index]; if (aspect) { dr = r + asp_r[ABS(aspect)]; dc = c + asp_c[ABS(aspect)]; } else dr = dc = -1; if (dr >= 0 && dr < nrows && dc >= 0 && dc < ncols) { /* if ((dr = astar_pts[killer].downr) > -1) { */ value = wat[this_index]; down_index = SEG_INDEX(wat_seg, dr, dc); r_max = dr; c_max = dc; /* get max flow accumulation */ max_val = -1; stream_cells = 0; swale_cells = 0; ele = alt[this_index]; is_null = 0; edge = 0; flat = 1; for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (r_nbr, c_nbr) for neighbours */ r_nbr = r + nextdr[ct_dir]; c_nbr = c + nextdc[ct_dir]; /* check that neighbour is within region */ if (r_nbr >= 0 && r_nbr < nrows && c_nbr >= 0 && c_nbr < ncols) { nbr_index = SEG_INDEX(wat_seg, r_nbr, c_nbr); /* check for swale or stream cells */ is_swale = FLAG_GET(swale, r_nbr, c_nbr); if (is_swale) swale_cells++; valued = wat[nbr_index]; ele_nbr = alt[nbr_index]; edge = Rast_is_c_null_value(&ele_nbr); if ((ABS(valued) + 0.5) >= threshold && ele_nbr > ele) stream_cells++; is_worked = !(FLAG_GET(worked, r_nbr, c_nbr)); if (is_worked == 0) { if (ele_nbr != ele) flat = 0; is_null = Rast_is_c_null_value(&ele_nbr); edge = is_null; if (!is_null && ABS(valued) > max_val) { max_val = ABS(valued); r_max = r_nbr; c_max = c_nbr; } } } else edge = 1; if (edge) break; } /* do not distribute flow along edges, this causes artifacts */ if (edge) { is_swale = FLAG_GET(swale, r, c); if (is_swale && aspect > 0) { aspect = -1 * drain[r - r_nbr + 1][c - c_nbr + 1]; asp[this_index] = aspect; } continue; } /* update asp */ if (dr != r_max || dc != c_max) { aspect = drain[r - r_max + 1][c - c_max + 1]; if (asp[this_index] < 0) aspect = -aspect; asp[this_index] = aspect; } is_swale = FLAG_GET(swale, r, c); /* start new stream */ value = ABS(value) + 0.5; if (!is_swale && (int)value >= threshold && stream_cells < 1 && swale_cells < 1 && !flat) { FLAG_SET(swale, r, c); is_swale = 1; } /* continue stream */ if (is_swale) { FLAG_SET(swale, r_max, c_max); } else { if (er_flag && !is_swale) slope_length(r, c, r_max, c_max); } } } G_free(astar_pts); flag_destroy(worked); G_free(dist_to_nbr); G_free(weight); return 0; }
void walkerPageRanger::remapNoInc( VaddrSpace *vaddrSpace, void *vaddr, paddr_t paddr, uarch_t nPages, ubit8 op, uarch_t __kflags ) { uarch_t l0Start, l0Current, l0End; uarch_t l1Start, l1Current, l1Limit, l1End; paddr_t l0Entry, l1Entry; #ifdef CONFIG_ARCH_x86_32_PAE uarch_t l2Start, l2Current, l2Limit, l2End; paddr_t l2Entry; #endif uarch_t archFlags, localFlush; if (nPages == 0) { return; }; localFlush = FLAG_TEST(__kflags, PAGEATTRIB_LOCAL_FLUSH_ONLY); vaddr = reinterpret_cast<void *>( (uarch_t)vaddr & PAGING_BASE_MASK_HIGH ); archFlags = walkerPageRanger::encodeFlags(__kflags); getLevelRanges( vaddr, nPages, &l0Start, &l0End, &l1Start, &l1End #ifdef CONFIG_ARCH_x86_32_PAE ,&l2Start, &l2End #endif ); // This is SRS BSNS. Lock off both address spaces. vaddrSpace->level0Accessor.lock.acquire(); cpuTrib.getCurrentCpuStream()->taskStream.getCurrentThread()->parent ->getVaddrSpaceStream()->vaddrSpace .level0Accessor.lock.acquire(); l0Current = l0Start; for (; l0Current <= l0End; l0Current++) { l0Entry = vaddrSpace->level0Accessor.rsrc->entries[l0Current]; *level1Modifier = l0Entry; tlbControl::flushSingleEntry((void *)level1Accessor); l1Current = ((l0Current == l0Start) ? l1Start : 0); l1Limit = ((l0Current == l0End) ? l1End : (PAGING_L1_NENTRIES - 1)); for (; l1Current <= l1Limit; l1Current++) { #ifdef CONFIG_ARCH_x86_32_PAE l1Entry = level1Accessor->entries[l1Current]; *level2Modifier = l1Entry; tlbControl::flushSingleEntry((void *)level2Accessor); l2Current = (((l0Current == l0Start) && (l1Current == l1Start)) ? l2Start : 0); l2Limit = (((l0Current == l0End) && (l1Current == l1End)) ? l2End : (PAGING_L2_NENTRIES - 1)) for (; l2Current < l2Limit; l2Current++) { l2Entry = level2Accessor->entries[l2Current] & 0xFFF; level2Accessor->entries[l2Current] = 0; level2Accessor->entries[l2Current] |= l2Entry; switch (op) { case WPRANGER_OP_SET: { FLAG_SET( level2Accessor ->entries[l2Current], archFlags); break; }; case WPRANGER_OP_CLEAR: { FLAG_UNSET( level2Accessor ->entries[l2Current], archFlags); break; }; case WPRANGER_OP_SET_PRESENT: { FLAG_SET( level2Accessor ->entries[l2Current], PAGING_L2_PRESENT); break; }; case WPRANGER_OP_CLEAR_PRESENT: { FLAG_UNSET( level2Accessor ->entries[l2Current], PAGING_L2_PRESENT); break; }; case WPRANGER_OP_SET_WRITE: { FLAG_SET( level2Accessor ->entries[l2Current], PAGING_L2_WRITE); break; }; case WPRANGER_OP_CLEAR_WRITE: { FLAG_UNSET( level2Accessor ->entries[l2Current], PAGING_L2_WRITE); break; }; default: break; }; level2Accessor->entries[l2Current] |= paddr; }; #else l1Entry = level1Accessor->entries[l1Current] & 0xFFF; level1Accessor->entries[l1Current] = 0; level1Accessor->entries[l1Current] |= l1Entry; switch (op) { case WPRANGER_OP_SET: { FLAG_SET( level1Accessor->entries[l1Current], archFlags); break; }; case WPRANGER_OP_CLEAR: { FLAG_UNSET( level1Accessor->entries[l1Current], archFlags); break; }; case WPRANGER_OP_SET_PRESENT: { FLAG_SET( level1Accessor ->entries[l1Current], PAGING_L1_PRESENT); break; }; case WPRANGER_OP_CLEAR_PRESENT: { FLAG_UNSET( level1Accessor ->entries[l1Current], PAGING_L1_PRESENT); break; }; case WPRANGER_OP_SET_WRITE: { FLAG_SET( level1Accessor ->entries[l1Current], PAGING_L1_WRITE); break; }; case WPRANGER_OP_CLEAR_WRITE: { FLAG_UNSET( level1Accessor ->entries[l1Current], PAGING_L1_WRITE); break; }; default: break; }; level1Accessor->entries[l1Current] |= paddr; #endif }; }; #if __SCALING__ > SCALING_SMP if (localFlush) { tlbControl::flushEntryRange(vaddr, nPages); } else { tlbControl::smpFlushEntryRange(vaddr, nPages); }; #else tlbControl::flushEntryRange(vaddr, nPages); #endif vaddrSpace->level0Accessor.lock.release(); cpuTrib.getCurrentCpuStream()->taskStream.getCurrentThread()->parent ->getVaddrSpaceStream()->vaddrSpace .level0Accessor.lock.release(); /* FIXME: * Insert code here to propagate possible changes to the kernel * address space into the other process address spaces. **/ // We make the assumption that this did not fail. }
int do_astar(void) { int r, c, r_nbr, c_nbr, ct_dir; GW_LARGE_INT first_cum, count; int nextdr[8] = { 1, -1, 0, 0, -1, 1, 1, -1 }; int nextdc[8] = { 0, 0, -1, 1, 1, -1, 1, -1 }; CELL ele_val, ele_up, ele_nbr[8]; WAT_ALT wa; ASP_FLAG af; char is_in_list, is_worked; HEAP_PNT heap_p; /* sides * |7|1|4| * |2| |3| * |5|0|6| */ int nbr_ew[8] = { 0, 1, 2, 3, 1, 0, 0, 1 }; int nbr_ns[8] = { 0, 1, 2, 3, 3, 2, 3, 2 }; double dx, dy, dist_to_nbr[8], ew_res, ns_res; double slope[8]; struct Cell_head window; int skip_diag; count = 0; first_cum = n_points; G_message(_("A* Search...")); Rast_get_window(&window); for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (r_nbr, c_nbr) for neighbours */ r_nbr = nextdr[ct_dir]; c_nbr = nextdc[ct_dir]; /* account for rare cases when ns_res != ew_res */ dy = abs(r_nbr) * window.ns_res; dx = abs(c_nbr) * window.ew_res; if (ct_dir < 4) dist_to_nbr[ct_dir] = dx + dy; else dist_to_nbr[ct_dir] = sqrt(dx * dx + dy * dy); } ew_res = window.ew_res; ns_res = window.ns_res; while (heap_size > 0) { G_percent(count++, n_points, 1); if (count > n_points) G_fatal_error(_("%lld surplus points"), heap_size); if (heap_size > n_points) G_fatal_error (_("Too many points in heap %lld, should be %lld"), heap_size, n_points); heap_p = heap_drop(); r = heap_p.pnt.r; c = heap_p.pnt.c; ele_val = heap_p.ele; for (ct_dir = 0; ct_dir < sides; ct_dir++) { /* get r, c (r_nbr, c_nbr) for neighbours */ r_nbr = r + nextdr[ct_dir]; c_nbr = c + nextdc[ct_dir]; slope[ct_dir] = ele_nbr[ct_dir] = 0; skip_diag = 0; /* check that neighbour is within region */ if (r_nbr < 0 || r_nbr >= nrows || c_nbr < 0 || c_nbr >= ncols) continue; seg_get(&aspflag, (char *)&af, r_nbr, c_nbr); is_in_list = FLAG_GET(af.flag, INLISTFLAG); is_worked = FLAG_GET(af.flag, WORKEDFLAG); if (!is_worked) { seg_get(&watalt, (char *)&wa, r_nbr, c_nbr); ele_nbr[ct_dir] = wa.ele; slope[ct_dir] = get_slope(ele_val, ele_nbr[ct_dir], dist_to_nbr[ct_dir]); } /* avoid diagonal flow direction bias */ if (!is_in_list) { if (ct_dir > 3 && slope[ct_dir] > 0) { if (slope[nbr_ew[ct_dir]] > 0) { /* slope to ew nbr > slope to center */ if (slope[ct_dir] < get_slope(ele_nbr[nbr_ew[ct_dir]], ele_nbr[ct_dir], ew_res)) skip_diag = 1; } if (!skip_diag && slope[nbr_ns[ct_dir]] > 0) { /* slope to ns nbr > slope to center */ if (slope[ct_dir] < get_slope(ele_nbr[nbr_ns[ct_dir]], ele_nbr[ct_dir], ns_res)) skip_diag = 1; } } } if (!skip_diag) { if (is_in_list == 0) { ele_up = ele_nbr[ct_dir]; af.asp = drain[r_nbr - r + 1][c_nbr - c + 1]; heap_add(r_nbr, c_nbr, ele_up); FLAG_SET(af.flag, INLISTFLAG); seg_put(&aspflag, (char *)&af, r_nbr, c_nbr); } else if (is_in_list && is_worked == 0) { if (FLAG_GET(af.flag, EDGEFLAG)) { /* neighbour is edge in list, not yet worked */ if (af.asp < 0) { /* adjust flow direction for edge cell */ af.asp = drain[r_nbr - r + 1][c_nbr - c + 1]; seg_put(&aspflag, (char *)&af, r_nbr, c_nbr); } } else if (FLAG_GET(af.flag, DEPRFLAG)) { G_debug(3, "real depression"); /* neighbour is inside real depression, not yet worked */ if (af.asp == 0 && ele_val <= ele_nbr[ct_dir]) { af.asp = drain[r_nbr - r + 1][c_nbr - c + 1]; FLAG_UNSET(af.flag, DEPRFLAG); seg_put(&aspflag, (char *)&af, r_nbr, c_nbr); } } } } } /* end neighbours */ /* add astar points to sorted list for flow accumulation and stream extraction */ first_cum--; seg_put(&astar_pts, (char *)&heap_p.pnt, 0, first_cum); seg_get(&aspflag, (char *)&af, r, c); FLAG_SET(af.flag, WORKEDFLAG); seg_put(&aspflag, (char *)&af, r, c); } /* end A* search */ G_percent(n_points, n_points, 1); /* finish it */ return 1; }
int thin_seg(int stream_id) { int thinned = 0; int r, c, r_nbr, c_nbr, last_r, last_c; CELL curr_stream, no_stream = 0; int asp_r[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 }; int asp_c[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 }; ASP_FLAG af; r = stream_node[stream_id].r; c = stream_node[stream_id].c; cseg_get(&stream, &curr_stream, r, c); seg_get(&aspflag, (char *)&af, r, c); if (af.asp > 0) { /* get downstream point */ last_r = r + asp_r[(int)af.asp]; last_c = c + asp_c[(int)af.asp]; cseg_get(&stream, &curr_stream, last_r, last_c); if (curr_stream != stream_id) return thinned; /* get next downstream point */ seg_get(&aspflag, (char *)&af, last_r, last_c); while (af.asp > 0) { r_nbr = last_r + asp_r[(int)af.asp]; c_nbr = last_c + asp_c[(int)af.asp]; if (r_nbr == last_r && c_nbr == last_c) return thinned; if (r_nbr < 0 || r_nbr >= nrows || c_nbr < 0 || c_nbr >= ncols) return thinned; cseg_get(&stream, &curr_stream, r_nbr, c_nbr); if (curr_stream != stream_id) return thinned; if (abs(r_nbr - r) < 2 && abs(c_nbr - c) < 2) { /* eliminate last point */ cseg_put(&stream, &no_stream, last_r, last_c); FLAG_UNSET(af.flag, STREAMFLAG); seg_put(&aspflag, (char *)&af, last_r, last_c); /* update start point */ seg_get(&aspflag, (char *)&af, r, c); af.asp = drain[r - r_nbr + 1][c - c_nbr + 1]; seg_put(&aspflag, (char *)&af, r, c); thinned = 1; } else { /* nothing to eliminate, continue from last point */ r = last_r; c = last_c; } last_r = r_nbr; last_c = c_nbr; seg_get(&aspflag, (char *)&af, last_r, last_c); } } return thinned; }
status_t I8254Pit::isr(ZkcmDeviceBase *self, ubit32 flags) { (void) flags; ubit32 devFlags; sZkcmTimerEvent *irqEvent; I8254Pit *device; error_t err; modeE mode; /** EXPLANATION: * 1. Check to make sure that this is not a "disabling" IRQ which is * meant to cause the i8254 to stop sending in IRQs. If it is the * disabling IRQ, unregister the ISR and exit. * 2. If this is not a disabling IRQ, queue an event and exit. **/ device = static_cast<I8254Pit *>( self ); device->state.lock.acquire(); devFlags = device->state.rsrc.flags; mode = device->state.rsrc.mode; // If this is the "disabling" final cleanup IRQ: if (device->i8254State.irqState == sI8254State::DISABLING) { device->i8254State.isrRegistered = 0; device->i8254State.irqState = sI8254State::DISABLED; device->state.lock.release(); // Part of the IBM-PC Symmetric IO mode switch. if (device->i8254State.smpModeSwitchInProgress) { // Release the lock and exit. taskTrib.unblock( device->i8254State.smpModeSwitchThread); }; return ZKCM_ISR_SUCCESS_AND_RETIRE_ME; }; // Small state machine cleanup for oneshot mode: unset the ENABLED flag. if (mode == ONESHOT) { FLAG_UNSET( device->state.rsrc.flags, ZKCM_TIMERDEV_STATE_FLAGS_ENABLED | ZKCM_TIMERDEV_STATE_FLAGS_SOFT_ENABLED); }; device->state.lock.release(); // Don't claim the IRQ if the timer hadn't been enabled. if (!FLAG_TEST(devFlags, ZKCM_TIMERDEV_STATE_FLAGS_ENABLED)) { return ZKCM_ISR_NOT_MY_IRQ; }; device->sendEoi(); // Invoke the system clock update routine if installed on this device. if (device->clockRoutine != NULL) { // Accesses state without the lock. Safe. (*device->clockRoutine)( (mode == ONESHOT) ? device->state.rsrc.currentTimeout.nseconds : device->state.rsrc.currentInterval.nseconds); }; // Create an event. if (!FLAG_TEST(devFlags, ZKCM_TIMERDEV_STATE_FLAGS_SOFT_ENABLED)) { return ZKCM_ISR_SUCCESS; }; irqEvent = device->allocateIrqEvent(); // Note well, this is faultable memory being allocated. if (irqEvent == NULL) { printf(WARNING i8254"isr: Couldn't allocate IRQ event.\n"); // FIXME: I don't like this return value. return ZKCM_ISR_SUCCESS; }; // Fill out the event and queue it. irqEvent->device = device; device->getLatchState( &irqEvent->latchedStream); timerTrib.getCurrentDateTime(&irqEvent->irqStamp); err = device->irqEventQueue.addItem(irqEvent); if (err != ERROR_SUCCESS) { device->freeIrqEvent(irqEvent); printf(WARNING i8254"isr: Failed to queue IRQ event; " "err %s.\n", strerror(err)); }; return ZKCM_ISR_SUCCESS; }
int create_isegs(struct globals *globals) { int row, col; int successflag = 1; int have_bound, rid; CELL current_bound, bounds_val; if (globals->bounds_map == NULL) { /* just one time through loop */ successflag = globals->method_fn(globals); } else { /* outer processing loop for polygon constraints */ for (current_bound = globals->lower_bound; current_bound <= globals->upper_bound; current_bound++) { G_debug(1, "current_bound = %d", current_bound); have_bound = 0; /* get min/max row/col to narrow the processing window */ globals->row_min = globals->nrows; globals->row_max = 0; globals->col_min = globals->ncols; globals->col_max = 0; for (row = 0; row < globals->nrows; row++) { for (col = 0; col < globals->ncols; col++) { FLAG_SET(globals->null_flag, row, col); Segment_get(&globals->bounds_seg, &bounds_val, row, col); if (!Rast_is_c_null_value(&bounds_val) && bounds_val == current_bound) { Segment_get(&globals->rid_seg, &rid, row, col); if (!Rast_is_c_null_value(&rid)) { have_bound = 1; FLAG_UNSET(globals->null_flag, row, col); if (globals->row_min > row) globals->row_min = row; if (globals->row_max < row) globals->row_max = row; if (globals->col_min > col) globals->col_min = col; if (globals->col_max < col) globals->col_max = col; } } } } globals->row_max++; globals->col_max++; if (have_bound) successflag = globals->method_fn(globals); } /* end outer loop for processing polygons */ /* restore NULL flag */ flag_clear_all(globals->null_flag); for (row = 0; row < globals->nrows; row++) { for (col = 0; col < globals->ncols; col++) { Segment_get(&globals->rid_seg, &rid, row, col); if (Rast_is_c_null_value(&rid)) FLAG_SET(globals->null_flag, row, col); } } } return successflag; }
void Indep(void) { int Count, DRow, DCol; int Found, R, C; double RowDist, RowDistSq, ColDist; struct History history; G_debug(2, "indep()"); Count = 0; Found = 0; while (CellCount > 0) { G_debug(3, "(CellCount):%d", CellCount); G_debug(3, "(Count):%d", Count); DRow = DoNext[Count].R; DCol = DoNext[Count++].C; if (0 != FlagGet(Cells, DRow, DCol)) { /* FLAG_SET( Out, DRow, DCol); */ Out[DRow][DCol] = ++Found; for (R = DRow; R < Rs; R++) { RowDist = NS * (R - DRow); if (RowDist > MaxDistSq) { R = Rs; } else { RowDistSq = RowDist * RowDist; for (C = DCol; C < Cs; C++) { ColDist = EW * (C - DCol); G_debug(3, "(RowDistSq):%.12lf", RowDistSq); G_debug(3, "(ColDist):%.12lf", ColDist); G_debug(3, "(MaxDistSq):%.12lf", MaxDistSq); if (MaxDistSq >= RowDistSq + ColDist * ColDist) { if (0 != FlagGet(Cells, R, C)) { G_debug(2, "unset()"); FLAG_UNSET(Cells, R, C); CellCount--; } } else { C = Cs; } } } } G_debug(2, "it1()"); for (R = DRow - 1; R >= 0; R--) { RowDist = NS * (DRow - R); if (RowDist > MaxDistSq) { R = 0; } else { RowDistSq = RowDist * RowDist; for (C = DCol; C < Cs; C++) { ColDist = EW * (C - DCol); if (MaxDistSq >= RowDistSq + ColDist * ColDist) { if (0 != FlagGet(Cells, R, C)) { G_debug(2, "unset()"); FLAG_UNSET(Cells, R, C); CellCount--; } } else { C = Cs; } } } } G_debug(2, "it2()"); for (R = DRow; R < Rs; R++) { RowDist = NS * (R - DRow); if (RowDist > MaxDistSq) { R = Rs; } else { RowDistSq = RowDist * RowDist; for (C = DCol - 1; C >= 0; C--) { ColDist = EW * (DCol - C); if (MaxDistSq >= RowDistSq + ColDist * ColDist) { if (0 != FlagGet(Cells, R, C)) { G_debug(2, "unset()"); FLAG_UNSET(Cells, R, C); CellCount--; } } else { C = 0; } } } } G_debug(2, "it3()"); for (R = DRow - 1; R >= 0; R--) { RowDist = NS * (DRow - R); if (RowDist > MaxDistSq) { R = 0; } else { RowDistSq = RowDist * RowDist; for (C = DCol - 1; C >= 0; C--) { ColDist = EW * (DCol - C); if (MaxDistSq >= RowDistSq + ColDist * ColDist) { if (0 != FlagGet(Cells, R, C)) { G_debug(2, "unset()"); FLAG_UNSET(Cells, R, C); CellCount--; } } else { C = 0; } } } } } } G_debug(2, "outputting()"); OutFD = Rast_open_c_new(Output->answer); G_message(_("Writing raster map <%s>..."), Output->answer); for (R = 0; R < Rs; R++) { G_percent(R, Rs, 2); for (C = 0; C < Cs; C++) { CellBuffer[C] = Out[R][C]; } Rast_put_row(OutFD, CellBuffer, CELL_TYPE); } G_percent(1, 1, 1); Rast_close(OutFD); Rast_short_history(Output->answer, "raster", &history); Rast_command_history(&history); Rast_write_history(Output->answer, &history); }