static bool bdrv_exceed_iops_limits(BlockDriverState *bs, bool is_write,

                             double elapsed_time, uint64_t *wait)

{

    uint64_t iops_limit = 0;

    double   ios_limit, ios_base;

    double   slice_time, wait_time;



    if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) {

        iops_limit = bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL];

    } else if (bs->io_limits.iops[is_write]) {

        iops_limit = bs->io_limits.iops[is_write];

    } else {

        if (wait) {

            *wait = 0;

        }



        return false;

    }



    slice_time = bs->slice_end - bs->slice_start;

    slice_time /= (NANOSECONDS_PER_SECOND);

    ios_limit  = iops_limit * slice_time;

    ios_base   = bs->nr_ops[is_write] - bs->io_base.ios[is_write];

    if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) {

        ios_base += bs->nr_ops[!is_write] - bs->io_base.ios[!is_write];

    }



    if (ios_base + 1 <= ios_limit) {

        if (wait) {

            *wait = 0;

        }



        return false;

    }



    /* Calc approx time to dispatch */

    wait_time = (ios_base + 1) / iops_limit;

    if (wait_time > elapsed_time) {

        wait_time = wait_time - elapsed_time;

    } else {

        wait_time = 0;

    }



    bs->slice_time = wait_time * BLOCK_IO_SLICE_TIME * 10;

    bs->slice_end += bs->slice_time - 3 * BLOCK_IO_SLICE_TIME;

    if (wait) {

        *wait = wait_time * BLOCK_IO_SLICE_TIME * 10;

    }



    return true;

}

static bool bdrv_exceed_iops_limits(BlockDriverState *bs, bool is_write,

                             double elapsed_time, uint64_t *wait)

{

    uint64_t iops_limit = 0;

    double   ios_limit, ios_base;

    double   slice_time, wait_time;



    if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) {

        iops_limit = bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL];

    } else if (bs->io_limits.iops[is_write]) {

        iops_limit = bs->io_limits.iops[is_write];

    } else {

        if (wait) {

            *wait = 0;

        }



        return false;

    }



    slice_time = bs->slice_end - bs->slice_start;

    slice_time /= (NANOSECONDS_PER_SECOND);

    ios_limit  = iops_limit * slice_time;

    ios_base   = bs->nr_ops[is_write] - bs->io_base.ios[is_write];

    if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) {

        ios_base += bs->nr_ops[!is_write] - bs->io_base.ios[!is_write];

    }



    if (ios_base + 1 <= ios_limit) {

        if (wait) {

            *wait = 0;

        }



        return false;

    }



    

    wait_time = (ios_base + 1) / iops_limit;

    if (wait_time > elapsed_time) {

        wait_time = wait_time - elapsed_time;

    } else {

        wait_time = 0;

    }



    bs->slice_time = wait_time * BLOCK_IO_SLICE_TIME * 10;

    bs->slice_end += bs->slice_time - 3 * BLOCK_IO_SLICE_TIME;

    if (wait) {

        *wait = wait_time * BLOCK_IO_SLICE_TIME * 10;

    }



    return true;

}

static bool FUNC_0(BlockDriverState *bs, bool is_write,

                             double elapsed_time, uint64_t *wait)

{

    uint64_t iops_limit = 0;

    double   VAR_0, VAR_1;

    double   VAR_2, VAR_3;



    if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) {

        iops_limit = bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL];

    } else if (bs->io_limits.iops[is_write]) {

        iops_limit = bs->io_limits.iops[is_write];

    } else {

        if (wait) {

            *wait = 0;

        }



        return false;

    }



    VAR_2 = bs->slice_end - bs->slice_start;

    VAR_2 /= (NANOSECONDS_PER_SECOND);

    VAR_0  = iops_limit * VAR_2;

    VAR_1   = bs->nr_ops[is_write] - bs->io_base.ios[is_write];

    if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) {

        VAR_1 += bs->nr_ops[!is_write] - bs->io_base.ios[!is_write];

    }



    if (VAR_1 + 1 <= VAR_0) {

        if (wait) {

            *wait = 0;

        }



        return false;

    }



    

    VAR_3 = (VAR_1 + 1) / iops_limit;

    if (VAR_3 > elapsed_time) {

        VAR_3 = VAR_3 - elapsed_time;

    } else {

        VAR_3 = 0;

    }



    bs->VAR_2 = VAR_3 * BLOCK_IO_SLICE_TIME * 10;

    bs->slice_end += bs->VAR_2 - 3 * BLOCK_IO_SLICE_TIME;

    if (wait) {

        *wait = VAR_3 * BLOCK_IO_SLICE_TIME * 10;

    }



    return true;

}

static bool FUNC_0(BlockDriverState *bs, bool is_write,
double elapsed_time, uint64_t *wait)
{ uint64_t iops_limit = 0; double   VAR_0, VAR_1; double   VAR_2, VAR_3; if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) { iops_limit = bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]; } else if (bs->io_limits.iops[is_write]) { iops_limit = bs->io_limits.iops[is_write]; } else { if (wait) { *wait = 0; } return false; } VAR_2 = bs->slice_end - bs->slice_start; VAR_2 /= (NANOSECONDS_PER_SECOND); VAR_0  = iops_limit * VAR_2; VAR_1   = bs->nr_ops[is_write] - bs->io_base.ios[is_write]; if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) { VAR_1 += bs->nr_ops[!is_write] - bs->io_base.ios[!is_write]; } if (VAR_1 + 1 <= VAR_0) { if (wait) { *wait = 0; } return false; } VAR_3 = (VAR_1 + 1) / iops_limit; if (VAR_3 > elapsed_time) { VAR_3 = VAR_3 - elapsed_time; } else { VAR_3 = 0; } bs->VAR_2 = VAR_3 * BLOCK_IO_SLICE_TIME * 10; bs->slice_end += bs->VAR_2 - 3 * BLOCK_IO_SLICE_TIME; if (wait) { *wait = VAR_3 * BLOCK_IO_SLICE_TIME * 10; } return true; }