/*
 * Memory helpers
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/mman.h>

#include "fio.h"

static void *pinned_mem;

void fio_unpin_memory(void)
{
	if (pinned_mem) {
		dprint(FD_MEM, "unpinning %llu bytes\n", mlock_size);
		if (munlock(pinned_mem, mlock_size) < 0)
			perror("munlock");
		munmap(pinned_mem, mlock_size);
		pinned_mem = NULL;
	}
}

int fio_pin_memory(void)
{
	unsigned long long phys_mem;

	if (!mlock_size)
		return 0;

	dprint(FD_MEM, "pinning %llu bytes\n", mlock_size);

	/*
	 * Don't allow mlock of more than real_mem-128MB
	 */
	phys_mem = os_phys_mem();
	if (phys_mem) {
		if ((mlock_size + 128 * 1024 * 1024) > phys_mem) {
			mlock_size = phys_mem - 128 * 1024 * 1024;
			log_info("fio: limiting mlocked memory to %lluMiB\n",
							mlock_size >> 20);
		}
	}

	pinned_mem = mmap(NULL, mlock_size, PROT_READ | PROT_WRITE,
				MAP_PRIVATE | OS_MAP_ANON, -1, 0);
	if (pinned_mem == MAP_FAILED) {
		perror("malloc locked mem");
		pinned_mem = NULL;
		return 1;
	}
	if (mlock(pinned_mem, mlock_size) < 0) {
		perror("mlock");
		munmap(pinned_mem, mlock_size);
		pinned_mem = NULL;
		return 1;
	}

	return 0;
}

static int alloc_mem_shm(struct thread_data *td)
{
	int flags = IPC_CREAT | SHM_R | SHM_W;

	if (td->o.mem_type == MEM_SHMHUGE)
		flags |= SHM_HUGETLB;

	td->shm_id = shmget(IPC_PRIVATE, td->orig_buffer_size, flags);
	dprint(FD_MEM, "shmget %zu, %d\n", td->orig_buffer_size, td->shm_id);
	if (td->shm_id < 0) {
		td_verror(td, errno, "shmget");
		if (geteuid() != 0 && errno == ENOMEM)
			log_err("fio: you may need to run this job as root\n");
		if (td->o.mem_type == MEM_SHMHUGE) {
			if (errno == EINVAL) {
				log_err("fio: check that you have free huge"
					" pages and that hugepage-size is"
					" correct.\n");
			} else if (errno == ENOSYS) {
				log_err("fio: your system does not appear to"
					" support huge pages.\n");
			} else if (errno == ENOMEM) {
				log_err("fio: no huge pages available, do you"
					" need to alocate some? See HOWTO.\n");
			}
		}

		return 1;
	}

	td->orig_buffer = shmat(td->shm_id, NULL, 0);
	dprint(FD_MEM, "shmat %d, %p\n", td->shm_id, td->orig_buffer);
	if (td->orig_buffer == (void *) -1) {
		td_verror(td, errno, "shmat");
		td->orig_buffer = NULL;
		return 1;
	}

	return 0;
}

static int alloc_mem_mmap(struct thread_data *td)
{
	int flags = MAP_PRIVATE;

	td->mmapfd = 1;

	if (td->mmapfile) {
		td->mmapfd = open(td->mmapfile, O_RDWR|O_CREAT, 0644);

		if (td->mmapfd < 0) {
			td_verror(td, errno, "open mmap file");
			td->orig_buffer = NULL;
			return 1;
		}
		if (ftruncate(td->mmapfd, td->orig_buffer_size) < 0) {
			td_verror(td, errno, "truncate mmap file");
			td->orig_buffer = NULL;
			return 1;
		}
	} else
		flags |= OS_MAP_ANON;

	td->orig_buffer = mmap(NULL, td->orig_buffer_size,
				PROT_READ | PROT_WRITE, flags, td->mmapfd, 0);
	dprint(FD_MEM, "mmap %zu/%d %p\n", td->orig_buffer_size, td->mmapfd,
							td->orig_buffer);
	if (td->orig_buffer == MAP_FAILED) {
		td_verror(td, errno, "mmap");
		td->orig_buffer = NULL;
		if (td->mmapfd) {
			close(td->mmapfd);
			unlink(td->mmapfile);
		}

		return 1;
	}

	return 0;
}

static int alloc_mem_malloc(struct thread_data *td)
{
	unsigned int bsize = td->orig_buffer_size;

	if (td->o.odirect)
		bsize += page_mask;

	td->orig_buffer = malloc(bsize);
	dprint(FD_MEM, "malloc %u %p\n", bsize, td->orig_buffer);
	if (td->orig_buffer)
		return 0;

	return 1;
}

/*
 * Setup the buffer area we need for io.
 */
int allocate_io_mem(struct thread_data *td)
{
	int ret = 0;

	if (td->io_ops->flags & FIO_NOIO)
		return 0;

	if (td->o.mem_type == MEM_MALLOC)
		ret = alloc_mem_malloc(td);
	else if (td->o.mem_type == MEM_SHM || td->o.mem_type == MEM_SHMHUGE)
		ret = alloc_mem_shm(td);
	else if (td->o.mem_type == MEM_MMAP || td->o.mem_type == MEM_MMAPHUGE)
		ret = alloc_mem_mmap(td);
	else {
		log_err("fio: bad mem type: %d\n", td->o.mem_type);
		ret = 1;
	}

	if (ret)
		td_verror(td, ENOMEM, "iomem allocation");

	return ret;
}

void free_io_mem(struct thread_data *td)
{
	if (td->o.mem_type == MEM_MALLOC) {
		dprint(FD_MEM, "free mem %p\n", td->orig_buffer);
		free(td->orig_buffer);
	} else if (td->o.mem_type == MEM_SHM || td->o.mem_type == MEM_SHMHUGE) {
		struct shmid_ds sbuf;

		dprint(FD_MEM, "shmdt/ctl %d %p\n", td->shm_id,
							td->orig_buffer);
		shmdt(td->orig_buffer);
		shmctl(td->shm_id, IPC_RMID, &sbuf);
	} else if (td->o.mem_type == MEM_MMAP ||
		   td->o.mem_type == MEM_MMAPHUGE) {
		dprint(FD_MEM, "munmap %zu %p\n", td->orig_buffer_size,
							td->orig_buffer);
		munmap(td->orig_buffer, td->orig_buffer_size);
		if (td->mmapfile) {
			close(td->mmapfd);
			unlink(td->mmapfile);
			free(td->mmapfile);
		}
	} else
		log_err("Bad memory type %u\n", td->o.mem_type);

	td->orig_buffer = NULL;
}
