void test_incremental_gc(void) { mrb_state *mrb = mrb_open(); size_t max = ~0, live = 0, total = 0, freed = 0; RVALUE *free; struct heap_page *page; puts("test_incremental_gc"); mrb_garbage_collect(mrb); gc_assert(mrb->gc_state == GC_STATE_NONE); incremental_gc(mrb, max); gc_assert(mrb->gc_state == GC_STATE_MARK); incremental_gc(mrb, max); gc_assert(mrb->gc_state == GC_STATE_MARK); incremental_gc(mrb, max); gc_assert(mrb->gc_state == GC_STATE_SWEEP); page = mrb->heaps; while (page) { RVALUE *p = page->objects; RVALUE *e = p + HEAP_PAGE_SIZE; while (p<e) { if (is_black(&p->as.basic)) { live++; } if (is_gray(&p->as.basic) && !is_dead(mrb, &p->as.basic)) { printf("%p\n", &p->as.basic); } p++; } page = page->next; total += HEAP_PAGE_SIZE; } gc_assert(mrb->gray_list == NULL); incremental_gc(mrb, max); gc_assert(mrb->gc_state == GC_STATE_SWEEP); incremental_gc(mrb, max); gc_assert(mrb->gc_state == GC_STATE_NONE); free = (RVALUE *)mrb->heaps->freelist; while (free) { freed++; free = (RVALUE *)free->as.free.next; } gc_assert(mrb->live == live); gc_assert(mrb->live == total-freed); mrb_close(mrb); }
void mrb_write_barrier(mrb_state *mrb, struct RBasic *obj) { if (!is_black(obj)) return; mrb_assert(!is_dead(mrb, obj)); mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE); paint_gray(obj); obj->gcnext = mrb->atomic_gray_list; mrb->atomic_gray_list = obj; }
void mrb_write_barrier(mrb_state *mrb, struct RBasic *obj) { if (!is_black(obj)) return; gc_assert(!is_dead(mrb, obj)); gc_assert(mrb->gc_state != GC_STATE_NONE); paint_gray(obj); obj->gcnext = mrb->variable_gray_list; mrb->variable_gray_list = obj; }
uchar Fl_MIDIKeyboard::find_key_from_offset(int off, bool low) { if (off < 0 || off > _total_width) return 0; uchar min = _firstkey; // binary search uchar max = _lastkey; uchar mid = min + (max - min) / 2; if (off >= keyscoord[max]) mid = max; else { do { if (off >= keyscoord[mid]) min = mid; else max = mid; mid = min + (max - min) / 2; } while (max - min > 1); } if (low && mid > _firstkey) { // if a black and a white key overlap and low == true, the function returns // the lower key, else the upper if (is_black(mid-1) && keyscoord[mid-1]+_b_width > off) mid--; else if (!is_black(mid-1) && keyscoord[mid-1]+_key_width > off) mid--; } return mid; }
MRB_API void mrb_write_barrier(mrb_state *mrb, struct RBasic *obj) { mrb_gc *gc = &mrb->gc; if (!is_black(obj)) return; mrb_assert(!is_dead(gc, obj)); mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT); paint_gray(obj); obj->gcnext = gc->atomic_gray_list; gc->atomic_gray_list = obj; }
typename ImageFactory<T>::view_type* thin_lc(const T& in) { //typedef typename ImageFactory<T>::data_type data_type; typedef typename ImageFactory<T>::view_type view_type; // Chain to thin_zs view_type* thin_view = thin_zs(in); if (in.nrows() == 1 || in.ncols() == 1) { return thin_view; } try { size_t nrows = thin_view->nrows(); size_t ncols = thin_view->ncols(); typename view_type::vec_iterator it = thin_view->vec_begin(); for (size_t y = 0; y < nrows; ++y) { size_t y_before = (y == 0) ? 1 : y - 1; size_t y_after = (y == nrows - 1) ? nrows - 2 : y + 1; for (size_t x = 0; x < ncols; ++x, ++it) { if (is_black(*it)) { size_t x_before = (x == 0) ? 1 : x - 1; size_t x_after = (x == ncols - 1) ? ncols - 2 : x + 1; size_t j = ((is_black(thin_view->get(Point(x_after, y_after))) << 3) | (is_black(thin_view->get(Point(x_after, y))) << 2) | (is_black(thin_view->get(Point(x_after, y_before))) << 1) | (is_black(thin_view->get(Point(x, y_before))))); size_t i = ((is_black(thin_view->get(Point(x_before, y_before))) << 3) | (is_black(thin_view->get(Point(x_before, y))) << 2) | (is_black(thin_view->get(Point(x_before, y_after))) << 1) | (is_black(thin_view->get(Point(x, y_after))))); if (thin_lc_look_up[i] & (1 << j)) *it = white(*thin_view); } } } } catch (std::exception e) { delete thin_view->data(); delete thin_view; } return thin_view; }
IntVector* projection_cols(const T& image) { IntVector* proj = new IntVector(image.ncols(), 0); try { for (size_t r = 0; r != image.nrows(); ++r) { for (size_t c = 0; c != image.ncols(); ++c) { if (is_black(image.get(Point(c, r)))) { (*proj)[c] += 1; } } } } catch (std::exception e) { delete proj; throw; } return proj; }
void mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value) { if (!is_black(obj)) return; if (!is_white(value)) return; mrb_assert(!is_dead(mrb, value) && !is_dead(mrb, obj)); mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE); if (is_generational(mrb) || mrb->gc_state == GC_STATE_MARK) { add_gray_list(mrb, value); } else { mrb_assert(mrb->gc_state == GC_STATE_SWEEP); paint_partial_white(mrb, obj); /* for never write barriers */ } }
inline IntVector* projection(T i, const T end) { IntVector* proj = new IntVector(end - i, 0); try { typename T::iterator j; typename IntVector::iterator p = proj->begin(); for (; i != end; ++i, ++p) { for (j = i.begin(); j != i.end(); ++j) { if (is_black(*j)) *p += 1; } } } catch (std::exception e) { delete proj; throw; } return proj; }
MRB_API void mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value) { mrb_gc *gc = &mrb->gc; if (!is_black(obj)) return; if (!is_white(value)) return; mrb_assert(gc->state == MRB_GC_STATE_MARK || (!is_dead(gc, value) && !is_dead(gc, obj))); mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT); if (is_generational(gc) || gc->state == MRB_GC_STATE_MARK) { add_gray_list(mrb, gc, value); } else { mrb_assert(gc->state == MRB_GC_STATE_SWEEP); paint_partial_white(gc, obj); /* for never write barriers */ } }
void Fl_MIDIKeyboard::center_keyboard(uchar k) { if (k <= _firstkey) { // k is too low key_position(_firstkey); return; } int nkeys = int(kbdw() / _key_width) + 1; // number of visible white keys int offset = nkeys / 2; // we shift 1/2 nkeys from k if (k > _lastkey || white_keys(k, _lastkey) < nkeys) { // k is too big key_position(_maxbottom); return; } for (int i = 0; i < offset; i++) { if (white_keys(k, _lastkey) == nkeys) break; if (k == _firstkey) break; k--; // shift one white key if(is_black(k)) k--; } key_position(k); }
inline void thin_zs_flag(const T& thin, T& flag, const unsigned char a, const unsigned char b) { register unsigned char p; size_t N, S; for (size_t y = 0; y < thin.nrows(); ++y) { size_t y_before = (y == 0) ? 1 : y - 1; size_t y_after = (y == thin.nrows() - 1) ? thin.nrows() - 2 : y + 1; for (size_t x = 0; x < thin.ncols(); ++x) { if (is_black(thin.get(Point(x, y)))) { thin_zs_get(y, y_before, y_after, x, thin, p, N, S); if ((N <= 6) && (N >= 2) && (S == 1) && !((p & a) == a) && !((p & b) == b)) flag.set(Point(x, y), black(flag)); else flag.set(Point(x, y), white(flag)); } } } }
// ------------------------------------------------------------------- // Determine whether the given move is legal // - from and to must be in [a1..h8] // - promotion piece will be automatically cast to correct colour // ------------------------------------------------------------------- bool ChessBoard::can_move(int from, int to, piece_type promotion) const { // Reject if game is not in progress if (!in_progress) return false; // Reject if that square is not occupied by the player's piece if (w_turn && !is_white(square[from]) || !w_turn && !is_black(square[from])) return false; move_list moves; switch (make_neutral(square[from])) { case King: moves=mobility_king(from); break; case Pawn: moves=mobility_pawn(from); break; case Knight: moves=mobility_knight(from); break; case Bishop: moves=mobility_bishop(from); break; case Rook: moves=mobility_rook(from); break; case Queen: moves=mobility_queen(from); break; } for (move_list::iterator i=moves.begin(); i!=moves.end(); ++i) if ((*i).to==to && (*i).promotion==promotion) return true; return false; }
void print_chesspiece(char p, FILE * f) { char output, black; output = '?'; if (is_black(p)) black = 1; else black = 0; if (is_king(p)) output = 'K'; if (is_queen(p)) output = 'Q'; if (is_rook(p)) output = 'R'; if (is_bishop(p)) output = 'B'; if (is_knight(p)) output = 'N'; if (is_pawn(p)) output = 'P'; if (black) output += 'a' - 'A'; if (is_free(p)) output = ' '; fprintf(f, "%c", output); }
// check color constraints for the subtree rooted at x static bool check_colors(rba_buffer_t *b, uint32_t x) { bool good; uint32_t i, j; if (x == 0) { good = is_black(b, x); if (!good) { printf("error: null node is not black\n"); fflush(stdout); } return good; } i = b->child[x][0]; j = b->child[x][1]; if (is_red(b, x) && (is_red(b, i) || is_red(b, j))) { printf("bad coloring at red node %"PRIu32": its two children should be black\n", x); fflush(stdout); return false; } return check_colors(b, i) && check_colors(b, j); }
char is_white(char p) { return !is_black(p); }
inline bool is_self(const T& v) const { return is_black(v); }
int Fl_MIDIKeyboard::handle(int e) { int ret = Fl_Scroll::handle(e); if (ret && ( // if the event was a keyboard scrolling ... (_type == MKB_HORIZONTAL && Fl::event_inside(&hscrollbar)) || (_type == MKB_VERTICAL &&Fl::event_inside(&scrollbar)))) return 1; // exit _callback_status = 0; switch(e) { case FL_PUSH : take_focus(); if (Fl::event_button1() && (_pressmode & MKB_PRESS_MOUSE)) press_key(_below_mouse); // press the key below mouse return 1; case FL_DRAG : if (!Fl::event_inside(this) || Fl::event_inside(&hscrollbar) || Fl::event_inside(&scrollbar)){ release_key(_below_mouse); // if the mouse leaved the keyboard, release the key _below_mouse = -1; } else { short new_below_mouse = find_key(Fl::event_x(), Fl::event_y()); if (new_below_mouse != _below_mouse) { // the key below mouse changed if (_pressmode & MKB_PRESS_MOUSE) { release_key(_below_mouse); press_key(new_below_mouse); } _below_mouse = new_below_mouse; } } if( (_scrollmode & MKB_SCROLL_MOUSE) && // scrolling with mouse !_autodrag && ( ( _type == MKB_HORIZONTAL && ( Fl::event_inside(x()-20, y(), x(), y()+h()) || Fl::event_inside(x()+w(), y(), x()+w()+20, y()+h()))) || ( _type == MKB_VERTICAL && ( Fl::event_inside(x(), y()-20, x()+w(), y()) || Fl::event_inside(x(), y()+h(), x()+w(), y()+h()+20)))) ) { _autodrag = true; Fl::add_timeout(0.3, autodrag_to, this); } return 1; // idem case FL_RELEASE : release_key(_below_mouse); if (_autodrag) { Fl::remove_timeout(autodrag_to, this); _autodrag = false; } return 1; case FL_ENTER : return 1; case FL_MOVE : _below_mouse = find_key(Fl::event_x(), Fl::event_y()); return 1; case FL_LEAVE : clear_pressed_status(); _below_mouse = -1; return 1; case FL_FOCUS : if (when() & MKB_WHEN_FOCUS) { _callback_status = MKB_FOCUS; do_callback(); } return 1; case FL_UNFOCUS : clear_pressed_status(); if (when() & MKB_WHEN_FOCUS) { _callback_status = MKB_UNFOCUS; do_callback(); } return 1; case FL_KEYDOWN : case FL_KEYUP : if ( (_scrollmode & MKB_SCROLL_KEYS) && (e == FL_KEYDOWN) ) { // handle arrow keys for scrolling switch(Fl::event_key()) { case FL_Left : key_position(is_black(_bottomkey-1) ? _bottomkey-2 : _bottomkey-1); if (_below_mouse != -1) // if mouse is inside the keyboard, recalculate _below_mouse key _below_mouse = find_key(Fl::event_x(), Fl::event_y()); return 1; case FL_Right : key_position(is_black(_bottomkey+1) ? _bottomkey+2 : (is_black(_bottomkey+2) ? _bottomkey+3 : _bottomkey+2)); if (_below_mouse != -1) // if mouse is inside the keyboard, recalculate _below_mouse key _below_mouse = find_key(Fl::event_x(), Fl::event_y()); return 1; default : break; } } if (_pressmode & MKB_PRESS_KEYS) { // handle playback with computer keyboard uchar offs; // is the offset from base C switch(Fl::event_key()) { case 'z' : offs = 0; // C break; case 's' : offs = 1; // C# break; case 'x' : offs = 2; // D break; case 'd' : offs = 3; // D# break; case 'c' : offs = 4; // E break; case 'v' : offs = 5; // F break; case 'g' : offs = 6; // F# break; case 'b' : offs = 7; // G break; case 'h' : offs = 8; // G# break; case 'n' : offs = 9; // A break; case 'j' : offs = 10; // A# break; case 'm' : offs = 11; // B break; case ',' : offs = 12; // C (upper octave) break; case FL_Up : if (_base_keyinput + 12 < _lastkey && e == FL_KEYDOWN) { _base_keyinput += 12; // raise one octave center_keyboard(_base_keyinput + 6); } return 1; case FL_Down : if (_base_keyinput - 12 > _firstkey && e == FL_KEYDOWN) { _base_keyinput -= 12; center_keyboard(_base_keyinput + 6); } return 1; // lower one octave default : return 0; // other keys not recognized } offs += _base_keyinput; // get the actual MIDI note number if (offs < _firstkey || offs > _lastkey) // the key is not in the extension return 0; if (e == FL_KEYDOWN && !pressed_keys[offs]) { //cout << "handle Pressed " << (char)offs << " "; press_key (offs); } if (e == FL_KEYUP && pressed_keys[offs]) { //cout << "handle Released " << (char)offs << " "; release_key(offs); } return 1; } break; default : break; } return ret; }
void rbtree_remove(struct rbtree_node *node, struct rbtree *tree) { struct rbtree_node *parent = get_parent(node); struct rbtree_node *left = node->left; struct rbtree_node *right = node->right; struct rbtree_node *next; enum rb_color color; if (node == tree->first) tree->first = rbtree_next(node); if (node == tree->last) tree->last = rbtree_prev(node); if (!left) next = right; else if (!right) next = left; else next = get_first(right); if (parent) set_child(next, parent, parent->left == node); else tree->root = next; if (left && right) { color = get_color(next); set_color(get_color(node), next); next->left = left; set_parent(next, left); if (next != right) { parent = get_parent(next); set_parent(get_parent(node), next); node = next->right; parent->left = node; next->right = right; set_parent(next, right); } else { set_parent(parent, next); parent = next; node = next->right; } } else { color = get_color(node); node = next; } /* * 'node' is now the sole successor's child and 'parent' its * new parent (since the successor can have been moved). */ if (node) set_parent(parent, node); /* * The 'easy' cases. */ if (color == RB_RED) return; if (node && is_red(node)) { set_color(RB_BLACK, node); return; } do { if (node == tree->root) break; if (node == parent->left) { struct rbtree_node *sibling = parent->right; if (is_red(sibling)) { set_color(RB_BLACK, sibling); set_color(RB_RED, parent); rotate_left(parent, tree); sibling = parent->right; } if ((!sibling->left || is_black(sibling->left)) && (!sibling->right || is_black(sibling->right))) { set_color(RB_RED, sibling); node = parent; parent = get_parent(parent); continue; } if (!sibling->right || is_black(sibling->right)) { set_color(RB_BLACK, sibling->left); set_color(RB_RED, sibling); rotate_right(sibling, tree); sibling = parent->right; } set_color(get_color(parent), sibling); set_color(RB_BLACK, parent); set_color(RB_BLACK, sibling->right); rotate_left(parent, tree); node = tree->root; break; } else { struct rbtree_node *sibling = parent->left; if (is_red(sibling)) { set_color(RB_BLACK, sibling); set_color(RB_RED, parent); rotate_right(parent, tree); sibling = parent->left; } if ((!sibling->left || is_black(sibling->left)) && (!sibling->right || is_black(sibling->right))) { set_color(RB_RED, sibling); node = parent; parent = get_parent(parent); continue; } if (!sibling->left || is_black(sibling->left)) { set_color(RB_BLACK, sibling->right); set_color(RB_RED, sibling); rotate_left(sibling, tree); sibling = parent->left; } set_color(get_color(parent), sibling); set_color(RB_BLACK, parent); set_color(RB_BLACK, sibling->left); rotate_right(parent, tree); node = tree->root; break; } } while (is_black(node)); if (node) set_color(RB_BLACK, node); }
inline bool is_other(const T& v) const { return is_black(v); }
void rbt_delete_item(struct rbt_struct **head_ref,char *key) { static struct rbt_struct **ref[MAX_DEEP]; static bool child[MAX_DEEP]; int ref_c=-1; struct rbt_struct *p=*head_ref; ref[++ref_c]=head_ref; while (p&&simple_strcmp(p->key,key)==0) { if (simple_strcmp2(key,p->key)==-1) { ref[++ref_c]=&p->left; child[ref_c]=LL; p=p->left; } else { ref[++ref_c]=&p->right; child[ref_c]=RR; p=p->right; } } if (p) { struct rbt_struct *u,*g,*s,*l,*r; struct rbt_struct **v; bool c; if (p->right) { u=p->right; ref[++ref_c]=&p->right; child[ref_c]=RR; for (u=p->right;u->left!=0;u=u->left) { ref[++ref_c]=&u->left; child[ref_c]=LL; } //p->val=u->val; /* copy start */ p->val=u->val; free(p->key); p->key=u->key; /* copy end */ v=ref[ref_c]; c=child[ref_c]; ref_c--; *v=u->right; if (ref_c==-1||u->type==R) { free(u); return; } /**/ else { p=*ref[ref_c]; free(u); } } else { u=p; v=ref[ref_c]; c=child[ref_c]; ref_c--; *v=u->right; /*top head deleted or no height violation*/ if (ref_c==-1||u->type==R) { free(u); return; } else { p=*ref[ref_c]; free(u); } } while (ref_c>=0) { if (c==LL) { s=p->right; l=s->left; r=s->right; if (s->type==R) { p->type=R; s->type=B; p->right=l; s->left=p; v=ref[ref_c]; *v=s; ref[++ref_c]=&s->left; s=p->right; l=s->left; r=s->right; } if (!is_black(l)) { s->left=l->right; p->right=l->left; l->type=p->type; l->left=p; l->right=s; p->type=B; v=ref[ref_c]; *v=l; return; } else if (p->type==R) { p->type=R; s->type=B; p->right=l; s->left=p; v=ref[ref_c]; *v=s; return; } else if (!is_black(r)) { p->right=l; s->left=p; r->type=B; v=ref[ref_c]; *v=s; return; } else { s->type=R; c=child[ref_c--]; if (ref_c>=0) p=*ref[ref_c]; } } else { s=p->left; l=s->left; r=s->right; if (s->type==R) { p->type=R; s->type=B; p->left=r; s->right=p; v=ref[ref_c]; *v=s; ref[++ref_c]=&s->right; s=p->left; l=s->left; r=s->right; } if (!is_black(r)) { s->right=r->left; p->left=r->right; r->type=p->type; r->right=p; r->left=s; p->type=B; v=ref[ref_c]; *v=r; return; } else if (p->type==R) { p->type=R; s->type=B; p->left=r; s->right=p; v=ref[ref_c]; *v=s; return; } else if (!is_black(l)) { p->left=r; s->right=p; l->type=B; v=ref[ref_c]; *v=s; return; } else { s->type=R; c=child[ref_c--]; if (ref_c>=0) p=*ref[ref_c]; } } } } }
/** * Remove node from tree. * * @attention * It is assumed that the node is already part of the tree. */ void G_HOT erbtree_remove(erbtree_t *tree, rbnode_t *node) { rbnode_t *removed = node; rbnode_t *parent = get_parent(node); rbnode_t *left = node->left; rbnode_t *right = node->right; rbnode_t *next; enum rbcolor color; erbtree_check(tree); g_assert(size_is_positive(tree->count)); g_assert(node != NULL); g_assert(is_valid(node)); /* Does not verify it is part of THIS tree */ tree->count--; if (node == tree->first) tree->first = erbtree_next(node); if (node == tree->last) tree->last = erbtree_prev(node); if (NULL == left) next = right; else if (NULL == right) next = left; else next = get_first(right); if (parent != NULL) set_child(parent, next, parent->left == node); else tree->root = next; if (left != NULL && right != NULL) { color = get_color(next); set_color(next, get_color(node)); next->left = left; set_parent(left, next); if (next != right) { parent = get_parent(next); set_parent(next, get_parent(node)); node = next->right; parent->left = node; next->right = right; set_parent(right, next); } else { set_parent(next, parent); parent = next; node = next->right; } } else { color = get_color(node); node = next; } /* * 'node' is now the sole successor's child and 'parent' its * new parent (since the successor can have been moved). */ if (node != NULL) set_parent(node, parent); invalidate(removed); /* * The "easy" cases. */ if (color == RB_RED) return; if (node != NULL && is_red(node)) { set_color(node, RB_BLACK); return; } do { if (node == tree->root) break; if (node == parent->left) { rbnode_t *sibling = parent->right; if (is_red(sibling)) { set_color(sibling, RB_BLACK); set_color(parent, RB_RED); rotate_left(tree, parent); sibling = parent->right; } if ( (NULL == sibling->left || is_black(sibling->left)) && (NULL == sibling->right || is_black(sibling->right)) ) { set_color(sibling, RB_RED); node = parent; parent = get_parent(parent); continue; } if (NULL == sibling->right || is_black(sibling->right)) { set_color(sibling->left, RB_BLACK); set_color(sibling, RB_RED); rotate_right(tree, sibling); sibling = parent->right; } set_color(sibling, get_color(parent)); set_color(parent, RB_BLACK); set_color(sibling->right, RB_BLACK); rotate_left(tree, parent); node = tree->root; break; } else { rbnode_t *sibling = parent->left; if (is_red(sibling)) { set_color(sibling, RB_BLACK); set_color(parent, RB_RED); rotate_right(tree, parent); sibling = parent->left; } if ( (NULL == sibling->left || is_black(sibling->left)) && (NULL == sibling->right || is_black(sibling->right)) ) { set_color(sibling, RB_RED); node = parent; parent = get_parent(parent); continue; } if (NULL == sibling->left || is_black(sibling->left)) { set_color(sibling->right, RB_BLACK); set_color(sibling, RB_RED); rotate_left(tree, sibling); sibling = parent->left; } set_color(sibling, get_color(parent)); set_color(parent, RB_BLACK); set_color(sibling->left, RB_BLACK); rotate_right(tree, parent); node = tree->root; break; } } while (is_black(node)); if (node != NULL) set_color(node, RB_BLACK); }
static inline int is_red(struct rbtree_node *node) { return !is_black(node); }
void Fl_MIDIKeyboard::set_keyboard_width(void) { bool _maxbottom_found = false; //_total_width = (int)(_key_width * _white_keys); if (_autoresize) { // autoresize mode: try to autoresize the keyboard and fit it in the widget without need of scrolling int res_min = (int)(kbdw() * (100.0 - _kw_resize_min) / 100); // minimum acceptable width int res_max = (int)(kbdw() * (100.0 + _kw_resize_max) / 100); // maximum acceptable width int old_width = (int)(_old_k_width * _white_keys); if (old_width >= res_min && old_width <= res_max) { if (!_autoresized) { // we are autoresizing for the first time _old_k_width = _key_width; // save old key width _autoresized = true; } _key_width = (float)kbdw() / _white_keys; _total_width = kbdw(); _b_width = (int)(_key_width * _bw_width_ratio); scroll_mode(_scrollmode); // sets scrollbars and keys height //_maxbottom = _firstkey; //_maxbottom_found = true; } else { if (old_width < res_min) { // width less than minimum _key_width = res_min / _white_keys; _total_width = (int)(_key_width * _white_keys); scroll_mode(_scrollmode); _maxbottom = _firstkey; // _maxbottom search would fail if width less than kbdw() _maxbottom_found = true; } else { // width greater than maximum if (_autoresized) { // we are switching from autoresized to normal _autoresized = false; _key_width = _old_k_width; } _total_width = (int)(_key_width * _white_keys); scroll_mode(_scrollmode); } } } else { // not autoresize _key_width = _old_k_width; _total_width = (int)(_key_width * _white_keys); scroll_mode(_scrollmode); if (_total_width <= kbdw()) { // _maxbottom search would fail if width less than kbdw() _maxbottom = _firstkey; _maxbottom_found = true; } } _b_width = (int)(_key_width * _bw_width_ratio); // adjust black keys width _type == MKB_HORIZONTAL ? // resizes the keyboard keyboard->size(_total_width, _key_height ) : keyboard->size(_key_height, _total_width); float offs = 0.0; for (uchar i = _firstkey; i <= _lastkey; i++) { keyscoord[i] = (int)offs; if (is_black(i)) keyscoord[i] -= (int)(_b_width / 2); else offs += _key_width; } if (!_maxbottom_found) _maxbottom = find_key_from_offset(_total_width - kbdw(), false); center_keyboard(); // calls redraw() }
bool is_red(Node<T>* node) const { return !is_black(node); }
/* 删除key */ int h_rbtree_delete(h_rbtree_st *tree, const void *key, uint32_t ksize) { rbtree_node_st *parent, *left, *right, *next; rb_color_t color; int is_left; rbtree_node_st *oldnode = do_lookup(tree, key, ksize, &parent, &is_left); rbtree_node_st *node; if (!oldnode) return -1; node = oldnode; left = node->left; right = node->right; if (node == tree->first) tree->first = rb_next(node); if (node == tree->last) tree->last = rb_prev(node); if (!left) next = right; else if (!right) next = left; else next = get_first(right); if (parent) set_child(next, parent, parent->left == node); else tree->root = next; if (left && right) { color = get_color(next); set_color(get_color(node), next); next->left = left; set_parent(next, left); if (next != right) { parent = get_parent(next); set_parent(get_parent(node), next); node = next->right; parent->left = node; next->right = right; set_parent(next, right); } else { set_parent(parent, next); parent = next; node = next->right; } } else { color = get_color(node); node = next; } /* * 'node' is now the sole successor's child and 'parent' its * new parent (since the successor can have been moved). */ if (node) set_parent(parent, node); /* * The 'easy' cases. */ if (color == RB_RED) goto end_delete; if (node && is_red(node)) { set_color(RB_BLACK, node); goto end_delete; } do { if (node == tree->root) break; if (node == parent->left) { rbtree_node_st *sibling = parent->right; if (is_red(sibling)) { set_color(RB_BLACK, sibling); set_color(RB_RED, parent); rotate_left(tree, parent); sibling = parent->right; } if ((!sibling->left || is_black(sibling->left)) && (!sibling->right || is_black(sibling->right))) { set_color(RB_RED, sibling); node = parent; parent = get_parent(parent); continue; } if (!sibling->right || is_black(sibling->right)) { set_color(RB_BLACK, sibling->left); set_color(RB_RED, sibling); rotate_right(tree, sibling); sibling = parent->right; } set_color(get_color(parent), sibling); set_color(RB_BLACK, parent); set_color(RB_BLACK, sibling->right); rotate_left(tree, parent); node = tree->root; break; } else { rbtree_node_st *sibling = parent->left; if (is_red(sibling)) { set_color(RB_BLACK, sibling); set_color(RB_RED, parent); rotate_right(tree, parent); sibling = parent->left; } if ((!sibling->left || is_black(sibling->left)) && (!sibling->right || is_black(sibling->right))) { set_color(RB_RED, sibling); node = parent; parent = get_parent(parent); continue; } if (!sibling->left || is_black(sibling->left)) { set_color(RB_BLACK, sibling->right); set_color(RB_RED, sibling); rotate_left(tree, sibling); sibling = parent->left; } set_color(get_color(parent), sibling); set_color(RB_BLACK, parent); set_color(RB_BLACK, sibling->left); rotate_right(tree, parent); node = tree->root; break; } } while (is_black(node)); if (node) set_color(RB_BLACK, node); end_delete: if ((void *)tree->data_free) tree->data_free(oldnode->cs.data); h_free(oldnode); tree->nelem--; return 0; }
void test_incremental_gc(void) { mrb_state *mrb = mrb_open(); size_t max = ~0, live = 0, total = 0, freed = 0; RVALUE *free; struct heap_page *page; puts("test_incremental_gc"); change_gen_gc_mode(mrb, FALSE); puts(" in mrb_full_gc"); mrb_full_gc(mrb); mrb_assert(mrb->gc_state == GC_STATE_NONE); puts(" in GC_STATE_NONE"); incremental_gc(mrb, max); mrb_assert(mrb->gc_state == GC_STATE_MARK); puts(" in GC_STATE_MARK"); incremental_gc_until(mrb, GC_STATE_SWEEP); mrb_assert(mrb->gc_state == GC_STATE_SWEEP); puts(" in GC_STATE_SWEEP"); page = mrb->heaps; while (page) { RVALUE *p = page->objects; RVALUE *e = p + MRB_HEAP_PAGE_SIZE; while (p<e) { if (is_black(&p->as.basic)) { live++; } if (is_gray(&p->as.basic) && !is_dead(mrb, &p->as.basic)) { printf("%p\n", &p->as.basic); } p++; } page = page->next; total += MRB_HEAP_PAGE_SIZE; } mrb_assert(mrb->gray_list == NULL); incremental_gc(mrb, max); mrb_assert(mrb->gc_state == GC_STATE_SWEEP); incremental_gc(mrb, max); mrb_assert(mrb->gc_state == GC_STATE_NONE); free = (RVALUE*)mrb->heaps->freelist; while (free) { freed++; free = (RVALUE*)free->as.free.next; } mrb_assert(mrb->live == live); mrb_assert(mrb->live == total-freed); puts("test_incremental_gc(gen)"); incremental_gc_until(mrb, GC_STATE_SWEEP); change_gen_gc_mode(mrb, TRUE); mrb_assert(mrb->gc_full == FALSE); mrb_assert(mrb->gc_state == GC_STATE_NONE); puts(" in minor"); mrb_assert(is_minor_gc(mrb)); mrb_assert(mrb->majorgc_old_threshold > 0); mrb->majorgc_old_threshold = 0; mrb_incremental_gc(mrb); mrb_assert(mrb->gc_full == TRUE); mrb_assert(mrb->gc_state == GC_STATE_NONE); puts(" in major"); mrb_assert(is_major_gc(mrb)); do { mrb_incremental_gc(mrb); } while (mrb->gc_state != GC_STATE_NONE); mrb_assert(mrb->gc_full == FALSE); mrb_close(mrb); }
int main(void) { system_init(); clock_init(); led_init(); led_set(0x01); //show life UART_Init(BAUD); UART_Write("\nInit"); //Show UART life motor_init(); adc_init(); //Enable Analog pins adc_enable(CHANNEL_SENSOR_LEFT); adc_enable(CHANNEL_SENSOR_RIGHT); adc_enable(CHANNEL_SENSOR_FRONT); //Sensor value variables uint16_t sensor_left_value = 0; uint16_t sensor_right_value = 0; uint16_t sensor_front_value = 0; //Analog inputSignal conditioning arrays circBuf_t left_buffer; circBuf_t right_buffer; circBuf_t front_buffer; //Initialise sensor averaging buffers initCircBuf(&left_buffer, ROLLING_AVERAGE_LENGTH); initCircBuf(&right_buffer, ROLLING_AVERAGE_LENGTH); initCircBuf(&front_buffer, ROLLING_AVERAGE_LENGTH); //UART output buffer char buffer[UART_BUFF_SIZE] = {0}; //=====Application specific variables===== //TODO: initialise circbuff circBuf_t sweep_times; initCircBuf(&sweep_times, SWEEP_TIME_MEMORY_LENGTH); short sweep_del_t_last = 0; short sweep_end_t_last = 0; //time when front sensor begins to see grey. uint32_t grey_time_start = 0; bool sweep_ended = FALSE; //set high if the front sensor crosses the line bool front_crossed_black = FALSE; //set high if front finds finish line bool front_crossed_grey = FALSE; bool sensor_update_serviced = TRUE; action current_action = IDLE; int16_t forward_speed = DEFAULT_FORWARD_SPEED; int16_t turn_speed = DEFAULT_SPEED; //Scheduler variables uint32_t t = 0; //Loop control time variables uint32_t maze_logic_t_last = 0; uint32_t sample_t_last = 0; uint32_t UART_t_last = 0; clock_set_ms(0); sei(); // Enable all interrupts UART_Write("ialized\n"); //wait for start command DDRD &= ~BIT(7); PORTD |= BIT(7); //motor_set(128, 128); while((PIND & BIT(7))) { continue; } while(1) { t = clock_get_ms(); //check if a sensor update has occured if ((sensor_update_serviced == FALSE) && (t%MAZE_LOGIC_PERIOD == 0) && (t != maze_logic_t_last)) { sensor_update_serviced = TRUE; // finishing condition is a grey read for a set period if(is_grey(sensor_front_value) && front_crossed_grey == FALSE) { front_crossed_grey = TRUE; grey_time_start = t; //TODO: adjust so that finishing condition is a 1/2 whole sweeps on grey line } else if (is_grey(sensor_front_value) && front_crossed_grey == TRUE) { // if ((grey_time_start + GREY_TIME) <= t ) { // Finish line found. Stop robot. maze_completed(); // wait for button push front_crossed_grey = FALSE; } } else { front_crossed_grey = FALSE; } //see if the front sensor crosses the line in case we run into a gap if(is_black(sensor_front_value)&&front_crossed_black == FALSE) { front_crossed_black = TRUE; //check for false finish line if(front_crossed_grey) front_crossed_grey = FALSE; //false alarm } // when both rear sensors go black, this indicates an intersection (turns included). // try turning left if(is_black(sensor_left_value) && is_black(sensor_right_value)) { sweep_ended = TRUE; motor_set(0, 255); PORTB |= BIT(3); PORTB |= BIT(4); } //when both sensors are completely white this indicates a dead end or a tape-gap else if (is_white(sensor_left_value) && is_white(sensor_right_value)) { sweep_ended = TRUE; PORTB &= ~BIT(3); PORTB &= ~BIT(4); //current_action = ON_WHITE; //Check if the front sensor is on black, or has been during the last sweep. if(is_black(sensor_front_value) | front_crossed_black) motor_set(255, 255); else if (is_white(sensor_front_value)) motor_set(-255, 255); } //sweep to the side that reads the darkest value else if (sensor_left_value + SENSOR_TOLLERANCE < sensor_right_value) { PORTB &= ~BIT(3); PORTB |= BIT(4); if (current_action == SWEEP_LEFT) sweep_ended = TRUE; current_action = SWEEP_RIGHT; motor_set(forward_speed + turn_speed, forward_speed); } else if(sensor_right_value + SENSOR_TOLLERANCE< sensor_left_value) { PORTB |= BIT(3); PORTB &= ~BIT(4); if (current_action == SWEEP_RIGHT) sweep_ended = TRUE; current_action = SWEEP_LEFT; motor_set(forward_speed, forward_speed+ turn_speed); } //If a new sweep started this cycle, find how long it took if (sweep_ended) { //reset front black crossing detection variable sweep_ended = FALSE; if (front_crossed_black) front_crossed_black = FALSE; //Calculate sweep time sweep_del_t_last = t - sweep_end_t_last; sweep_end_t_last = t; writeCircBuf(&sweep_times, sweep_del_t_last); //adjust turn_speed for battery level. if (sweep_del_t_last > IDEAL_SWEEP_TIME) { turn_speed += 5; } if (sweep_del_t_last < IDEAL_SWEEP_TIME) { turn_speed -= 5; } turn_speed = regulate_within(turn_speed, MIN_TURN_SPEED, MAX_TURN_SPEED); } } //Sensor value update if((t%SAMPLE_PERIOD == 0) & (t!=sample_t_last)) { sample_t_last = t; //read in analog values sensor_update(CHANNEL_SENSOR_LEFT, &left_buffer, &sensor_left_value ); sensor_update(CHANNEL_SENSOR_RIGHT, &right_buffer, &sensor_right_value ); sensor_update(CHANNEL_SENSOR_FRONT, &front_buffer, &sensor_front_value ); sensor_update_serviced = FALSE; } //display debug information if((t%UART_PERIOD == 0) & (t != UART_t_last) & UART_ENABLED) { UART_t_last = t; sprintf(buffer, "sweep_time: %u \n", sweep_del_t_last); UART_Write(buffer); sprintf(buffer, "L: %u F: %u R: %u", sensor_left_value, sensor_front_value, sensor_right_value); UART_Write(buffer); UART_Write("\n"); } } }