예제 #1
0
static inline const fletcher_4_ops_t *
fletcher_4_impl_get(void)
{
	fletcher_4_ops_t *ops = NULL;
	const uint32_t impl = IMPL_READ(fletcher_4_impl_chosen);

	switch (impl) {
	case IMPL_FASTEST:
		ASSERT(fletcher_4_initialized);
		ops = &fletcher_4_fastest_impl;
		break;
#if !defined(_KERNEL)
	case IMPL_CYCLE: {
		ASSERT(fletcher_4_initialized);
		ASSERT3U(fletcher_4_supp_impls_cnt, >, 0);

		static uint32_t cycle_count = 0;
		uint32_t idx = (++cycle_count) % fletcher_4_supp_impls_cnt;
		ops = fletcher_4_supp_impls[idx];
	}
	break;
#endif
	default:
		ASSERT3U(fletcher_4_supp_impls_cnt, >, 0);
		ASSERT3U(impl, <, fletcher_4_supp_impls_cnt);

		ops = fletcher_4_supp_impls[impl];
		break;
	}

	ASSERT3P(ops, !=, NULL);

	return (ops);
}
예제 #2
0
파일: zfs_fletcher.c 프로젝트: Ramzec/zfs
static void
fletcher_4_benchmark_impl(boolean_t native, char *data, uint64_t data_size)
{

	struct fletcher_4_kstat *fastest_stat =
	    &fletcher_4_stat_data[fletcher_4_supp_impls_cnt];
	hrtime_t start;
	uint64_t run_bw, run_time_ns, best_run = 0;
	zio_cksum_t zc;
	uint32_t i, l, sel_save = IMPL_READ(fletcher_4_impl_chosen);


	fletcher_checksum_func_t *fletcher_4_test = native ?
	    fletcher_4_native : fletcher_4_byteswap;

	for (i = 0; i < fletcher_4_supp_impls_cnt; i++) {
		struct fletcher_4_kstat *stat = &fletcher_4_stat_data[i];
		uint64_t run_count = 0;

		/* temporary set an implementation */
		fletcher_4_impl_chosen = i;

		kpreempt_disable();
		start = gethrtime();
		do {
			for (l = 0; l < 32; l++, run_count++)
				fletcher_4_test(data, data_size, NULL, &zc);

			run_time_ns = gethrtime() - start;
		} while (run_time_ns < FLETCHER_4_BENCH_NS);
		kpreempt_enable();

		run_bw = data_size * run_count * NANOSEC;
		run_bw /= run_time_ns;	/* B/s */

		if (native)
			stat->native = run_bw;
		else
			stat->byteswap = run_bw;

		if (run_bw > best_run) {
			best_run = run_bw;

			if (native) {
				fastest_stat->native = i;
				FLETCHER_4_FASTEST_FN_COPY(native,
				    fletcher_4_supp_impls[i]);
			} else {
				fastest_stat->byteswap = i;
				FLETCHER_4_FASTEST_FN_COPY(byteswap,
				    fletcher_4_supp_impls[i]);
			}
		}
	}

	/* restore original selection */
	atomic_swap_32(&fletcher_4_impl_chosen, sel_save);
}
예제 #3
0
int
fletcher_4_impl_set(const char *val)
{
	int err = -EINVAL;
	uint32_t impl = IMPL_READ(fletcher_4_impl_chosen);
	size_t i, val_len;

	val_len = strlen(val);
	while ((val_len > 0) && !!isspace(val[val_len-1])) /* trim '\n' */
		val_len--;

	/* check mandatory implementations */
	for (i = 0; i < ARRAY_SIZE(fletcher_4_impl_selectors); i++) {
		const char *name = fletcher_4_impl_selectors[i].fis_name;

		if (val_len == strlen(name) &&
		    strncmp(val, name, val_len) == 0) {
			impl = fletcher_4_impl_selectors[i].fis_sel;
			err = 0;
			break;
		}
	}

	if (err != 0 && fletcher_4_initialized) {
		/* check all supported implementations */
		for (i = 0; i < fletcher_4_supp_impls_cnt; i++) {
			const char *name = fletcher_4_supp_impls[i]->name;

			if (val_len == strlen(name) &&
			    strncmp(val, name, val_len) == 0) {
				impl = i;
				err = 0;
				break;
			}
		}
	}

	if (err == 0) {
		atomic_swap_32(&fletcher_4_impl_chosen, impl);
		membar_producer();
	}

	return (err);
}
예제 #4
0
static int
fletcher_4_param_get(char *buffer, struct kernel_param *unused)
{
	const uint32_t impl = IMPL_READ(fletcher_4_impl_chosen);
	char *fmt;
	int i, cnt = 0;

	/* list fastest */
	fmt = (impl == IMPL_FASTEST) ? "[%s] " : "%s ";
	cnt += sprintf(buffer + cnt, fmt, "fastest");

	/* list all supported implementations */
	for (i = 0; i < fletcher_4_supp_impls_cnt; i++) {
		fmt = (i == impl) ? "[%s] " : "%s ";
		cnt += sprintf(buffer + cnt, fmt,
		    fletcher_4_supp_impls[i]->name);
	}

	return (cnt);
}