示例#1
0
文件: gc.c 项目: CRogers/obc
/* free_block -- free a block, merging it with its neighbours */
static header *free_block(header *h, bool mapped) {
    /* Mapped is true if this memory is being recycled: it's already
       in the page table, but we'll need to zero it. */

    header *prev = left_neighbour(h), *next = right_neighbour(h);

    /* Base and size of area where page table needs updating */
    uchar *pg_memory = h->h_memory;
    unsigned pg_size = (mapped ? 0 : h->h_size);

#ifdef TRACE
    if (debug['l']) {
        printf("Freeing block at %p, size %#x\n",
               h->h_memory, h->h_size);
        if (prev == NULL) printf("prev=null, ");
        else printf("prev=%p, ", prev->h_memory);
        if (next == NULL) printf("next=null\n");
        else printf("next=%p\n", next->h_memory);
    }
#endif

    if (mapped) memset(h->h_memory, 0, h->h_size);

    if (prev != NULL && prev->h_objsize == 0) {
        DEBUG_PRINT('l', ("Merging with prev\n"));
        unlink(prev);
        prev->h_size += h->h_size;
        pg_memory = h->h_memory;
        pg_size = h->h_size;
        free_header(h);
        h = prev;
    }

    if (next != NULL && next->h_objsize == 0) {
        DEBUG_PRINT('l', ("Merging with next\n"));
        unlink(next);
        next->h_memory = h->h_memory;
        next->h_size += h->h_size;
        pg_memory = h->h_memory;
        pg_size = h->h_size;
        free_header(h);
        h = next;
    }

    if (pg_size > 0) page_setup(pg_memory, pg_size, h);
    make_free(h);

    /* Return the merged block */
    return h;
}
示例#2
0
bool LOSfinder::bresen_y(PosPoint source, PosPoint target)
{
    int x = source.posx;
    int error = 0;
    int delta_y = std::abs(source.posy - target.posy);
    int deltaerr = std::abs(source.posx - target.posx);
    int deltastep = sign(target.posx - source.posx);
    int incrstep = sign(target.posy - source.posy);
    for (int y = source.posy; y != target.posy; y += incrstep)
    {
        if ((x % RAY_MULTIPLIER) == 0 && (y % RAY_MULTIPLIER) == 0)
        {
            // when in corner check side neighbours
            // if both of them are not transparent then corner is not transparent
            PosPoint left_neighbour(x + deltastep, y, source.posz);
            PosPoint right_neighbour(x, y + incrstep, source.posz);
            if (!is_transparent(left_neighbour) && !is_transparent(right_neighbour))
            {
                return false;
            }
        }
        else if (x % RAY_MULTIPLIER == 0)
        {
            // when ray hits an edge check both tiles. Since ray travels through edge both of them 
            // must be transparent
            PosPoint left_neighbour(x - deltastep, y, source.posz);
            PosPoint right_neighbour(x + deltastep, y, source.posz);
            if (!is_transparent(left_neighbour) || !is_transparent(right_neighbour))
            {
                return false;
            }
        }
        else if (y % RAY_MULTIPLIER == 0)
        {
            // second case of edge handling
            PosPoint left_neighbour(x, y - incrstep, source.posz);
            PosPoint right_neighbour(x, y + incrstep, source.posz);
            if (!is_transparent(left_neighbour) || !is_transparent(right_neighbour))
            {
                return false;
            }
        }
        else
        {
            PosPoint new_point(x, y, source.posz);

            if (!is_transparent(new_point))
            {
                return false;
            }
        }

        error += deltaerr;
        if (error >= delta_y)
        {
            x += deltastep;
            error -= delta_y;
        }
    }

    return true;
}