예제 #1
0
파일: io_u.c 프로젝트: vsharma13/fio
static int __get_next_rand_offset(struct thread_data *td, struct fio_file *f,
				  enum fio_ddir ddir, uint64_t *b)
{
	uint64_t r, lastb;

	lastb = last_block(td, f, ddir);
	if (!lastb)
		return 1;

	if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE) {
		uint64_t rmax;

		rmax = td->o.use_os_rand ? OS_RAND_MAX : FRAND_MAX;

		if (td->o.use_os_rand) {
			rmax = OS_RAND_MAX;
			r = os_random_long(&td->random_state);
		} else {
			rmax = FRAND_MAX;
			r = __rand(&td->__random_state);
		}

		dprint(FD_RANDOM, "off rand %llu\n", (unsigned long long) r);

		*b = (lastb - 1) * (r / ((uint64_t) rmax + 1.0));
	} else {
		uint64_t off = 0;

		if (lfsr_next(&f->lfsr, &off, lastb))
			return 1;

		*b = off;
	}

	/*
	 * if we are not maintaining a random map, we are done.
	 */
	if (!file_randommap(td, f))
		goto ret;

	/*
	 * calculate map offset and check if it's free
	 */
	if (random_map_free(f, *b))
		goto ret;

	dprint(FD_RANDOM, "get_next_rand_offset: offset %llu busy\n",
						(unsigned long long) *b);

	*b = axmap_next_free(f->io_axmap, *b);
	if (*b == (uint64_t) -1ULL)
		return 1;
ret:
	return 0;
}
예제 #2
0
파일: io_u.c 프로젝트: jeefke/fio
static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
				enum fio_ddir ddir, unsigned long long *b)
{
	unsigned long long r, lastb;
	int loops = 5;

	lastb = last_block(td, f, ddir);
	if (!lastb)
		return 1;

	do {
		r = os_random_long(&td->random_state);
		dprint(FD_RANDOM, "off rand %llu\n", r);
		*b = (lastb - 1) * (r / ((unsigned long long) OS_RAND_MAX + 1.0));

		/*
		 * if we are not maintaining a random map, we are done.
		 */
		if (!file_randommap(td, f))
			return 0;

		/*
		 * calculate map offset and check if it's free
		 */
		if (random_map_free(f, *b))
			return 0;

		dprint(FD_RANDOM, "get_next_rand_offset: offset %llu busy\n",
									*b);
	} while (--loops);

	/*
	 * we get here, if we didn't suceed in looking up a block. generate
	 * a random start offset into the filemap, and find the first free
	 * block from there.
	 */
	loops = 10;
	do {
		f->last_free_lookup = (f->num_maps - 1) *
					(r / (OS_RAND_MAX + 1.0));
		if (!get_next_free_block(td, f, ddir, b))
			return 0;

		r = os_random_long(&td->random_state);
	} while (--loops);

	/*
	 * that didn't work either, try exhaustive search from the start
	 */
	f->last_free_lookup = 0;
	return get_next_free_block(td, f, ddir, b);
}
예제 #3
0
파일: io_u.c 프로젝트: CoryXie/fio
static int __get_next_rand_offset(struct thread_data *td, struct fio_file *f,
				  enum fio_ddir ddir, uint64_t *b)
{
	uint64_t r;

	if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE ||
	    td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64) {
		uint64_t frand_max, lastb;

		lastb = last_block(td, f, ddir);
		if (!lastb)
			return 1;

		frand_max = rand_max(&td->random_state);
		r = __rand(&td->random_state);

		dprint(FD_RANDOM, "off rand %llu\n", (unsigned long long) r);

		*b = lastb * (r / ((uint64_t) frand_max + 1.0));
	} else {
		uint64_t off = 0;

		assert(fio_file_lfsr(f));

		if (lfsr_next(&f->lfsr, &off))
			return 1;

		*b = off;
	}

	/*
	 * if we are not maintaining a random map, we are done.
	 */
	if (!file_randommap(td, f))
		goto ret;

	/*
	 * calculate map offset and check if it's free
	 */
	if (random_map_free(f, *b))
		goto ret;

	dprint(FD_RANDOM, "get_next_rand_offset: offset %llu busy\n",
						(unsigned long long) *b);

	*b = axmap_next_free(f->io_axmap, *b);
	if (*b == (uint64_t) -1ULL)
		return 1;
ret:
	return 0;
}
예제 #4
0
파일: io_u.c 프로젝트: Neil693667/speedtest
/*
 * Mark a given offset as used in the map.
 */
static void mark_random_map(struct thread_data *td, struct io_u *io_u)
{
	unsigned int min_bs = td->o.rw_min_bs;
	struct fio_file *f = io_u->file;
	unsigned long long block;
	unsigned int blocks, nr_blocks;
	int busy_check;

	block = (io_u->offset - f->file_offset) / (unsigned long long) min_bs;
	nr_blocks = (io_u->buflen + min_bs - 1) / min_bs;
	blocks = 0;
	busy_check = !(io_u->flags & IO_U_F_BUSY_OK);

	while (nr_blocks) {
		unsigned int idx, bit;
		unsigned long mask, this_blocks;

		/*
		 * If we have a mixed random workload, we may
		 * encounter blocks we already did IO to.
		 */
		if (!busy_check) {
			blocks = nr_blocks;
			break;
		}
		if ((td->o.ddir_seq_nr == 1) && !random_map_free(f, block))
			break;

		idx = RAND_MAP_IDX(f, block);
		bit = RAND_MAP_BIT(f, block);

		fio_assert(td, idx < f->num_maps);

		this_blocks = nr_blocks;
		if (this_blocks + bit > BLOCKS_PER_MAP)
			this_blocks = BLOCKS_PER_MAP - bit;

		do {
			if (this_blocks == BLOCKS_PER_MAP)
				mask = -1UL;
			else
				mask = ((1UL << this_blocks) - 1) << bit;
	
			if (!(f->file_map[idx] & mask))
				break;

			this_blocks--;
		} while (this_blocks);

		if (!this_blocks)
			break;

		f->file_map[idx] |= mask;
		nr_blocks -= this_blocks;
		blocks += this_blocks;
		block += this_blocks;
	}

	if ((blocks * min_bs) < io_u->buflen)
		io_u->buflen = blocks * min_bs;
}