Beispiel #1
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");

  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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
  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;
  }
Beispiel #7
0
  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;
  }
Beispiel #8
0
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 */
  }
}
Beispiel #9
0
  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;
  }
Beispiel #10
0
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 */
  }
}
Beispiel #11
0
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);
}
Beispiel #12
0
  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));
	}
      }
    }
  }
Beispiel #13
0
// -------------------------------------------------------------------
// 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;
}
Beispiel #14
0
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);
}
Beispiel #15
0
// 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);
}
Beispiel #16
0
char is_white(char p)
{
    return !is_black(p);
}
Beispiel #17
0
      inline bool is_self(const T& v) const {
	return is_black(v);
      }
Beispiel #18
0
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;
}
Beispiel #19
0
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);
}
Beispiel #20
0
      inline bool is_other(const T& v) const {
	return is_black(v);
      }
Beispiel #21
0
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];
				}
			}
		}
	}
}
Beispiel #22
0
/**
 * 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);
}
Beispiel #23
0
static inline int is_red(struct rbtree_node *node)
{
	return !is_black(node);
}
Beispiel #24
0
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);
}
Beispiel #26
0
/* 删除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;
}
Beispiel #27
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");
		}
	}
}