⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blib.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 2 页
字号:

    if (NULL == block)
    {
        CYG_ASSERTC(!list_empty(&bl->list_head));
        
        block = list_get_last_block(bl);

        D(("blib reusing block=%d space\n", block->num)); 

        ret = blib_sync_block(bl, block);
        if (ENOERR != ret)
            return ret;
        
        list_del_block(bl, block);
        rb_del_block(bl, block);
    }

    block->num      = num;
    block->modified = false;

    if (read_data)
    {
        D(("blib reading block=%d\n", block->num)); 

        STAT(bl, n_reads);

        len = 1;
        ret = bl->bread_fn(bl->priv, (void *)block->data, &len, block->num);
        if (ENOERR != ret)
        {
            free_block(bl, block);
            return ret;
        }
    }
    rb_add_block(bl, block);
    list_add_block(bl, block);
    
    *dblock = block;
    return ret;
}

static int 
blib_init_cache(cyg_blib_t *bl, 
                void       *mem_base,
                cyg_uint32  mem_size,
                cyg_uint32  block_size, 
                cyg_bool    reinit)
{
    int ret = ENOERR;
    
    if (reinit)
    {
        ret = blib_sync(bl);
        if (ENOERR != ret)
            return ret;
    }
    
    bl->rb_root = RB_ROOT;
    INIT_LIST_HEAD(&bl->list_head);

    bl->mem_base   = mem_base;
    bl->mem_size   = mem_size;    
    bl->block_size = block_size;

    bl->block_size_log2 = get_val_log2(block_size);
    if (0 == bl->block_size_log2)
        return -EINVAL;
    
    init_block_mem_pool(bl);

    STAT_INIT(bl);

    return ret;
}

// --------------------------------------------------------------------

static int
io_bread(void *priv, void *buf, cyg_uint32 *len, cyg_uint32 pos)
{
    return cyg_io_bread((cyg_io_handle_t)priv, buf, len, pos);
}

static int
io_bwrite(void *priv, const void *buf, cyg_uint32 *len, cyg_uint32 pos)
{
    return cyg_io_bwrite((cyg_io_handle_t)priv, buf, len, pos);
}

// --------------------------------------------------------------------

int
cyg_blib_create(void               *priv_data,
                void               *mem_base,
                cyg_uint32          mem_size,
                cyg_uint32          block_size,
                cyg_blib_bread_fn   bread_fn,
                cyg_blib_bwrite_fn  bwrite_fn,
                cyg_blib_t         *bl)
{
    int ret;
    
    bl->priv      = priv_data;
    bl->bread_fn  = bread_fn;
    bl->bwrite_fn = bwrite_fn;

    ret = blib_init_cache(bl, mem_base, mem_size, block_size, false); 
    return ret; 
}

int 
cyg_blib_io_create(cyg_io_handle_t     handle,
                   void               *mem_base,
                   cyg_uint32          mem_size,
                   cyg_uint32          block_size,
                   cyg_blib_t         *bl)
{
    return cyg_blib_create((void *)handle, mem_base, mem_size, block_size,
                           io_bread, io_bwrite, bl);
}

int
cyg_blib_delete(cyg_blib_t *bl)
{
    return blib_sync(bl);
}

int 
cyg_blib_bread(cyg_blib_t *bl,
               void       *buf,
               cyg_uint32 *len,
               cyg_uint32  pos)
{
    blib_block_t *block;
    cyg_int32  size = *len;
    cyg_int32  bnum = pos;
    cyg_uint8 *bbuf = buf;
    Cyg_ErrNo  ret  = ENOERR;

    D(("blib bread block=%d len=%d buf=%p\n", pos, *len, buf)); 

    while (size > 0)
    {
        ret = blib_get_block(bl, bnum, true, &block); 
        if (ENOERR != ret)
            break;
        
        memcpy((void *)bbuf, (void *)block->data, bl->block_size);

        bbuf += bl->block_size;
        bnum++;
        size--;
    }
    *len -= size;
    return ret;
}

int 
cyg_blib_bwrite(cyg_blib_t *bl,
                const void *buf,
                cyg_uint32 *len,
                cyg_uint32  pos)
{
    blib_block_t *block;
    cyg_int32  size = *len;
    cyg_int32  bnum = pos;
    cyg_uint8 *bbuf = (cyg_uint8 * const) buf;
    Cyg_ErrNo  ret  = ENOERR;

    D(("blib bwrite block=%d len=%d buf=%p\n", pos, *len, buf)); 

    while (size > 0)
    {
        ret = blib_get_block(bl, bnum, false, &block); 
        if (ENOERR != ret)
            break;
        
        memcpy((void *)block->data, (void *)bbuf, bl->block_size);
        block->modified = true;

        bbuf += bl->block_size;
        bnum++;
        size--;
    }
    *len -= size;
    return ret;
}

int
cyg_blib_read(cyg_blib_t *bl,
              void       *buf,
              cyg_uint32 *len,
              cyg_uint32  bnum,
              cyg_uint32  pos)
{
    blib_block_t *block;
    cyg_uint8 *bbuf = buf;
    cyg_int32  size = *len;
    Cyg_ErrNo  ret  = ENOERR;

    size = *len;

    if (pos >= bl->block_size)
    {
        bnum += pos >> bl->block_size_log2;
        pos   = pos & (bl->block_size - 1);
    }
        
    D(("blib read len=%d pos=%d bnum=%d\n", *len, pos, bnum));

    while (size > 0)
    {
        cyg_uint32 csize;

        if ((size + pos) > bl->block_size)
            csize = bl->block_size - pos;
        else
            csize = size;

        ret = blib_get_block(bl, bnum, true, &block);
        if (ENOERR != ret)
            break;
 
        memcpy((void *)bbuf, (void *)(block->data+pos), csize);

        bbuf += csize;
        size -= csize;
        pos   = 0;
        bnum++;
    }
    *len -= size;
    return ret;
}

int
cyg_blib_write(cyg_blib_t *bl,
               const void *buf,
               cyg_uint32 *len,
               cyg_uint32  bnum,
               cyg_uint32  pos)
{
    blib_block_t *block;
    cyg_uint8 *bbuf = (cyg_uint8 * const) buf;
    cyg_int32  size = *len;
    Cyg_ErrNo  ret  = ENOERR;

    size = *len;

    if (pos >= bl->block_size)
    {
        bnum += pos >> bl->block_size_log2;
        pos   = pos & (bl->block_size - 1);
    }
        
    D(("blib write len=%d pos=%d bnum=%d\n", *len, pos, bnum));

    while (size > 0)
    {
        cyg_uint32 csize;

        if ((size + pos) > bl->block_size)
            csize = bl->block_size - pos;
        else
            csize = size;

        if (0 == pos && csize == bl->block_size)
            ret = blib_get_block(bl, bnum, false, &block);
        else
            ret = blib_get_block(bl, bnum, true, &block);
        if (ENOERR != ret)
            break;

        memcpy((void *)(block->data+pos), (void *)bbuf, csize);
        block->modified = true;

        bbuf += csize;
        size -= csize;
        pos   = 0;
        bnum++;
    }
    *len -= size;
    return ret;
}

int
cyg_blib_sync(cyg_blib_t *bl)
{
    return blib_sync(bl);
}

int
cyg_blib_sync_block(cyg_blib_t *bl, cyg_uint32 num)
{
    blib_block_t *block = rb_find_block(bl, num);
    
    if (NULL != block)
        return blib_sync_block(bl, block);
    else
        return -EINVAL;
}

int
cyg_blib_flush(cyg_blib_t *bl)
{
    return blib_init_cache(bl, bl->mem_base,  bl->mem_size,
                           bl->block_size, true);
}

int
cyg_blib_set_block_size(cyg_blib_t *bl, cyg_uint32 block_size)
{
    return blib_init_cache(bl, bl->mem_base, bl->mem_size, 
                           block_size, true); 
}    

int
cyg_blib_get_stat(cyg_blib_t *bl, cyg_blib_stat_t *stat)
{
#ifdef CYGIMP_BLOCK_LIB_STATISTICS
    *stat = bl->stat;
    return ENOERR;
#else
    stat->n_gets   = 0;
    stat->n_reads  = 0;
    stat->n_writes = 0;
    return -EINVAL;
#endif
}

// --------------------------------------------------------------------
// EOF blib.c

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -