Esempio n. 1
0
/**
 *******************************************************************************
 * \brief
 ******************************************************************************/
static void kv_async_dispatch(async_CB_t *pCB)
{
    uint32_t new_flags = pCB->flags;

    new_flags &= ~KV_ASYNC_CB_QUEUED;
    new_flags |=  KV_ASYNC_CB_RUNNING;
    pCB->flags = new_flags;

    if (pCB->flags & KV_ASYNC_CB_SET)
    {
        KV_TRC_IO(pFT, "DISPATCH: SET: %p", pCB);
        kv_async_SET_KEY(pCB);
    }
    else if (pCB->flags & KV_ASYNC_CB_GET)
    {
        KV_TRC_IO(pFT, "DISPATCH: GET: %p", pCB);
        kv_async_GET_KEY(pCB);
    }
    else if (pCB->flags & KV_ASYNC_CB_EXISTS)
    {
        KV_TRC_IO(pFT, "DISPATCH: EXI: %p", pCB);
        kv_async_EXISTS_KEY(pCB);
    }
    else if (pCB->flags & KV_ASYNC_CB_DEL)
    {
        KV_TRC_IO(pFT, "DISPATCH: DEL: %p", pCB);
        kv_async_DEL_KEY(pCB);
    }
    else
    {
        EXPECT_TRUE(0);
    }
}
Esempio n. 2
0
int main(int argc, char **argv)
{
    async_CB_t *pCB  = NULL;
    uint32_t    i    = 1;
    uint32_t    ctxt = 0;

    if (1 == argc)
    {
        printf("usage: run_kv_async_multi [-p] <dev1> <dev2> ...\n");
        printf("   ex: run_kv_async_multi /dev/cxl/afu0.0s /dev/cxl/afu1.0s\n");
        printf("   ex: run_kv_async_multi /dev/sdb /dev/sdh /dev/sdq\n");
        printf("   ex: run_kv_async_multi -p /dev/sg4 /dev/sg8\n");
        exit(0);
    }
    bzero(pCTs, sizeof(pCTs));

    if (0 == strncmp(argv[1], "-p", 7))
    {
        printf("Attempting to run with physical lun\n");
        ark_create_flag       = ARK_KV_PERSIST_STORE;
        KV_ASYNC_CTXT_PER_DEV = 1;
        i                     = 2;
    }
    else
    {
        //KV_ASYNC_CTXT_PER_DEV  = 1;
        KV_ASYNC_CTXT_PER_DEV  = 4;
        KV_ASYNC_JOBS_PER_CTXT = 60;
    }

    while (argv[i] != NULL && KV_ASYNC_CONTEXTS <= KV_ASYNC_MAX_CONTEXTS)
    {
        kv_async_init_io(argv[i++],
                        KV_ASYNC_JOBS_PER_CTXT,
                        KV_ASYNC_KLEN,
                        KV_ASYNC_VLEN,
                        KV_ASYNC_NUM_KV);
        KV_ASYNC_CONTEXTS += KV_ASYNC_CTXT_PER_DEV;
    }
    start = time(0);

    /* start all jobs for all contexts */
    for (ctxt=0; ctxt<KV_ASYNC_CONTEXTS; ctxt++)
    {
        for (pCB=pCTs[ctxt].pCBs;
             pCB<pCTs[ctxt].pCBs+KV_ASYNC_JOBS_PER_CTXT;
             pCB++)
        {
            pCB->flags |=  KV_ASYNC_RUNNING;
            kv_async_SET_KEY(pCB);
        }
    }
    kv_async_wait_jobs();

    return 0;
}
Esempio n. 3
0
/**
 *******************************************************************************
 * \brief
 *  callback function for set/get/exists/del
 ******************************************************************************/
static void kv_async_cb(int errcode, uint64_t dt, int64_t res)
{
    async_CB_t *pCB  = (async_CB_t*)dt;
    kv_t       *p_kv = NULL;
    uint64_t    tag  = (uint64_t)pCB;

    if (pCB == NULL)
    {
        KV_TRC_FFDC(pFT, "FFDC: pCB NULL");
        return;
    }
    if (pCB->b_mark != B_MARK)
    {
        KV_TRC_FFDC(pFT, "FFDC: B_MARK FAILURE %p: %"PRIx64"", pCB, pCB->b_mark);
        return;
    }
    if (pCB->e_mark != E_MARK)
    {
        KV_TRC_FFDC(pFT, "FFDC: E_MARK FAILURE %p: %"PRIx64"", pCB, pCB->e_mark);
        return;
    }
    if (EBUSY == errcode) {kv_async_q_retry(pCB); goto done;}

    if (IS_GTEST)
    {
        EXPECT_EQ(0,   errcode);
        EXPECT_EQ(tag, pCB->tag);
    }
    p_kv = pCB->db + pCB->len_i;
    ++pCB->len_i;

    if (pCB->flags & KV_ASYNC_CB_SET)
    {
        KV_TRC_IO(pFT, "KV_ASYNC_CB_SET, %p %d %d", pCB, pCB->len_i, pCB->len);
        if (0   != errcode)    printf("ark_set failed, errcode=%d\n", errcode);
        if (tag != pCB->tag)   printf("ark_set bad tag\n");
        if (res != p_kv->vlen) printf("ark_set bad vlen\n");
        if (IS_GTEST) {        EXPECT_EQ(res, p_kv->vlen);}

        /* end of db len sequence, move to next step */
        if (pCB->len_i == pCB->len)
        {
            if (pCB->flags & KV_ASYNC_CB_WRITE_PERF)
            {
                pCB->len_i = 0;
                kv_async_perf_done(pCB);
                goto done;
            }
            pCB->len_i  = 0;
            pCB->flags &= ~KV_ASYNC_CB_SET;
            pCB->flags |= KV_ASYNC_CB_GET;
            kv_async_GET_KEY(pCB);
            goto done;
        }
        kv_async_SET_KEY(pCB);
        goto done;
    }
    else if (pCB->flags & KV_ASYNC_CB_GET)
    {
        uint32_t miscompare = memcmp(p_kv->value, pCB->gvalue, p_kv->vlen);

        KV_TRC_IO(pFT, "KV_ASYNC_CB_GET, %p %d %d", pCB, pCB->len_i, pCB->len);
        if (0   != errcode)    printf("ark_get failed, errcode=%d\n", errcode);
        if (tag != pCB->tag)   printf("ark_get bad tag\n");
        if (res != p_kv->vlen) printf("ark_get bad vlen\n");
        if (IS_GTEST) {        EXPECT_EQ(0, miscompare);}

        /* end of db len sequence, move to next step */
        if (pCB->len_i == pCB->len)
        {
            if (pCB->flags & KV_ASYNC_CB_READ_PERF)
            {
                pCB->len_i = 0;
                kv_async_perf_done(pCB);
                goto done;
            }
            pCB->len_i  = 0;
            pCB->flags &= ~KV_ASYNC_CB_GET;
            pCB->flags |= KV_ASYNC_CB_EXISTS;
            kv_async_EXISTS_KEY(pCB);
            goto done;
        }
        kv_async_GET_KEY(pCB);
        goto done;
    }
    else if (pCB->flags & KV_ASYNC_CB_EXISTS)
    {
        KV_TRC_IO(pFT, "KV_ASYNC_CB_EXISTS, %p %d %d", pCB, pCB->len_i, pCB->len);
        if (0   != errcode)    printf("ark_exists failed,errcode=%d\n",errcode);
        if (tag != pCB->tag)   printf("ark_exists bad tag\n");
        if (res != p_kv->vlen) printf("ark_exists bad vlen\n");
        if (IS_GTEST) {        EXPECT_EQ(res, p_kv->vlen);}

        /* if end of db len sequence, move to next step */
        if (pCB->len_i == pCB->len)
        {
            pCB->len_i  = 0;
            pCB->flags &= ~KV_ASYNC_CB_EXISTS;

            if (pCB->flags & KV_ASYNC_CB_SGD)
            {
                pCB->flags |= KV_ASYNC_CB_DEL;
                kv_async_DEL_KEY(pCB);
                goto done;
            }
            else if (pCB->flags & KV_ASYNC_CB_REPLACE)
            {
                /* make sure we don't shutdown before we have replaced once */
                if (pCB->replace &&
                    pCB->flags & KV_ASYNC_CB_SHUTDOWN)
                {
                    pCB->flags |= KV_ASYNC_CB_DEL;
                    kv_async_DEL_KEY(pCB);
                    goto done;
                }
                pCB->replace = TRUE;
                if (0 != pCB->regen(pCB->db, pCB->len, pCB->regen_len))
                {
                    printf("regen failure, fatal\n");
                    KV_TRC_FFDC(pFT, "FFDC: regen failure");
                    memset(pCB, 0, sizeof(async_CB_t));
                    goto done;
                }
                pCB->flags |= KV_ASYNC_CB_SET;
                kv_async_SET_KEY(pCB);
                goto done;
            }
            else
            {
                /* should not be here */
                EXPECT_TRUE(0);
            }
        }
        kv_async_EXISTS_KEY(pCB);
        goto done;
    }
    else if (pCB->flags & KV_ASYNC_CB_DEL)
    {
        KV_TRC_IO(pFT, "KV_ASYNC_CB_DEL, %p i:%d len:%d", pCB, pCB->len_i,pCB->len);
        if (0   != errcode)    printf("ark_del failed, errcode=%d\n",errcode);
        if (tag != pCB->tag)   printf("ark_del bad tag\n");
        if (res != p_kv->vlen) printf("ark_del bad vlen\n");
        if (IS_GTEST) {        EXPECT_EQ(res, p_kv->vlen);}

        /* end of db len sequence, move to next step */
        if (pCB->len_i == pCB->len)
        {
            if (pCB->flags & KV_ASYNC_CB_SHUTDOWN)
            {
                if (!(pCB->flags & KV_ASYNC_CB_MULTI_CTXT_IO))
                {
                    kv_db_destroy(pCB->db, pCB->len);
                }
                if (pCB->gvalue) free(pCB->gvalue);
                memset(pCB, 0, sizeof(async_CB_t));
                KV_TRC_IO(pFT, "LOOP_DONE: %p", pCB);
                goto done;
            }
            KV_TRC_IO(pFT, "NEXT_LOOP, %p", pCB);
            pCB->flags &= ~KV_ASYNC_CB_DEL;
            pCB->flags |= KV_ASYNC_CB_SET;
            pCB->len_i  = 0;
            kv_async_SET_KEY(pCB);
            goto done;
        }
        kv_async_DEL_KEY(pCB);
        goto done;
    }
    else
    {
        /* should not be here */
        EXPECT_TRUE(0);
    }

done:
    return;
}
Esempio n. 4
0
/**
********************************************************************************
** \brief
**   do an ark asynchronous IO performance run
*******************************************************************************/
void kv_async_io(char    *dev,
                  uint32_t ctxts,
                  uint32_t jobs,
                  uint32_t vlen,
                  uint32_t len,
                  uint32_t read)
{
    async_context_t *pCT          = NULL;
    async_CB_t      *pCB          = NULL;
    uint32_t         job          = 0;
    uint32_t         ctxt         = 0;
    uint32_t         ctxt_running = 0;
    uint32_t         i            = 0;
    uint32_t         e_secs       = 0;
    uint64_t         ops          = 0;
    uint64_t         ios          = 0;
    uint32_t         tops         = 0;
    uint32_t         tios         = 0;

    if (read == 75) read100 = FALSE;
    else            read100 = TRUE;
    printf("ASYNC: ctxt:%-2d QD:%-3d size:%2dk read:%3d%% ",
            ctxts, jobs, vlen/1000, read);
    fflush(stdout);

    init_kv_db(jobs, KLEN, vlen, len);
    pCTs = (async_context_t*) malloc(ctxts*sizeof(async_context_t));
    assert(0 != pCTs);

    for (ctxt=0; ctxt<ctxts; ctxt++)
    {
        ARK *ark = NULL;
        pCT = pCTs+ctxt;
        memset(pCT, 0, sizeof(async_context_t));

        NEW_ARK(dev, &ark);
        pCT->ark = ark;

        for (job=0; job<jobs; job++)
        {
            pCB            = pCT->pCBs+job;
            pCB->itag      = SET_ITAG(ctxt,job);
            pCB->ark       = pCT->ark;
            pCB->flags     = KV_ASYNC_SET;
            pCB->db        = dbs+job;
            pCB->len       = len;
        }
    }

    testcase_start = time(0);

    /* start all jobs for all contexts */
    for (ctxt=0; ctxt<ctxts; ctxt++)
    {
        for (pCB=pCTs[ctxt].pCBs;
             pCB<pCTs[ctxt].pCBs+jobs;
             pCB++)
        {
            pCB->flags |=  KV_ASYNC_RUNNING;
            kv_async_SET_KEY(pCB);
        }
    }

    /* loop until all jobs are done or until time elapses */
    do
    {
        ctxt_running = FALSE;

        /* loop through contexts(arks) and check if all jobs are done or
         * time has elapsed
         */
        for (i=0; i<ctxts; i++)
        {
            /* check if all jobs are done */
            for (pCB=pCTs[i].pCBs;pCB<pCTs[i].pCBs+jobs;pCB++)
            {
                if (pCB->flags & KV_ASYNC_RUNNING)
                {
                    ctxt_running = TRUE;
                }
            }
            if (!ctxt_running) continue;

            /* check if time has elapsed */
            if (time(0) - testcase_start < KV_MIN_SECS) continue;

            for (pCB=pCTs[i].pCBs;pCB<pCTs[i].pCBs+jobs;pCB++)
            {
                if (pCB->flags & KV_ASYNC_RUNNING &&
                 (!(pCB->flags & KV_ASYNC_SHUTDOWN)) )
                {
                    pCB->flags |=  KV_ASYNC_SHUTDOWN;
                }
            }
        }
    }
    while (ctxt_running);

    testcase_stop = time(0);
    e_secs = testcase_stop - testcase_start;

    /* sum perf ops for all contexts/jobs and delete arks */
    for (i=0; i<ctxts; i++)
    {
        (void)ark_stats(pCTs[i].ark, &ops, &ios);
        tops += (uint32_t)ops;
        tios += (uint32_t)ios;
    }

    tops = tops / e_secs;
    tios = tios / e_secs;
    printf("op/s:%-7d io/s:%-7d secs:%d\n", tops, tios, e_secs);

    /* sum perf ops for all contexts/jobs and delete arks */
    for (i=0; i<ctxts; i++)
    {
        assert(0 == ark_delete(pCTs[i].ark));
    }

    free_kv_db(jobs, len);
}
Esempio n. 5
0
/**
********************************************************************************
** \brief
**   callback for ark functions: set,get,exists,del
*******************************************************************************/
void kv_async_cb(int errcode, uint64_t dt, int64_t res)
{
    async_context_t *pCT  = pCTs+GET_CTXT(dt);
    async_CB_t      *pCB  = NULL;
    kv_t            *p_kv = NULL;

    if (NULL == pCT) KV_ERR_STOP(pCB, "bad dt: ctxt", 0);
    pCB = pCT->pCBs+GET_CB(dt);

    if (NULL == pCB)          KV_ERR_STOP(pCB, "bad dt: cb", 0);
    if (0   != errcode)       KV_ERR_STOP(pCB, "bad errcode", errcode);
    if (dt  != pCB->tag)      KV_ERR_STOP(pCB, "bad tag", 0);
    if (res != pCB->db->vlen) KV_ERR_STOP(pCB, "bad res", 0);

    p_kv = pCB->db->kv + pCB->len_i;
    ++pCB->len_i;

    if (pCB->flags & KV_ASYNC_SET)
    {
        /* end of db len sequence, move to next step */
        if (pCB->len_i == pCB->len)
        {
            pCB->len_i  = 0;
            pCB->flags &= ~KV_ASYNC_SET;
            pCB->flags |= KV_ASYNC_GET;
            kv_async_GET_KEY(pCB);
            goto done;
        }
        kv_async_SET_KEY(pCB);
        goto done;
    }
    else if (pCB->flags & KV_ASYNC_GET)
    {
        if (0 != memcmp(p_kv->value, pCB->gvalue, pCB->db->vlen))
        {
            KV_ERR_STOP(pCB,"get miscompare",0);
        }

        /* end of db len sequence, move to next step */
        if (pCB->len_i == pCB->len)
        {
            pCB->len_i = 0;
            if (read100 && !(pCB->flags & KV_ASYNC_SHUTDOWN))
            {
                kv_async_GET_KEY(pCB);
            }
            else
            {
                pCB->flags &= ~KV_ASYNC_GET;
                pCB->flags |= KV_ASYNC_EXISTS;
                kv_async_EXISTS_KEY(pCB);
            }
            goto done;
        }
        kv_async_GET_KEY(pCB);
        goto done;
    }
    else if (pCB->flags & KV_ASYNC_EXISTS)
    {
        /* if end of db len sequence, move to next step */
        if (pCB->len_i == pCB->len)
        {
            pCB->len_i  = 0;
            pCB->flags &= ~KV_ASYNC_EXISTS;
            pCB->flags |= KV_ASYNC_DEL;
            kv_async_DEL_KEY(pCB);
            goto done;
        }
        kv_async_EXISTS_KEY(pCB);
        goto done;
    }
    else if (pCB->flags & KV_ASYNC_DEL)
    {
        /* end of db len sequence, move to next step */
        if (pCB->len_i == pCB->len)
        {
            if (pCB->flags & KV_ASYNC_SHUTDOWN)
            {
                pCB->flags &= ~KV_ASYNC_RUNNING;
                goto done;
            }
            pCB->flags &= ~KV_ASYNC_DEL;
            pCB->flags |= KV_ASYNC_SET;
            pCB->len_i  = 0;
            kv_async_SET_KEY(pCB);
            goto done;
        }
        kv_async_DEL_KEY(pCB);
        goto done;
    }
    else
    {
        /* should not be here */
        assert(0);
    }

done:
    return;
}