当前位置: 首页 > 工具软件 > fatcache > 使用案例 >

fatcache分配空间阅读记录

单耘豪
2023-12-01
slab_get_item(uint8_t cid)
{
    rstatus_t status;
    struct slabclass *c;
    struct slabinfo *sinfo;
    struct slab *slab;

    ASSERT(cid >= SLABCLASS_MIN_ID && cid < nctable);
    c = &ctable[cid];

    if (itemx_empty()) {
        status = slab_evict();
        if (status != FC_OK) {
            return NULL;
        }
    }

    if (!TAILQ_EMPTY(&c->partial_msinfoq)) {
        return _slab_get_item(cid);
    }//这个class的partial_msinfoq不为空,取一个可用的item位置返回

    if (!TAILQ_EMPTY(&free_msinfoq)) {//在free_msinfoq中取一个空的,初始化
        /* move memory slab from free to partial q */
        sinfo = TAILQ_FIRST(&free_msinfoq);//在free_msinfoq中取一个
        ASSERT(nfree_msinfoq > 0);
        nfree_msinfoq--;//free的少一个
        c->nmslab++;//这个class的内存中的slab多一个
        TAILQ_REMOVE(&free_msinfoq, sinfo, tqe);

        /* init partial sinfo */
        TAILQ_INSERT_HEAD(&c->partial_msinfoq, sinfo, tqe);//放入头部并初始化
        /* sid is already initialized by slab_init */
        /* addr is already initialized by slab_init */
        sinfo->nalloc = 0;
        sinfo->nfree = 0;
        sinfo->cid = cid;
        /* mem is already initialized by slab_init */
        ASSERT(sinfo->mem == 1);//表明时内存中的slab

        /* init slab of partial sinfo */
        slab = slab_from_maddr(sinfo->addr, false);
        slab->magic = SLAB_MAGIC;
        slab->cid = cid;
        /* unused[] is left uninitialized */
        slab->sid = sinfo->sid;
        /* data[] is initialized on-demand */

        return _slab_get_item(cid);
    }

    ASSERT(!TAILQ_EMPTY(&full_msinfoq));
    ASSERT(nfull_msinfoq > 0);

    status = slab_drain();
    if (status != FC_OK) {
        return NULL;
    }

    return slab_get_item(cid);
}


若磁盘free非空,直接将内存的移至磁盘,返回,若为空,先slab_evict(),再把内存旧的移至磁盘,返回

slab_drain(void)
{
    rstatus_t status;

    if (!TAILQ_EMPTY(&free_dsinfoq)) {
        ASSERT(nfree_dsinfoq > 0);
        return _slab_drain();
    }

    status = slab_evict();
    if (status != FC_OK) {
        return status;
    }

    ASSERT(!TAILQ_EMPTY(&free_dsinfoq));
    ASSERT(nfree_dsinfoq > 0);

    return _slab_drain();
}



将内存中老的移至磁盘中free的位置

_slab_drain(void)
{
    struct slabinfo *msinfo, *dsinfo; /* memory and disk slabinfo */
    struct slab *slab;                /* slab to write */
    size_t size;                      /* bytes to write */
    off_t off;                        /* offset to write at */
    int n;                            /* written bytes */

    ASSERT(!TAILQ_EMPTY(&full_msinfoq));
    ASSERT(nfull_msinfoq > 0);

    ASSERT(!TAILQ_EMPTY(&free_dsinfoq));
    ASSERT(nfree_dsinfoq > 0);

    /* get memory sinfo from full q */
    msinfo = TAILQ_FIRST(&full_msinfoq);//从内存中满的里面取一个
    nfull_msinfoq--;
    TAILQ_REMOVE(&full_msinfoq, msinfo, tqe);
    ASSERT(msinfo->mem);
    ASSERT(slab_full(msinfo));

    /* get disk sinfo from free q */
    dsinfo = TAILQ_FIRST(&free_dsinfoq);//从磁盘中取一个空的
    nfree_dsinfoq--;
    TAILQ_REMOVE(&free_dsinfoq, dsinfo, tqe);
    ASSERT(!dsinfo->mem);

    /* drain the memory to disk slab */
    slab = slab_from_maddr(msinfo->addr, true);
    size = settings.slab_size;
    off = slab_to_daddr(dsinfo);
    n = pwrite(fd, slab, size, off);
    if (n < size) {
        log_error("pwrite fd %d %zu bytes at offset %"PRId64" failed: %s",
                  fd, size, off, strerror(errno));
        return FC_ERROR;
    }

    ctable[msinfo->cid].nmslab--;
    ctable[msinfo->cid].ndslab++;
    log_debug(LOG_DEBUG, "drain slab at memory (sid %"PRIu32" addr %"PRIu32") "
              "to disk (sid %"PRIu32" addr %"PRIu32")", msinfo->sid,
              msinfo->addr, dsinfo->sid, dsinfo->addr);

    /* swap msinfo <> dsinfo addresses */
    slab_swap_addr(msinfo, dsinfo);

    /* move dsinfo (now a memory sinfo) to free q */
    nfree_msinfoq++;
    TAILQ_INSERT_TAIL(&free_msinfoq, dsinfo, tqe);

    /* move msinfo (now a disk sinfo) to full q */
    nfull_dsinfoq++;
    TAILQ_INSERT_TAIL(&full_dsinfoq, msinfo, tqe);

    return FC_OK;
}


在_slab_get_item(uint8_t cid)中,若partial_msinfoq中的slab满了,则放进full_msinfoq中




 类似资料: