Exemplo n.º 1
0
static int metal_add_page_size(const char *path, int shift, int mmap_flags)
{
	int index = _metal.num_page_sizes;
	unsigned long size = 1UL << shift;

	if (index >= MAX_PAGE_SIZES) {
		metal_log(METAL_LOG_WARNING, "skipped page size %ld - overflow\n",
			  size);
		return -EOVERFLOW;
	}

	if (!path || shift <= 0) {
		metal_log(METAL_LOG_WARNING, "skipped page size %ld - invalid args\n",
			  size);
		return -EINVAL;
	}

	_metal.page_sizes[index].page_shift = shift;
	_metal.page_sizes[index].page_size = size;
	_metal.page_sizes[index].mmap_flags = mmap_flags;
	strncpy(_metal.page_sizes[index].path, path, PATH_MAX);
	_metal.num_page_sizes ++;

	metal_log(METAL_LOG_DEBUG, "added page size %ld @%s\n", size, path);

	return 0;
}
Exemplo n.º 2
0
int metal_sys_init(const struct metal_init_params *params)
{
	static char sysfs_path[SYSFS_PATH_MAX];
	const char *tmp_path;
	unsigned int seed;
	FILE* urandom;
	int result;

	/* Determine sysfs mount point. */
	result = sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path));
	if (result) {
		metal_log(METAL_LOG_ERROR, "failed to get sysfs path (%s)\n",
			  strerror(-result));
		return result;
	}
	_metal.sysfs_path = sysfs_path;

	/* Find the temporary directory location. */
	tmp_path = getenv("TMPDIR");
	if (!tmp_path)
		tmp_path = "/tmp";
	_metal.tmp_path = tmp_path;

	/* Initialize the pseudo-random number generator. */
	urandom = fopen("/dev/urandom", "r");
	if (!urandom) {
		metal_log(METAL_LOG_ERROR, "failed to open /dev/urandom (%s)\n",
			  strerror(errno));
		return -errno;
	}
	if (sizeof(int) != fread(&seed, sizeof(int), 1, urandom)) {
		metal_log(METAL_LOG_DEBUG, "Failed fread /dev/urandom\n");
	}
	fclose(urandom);
	srand(seed);

	result = metal_init_page_sizes();
	if (result < 0)
		return result;

	result = metal_linux_bus_init();
	if (result < 0)
		return result;

	result = open("/proc/self/pagemap", O_RDONLY | O_CLOEXEC);
	if (result < 0) {
		metal_log(METAL_LOG_DEBUG, "Failed pagemap open - %s\n",
			  strerror(errno));
	}
	_metal.pagemap_fd = result;

	metal_unused(params);

	/* Initialize IRQ handling */
	metal_linux_irq_init();
	return 0;
}
Exemplo n.º 3
0
void metal_finish_threads(int threads, void *tids)
{
	int i;
	pthread_t *tid_p = (pthread_t *)tids;

	if (!tids) {
		metal_log(METAL_LOG_ERROR, "invalid argument, tids is NULL.\n");
		return;
	}

	for (i = 0; i < threads; i++)
		(void)pthread_join(tid_p[i], NULL);
}
Exemplo n.º 4
0
static int metal_init_page_sizes(void)
{
	const int max_sizes = MAX_PAGE_SIZES - 1;
	long sizes[max_sizes];

	/* Determine system page size. */
	sizes[0] = getpagesize();
	if (sizes[0] <= 0) {
		metal_log(METAL_LOG_ERROR, "failed to get page size\n");
		return -ENOSYS;
	}
	_metal.page_size  = sizes[0];
	_metal.page_shift = metal_log2(sizes[0]);
	metal_add_page_size(_metal.tmp_path, _metal.page_shift, 0);

#ifdef HAVE_HUGETLBFS_H
#ifndef MAP_HUGE_SHIFT
	/* System does not support multiple huge page sizes. */
	sizes[0] = gethugepagesize();
	if (sizes[0] > 0) {
		metal_add_page_size(hugetlbfs_find_path(),
				    metal_log2(sizes[0]),
				    MAP_HUGETLB);
	}
#else
	if (gethugepagesize() >= 0) {
		int i, count;

		/* System supports multiple huge page sizes. */
		count = gethugepagesizes(sizes, max_sizes);
		for (i = 0; i < count; i++) {
			int shift = metal_log2(sizes[i]);
			if ((shift & MAP_HUGE_MASK) != shift)
				continue;
			metal_add_page_size(
				hugetlbfs_find_path_for_size(sizes[i]),
				shift, (MAP_HUGETLB |
				(shift << MAP_HUGE_SHIFT)));
		}
	}
#endif
#endif

	/* Finally sort the resulting array by size. */
	qsort(_metal.page_sizes, _metal.num_page_sizes,
	      sizeof(struct metal_page_size), metal_pagesize_compare);

	return 0;
}
Exemplo n.º 5
0
int metal_run_noblock(int threads, metal_thread_t child,
		     void *arg, void *tids, int *threads_out)
{
	int i;
	TaskHandle_t *tid_p = (TaskHandle_t *)tids;
	BaseType_t stat = pdPASS;
	char tn[15];
	thread_wrap_arg_t *wrap_p;

	if (!tids) {
		metal_log(METAL_LOG_ERROR, "invalid argument, tids is NULL.\n");
		return -EINVAL;
	}

	for (i = 0; i < threads; i++) {
		snprintf(tn, metal_dim(tn), "%d", i);
		wrap_p = pvPortMalloc(sizeof(thread_wrap_arg_t));
		if (!wrap_p) {
			metal_log(METAL_LOG_ERROR, "failed to allocate wrapper %d\n", i);
			break;
		}

		wrap_p->thread_func = child;
		wrap_p->arg = arg;
		stat = xTaskCreate(thread_wrapper, tn, TEST_THREAD_STACK_SIZE,
				   wrap_p, 2, &tid_p[i]);
		if (stat != pdPASS) {
			metal_log(METAL_LOG_ERROR, "failed to create thread %d\n", i);
			vPortFree(wrap_p);
			break;
		}
	}

	*threads_out = i;
	return pdPASS == stat ? 0 : -ENOMEM;
}
Exemplo n.º 6
0
int metal_run_noblock(int threads, metal_thread_t child,
		     void *arg, void *tids, int *threads_out)
{
	int error, i;
	pthread_t *tid_p = (pthread_t *)tids;

	if (!tids) {
		metal_log(METAL_LOG_ERROR, "invalid arguement, tids is NULL.\n");
		return -EINVAL;
	}

	error = 0;
	for (i = 0; i < threads; i++) {
		error = -pthread_create(&tid_p[i], NULL, child, arg);
		if (error) {
			metal_log(METAL_LOG_ERROR, "failed to create thread - %s\n",
				  strerror(error));
			break;
		}
	}

	*threads_out = i;
	return error;
}
Exemplo n.º 7
0
void metal_finish_threads(int threads, void *tids)
{
	int i;
	TaskHandle_t *tid_p = (TaskHandle_t *)tids;

	if (!tids) {
		metal_log(METAL_LOG_ERROR, "invalid argument, tids is NULL.\n");
		return;
	}

	for (i = 0; i < threads; i++) {
		eTaskState ts;
		do {
			taskYIELD();
			ts=eTaskGetState(tid_p[i]);
		} while (ts != eDeleted);
	}
}
Exemplo n.º 8
0
static int atomic(void)
{
	atomic_int counter = ATOMIC_VAR_INIT(0);
	int value, error=0, i;

	for (i = 0; i < atomic_test_count; i++) {
		atomic_fetch_add(&counter, 1);
	}

	value = atomic_load(&counter);
	value -= atomic_test_count;
	if (value) {
		metal_log(METAL_LOG_DEBUG, "counter mismatch, delta = %d\n", value);
		error = -1;
	}

	return error;
}
Exemplo n.º 9
0
static void *alloc_thread(void *arg)
{
	int i;
	void *ptr;
	void *rv = 0;

	(void)arg;

	for (i = 0; i < test_count; i++) {
		/* expecting the implementation to be thread safe */
		ptr = metal_allocate_memory(256 /*10*i*/);
		if (!ptr) {
			metal_log(METAL_LOG_DEBUG, "failed to allocate memmory\n");
		        rv = (void *)-ENOMEM;
			break;
		}

		metal_free_memory(ptr);
	}

	return rv;
}