/*
 * Really simple exclusive file locking based on filename.
 * No hash indexing, just a list, so only works well for < 100 files or
 * so. But that's more than what fio needs, so should be fine.
 */
#include <inttypes.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>

#include "flist.h"
#include "filelock.h"
#include "smalloc.h"
#include "mutex.h"
#include "hash.h"
#include "log.h"

struct fio_filelock {
	uint32_t hash;
	struct fio_mutex lock;
	struct flist_head list;
	unsigned int references;
};

#define MAX_FILELOCKS	128
	
static struct filelock_data {
	struct flist_head list;
	struct fio_mutex lock;

	struct flist_head free_list;
	struct fio_filelock ffs[MAX_FILELOCKS];
} *fld;

static void put_filelock(struct fio_filelock *ff)
{
	flist_add(&ff->list, &fld->free_list);
}

static struct fio_filelock *__get_filelock(void)
{
	struct fio_filelock *ff;

	if (flist_empty(&fld->free_list))
		return NULL;

	ff = flist_first_entry(&fld->free_list, struct fio_filelock, list);
	flist_del_init(&ff->list);
	return ff;
}

static struct fio_filelock *get_filelock(int trylock, int *retry)
{
	struct fio_filelock *ff;

	do {
		ff = __get_filelock();
		if (ff || trylock)
			break;

		fio_mutex_up(&fld->lock);
		usleep(1000);
		fio_mutex_down(&fld->lock);
		*retry = 1;
	} while (1);

	return ff;
}

int fio_filelock_init(void)
{
	int i;

	fld = smalloc(sizeof(*fld));
	if (!fld)
		return 1;

	INIT_FLIST_HEAD(&fld->list);
	INIT_FLIST_HEAD(&fld->free_list);

	if (__fio_mutex_init(&fld->lock, FIO_MUTEX_UNLOCKED))
		goto err;

	for (i = 0; i < MAX_FILELOCKS; i++) {
		struct fio_filelock *ff = &fld->ffs[i];

		if (__fio_mutex_init(&ff->lock, FIO_MUTEX_UNLOCKED))
			goto err;
		flist_add_tail(&ff->list, &fld->free_list);
	}

	return 0;
err:
	fio_filelock_exit();
	return 1;
}

void fio_filelock_exit(void)
{
	if (!fld)
		return;

	assert(flist_empty(&fld->list));
	__fio_mutex_remove(&fld->lock);

	while (!flist_empty(&fld->free_list)) {
		struct fio_filelock *ff;

		ff = flist_first_entry(&fld->free_list, struct fio_filelock, list);

		flist_del_init(&ff->list);
		__fio_mutex_remove(&ff->lock);
	}

	sfree(fld);
	fld = NULL;
}

static struct fio_filelock *fio_hash_find(uint32_t hash)
{
	struct flist_head *entry;
	struct fio_filelock *ff;

	flist_for_each(entry, &fld->list) {
		ff = flist_entry(entry, struct fio_filelock, list);
		if (ff->hash == hash)
			return ff;
	}

	return NULL;
}

static struct fio_filelock *fio_hash_get(uint32_t hash, int trylock)
{
	struct fio_filelock *ff;

	ff = fio_hash_find(hash);
	if (!ff) {
		int retry = 0;

		ff = get_filelock(trylock, &retry);
		if (!ff)
			return NULL;

		/*
		 * If we dropped the main lock, re-lookup the hash in case
		 * someone else added it meanwhile. If it's now there,
		 * just return that.
		 */
		if (retry) {
			struct fio_filelock *__ff;

			__ff = fio_hash_find(hash);
			if (__ff) {
				put_filelock(ff);
				return __ff;
			}
		}

		ff->hash = hash;
		ff->references = 0;
		flist_add(&ff->list, &fld->list);
	}

	return ff;
}

static bool __fio_lock_file(const char *fname, int trylock)
{
	struct fio_filelock *ff;
	uint32_t hash;

	hash = jhash(fname, strlen(fname), 0);

	fio_mutex_down(&fld->lock);
	ff = fio_hash_get(hash, trylock);
	if (ff)
		ff->references++;
	fio_mutex_up(&fld->lock);

	if (!ff) {
		assert(!trylock);
		return true;
	}

	if (!trylock) {
		fio_mutex_down(&ff->lock);
		return false;
	}

	if (!fio_mutex_down_trylock(&ff->lock))
		return false;

	fio_mutex_down(&fld->lock);

	/*
	 * If we raced and the only reference to the lock is us, we can
	 * grab it
	 */
	if (ff->references != 1) {
		ff->references--;
		ff = NULL;
	}

	fio_mutex_up(&fld->lock);

	if (ff) {
		fio_mutex_down(&ff->lock);
		return false;
	}

	return true;
}

bool fio_trylock_file(const char *fname)
{
	return __fio_lock_file(fname, 1);
}

void fio_lock_file(const char *fname)
{
	__fio_lock_file(fname, 0);
}

void fio_unlock_file(const char *fname)
{
	struct fio_filelock *ff;
	uint32_t hash;

	hash = jhash(fname, strlen(fname), 0);

	fio_mutex_down(&fld->lock);

	ff = fio_hash_find(hash);
	if (ff) {
		int refs = --ff->references;
		fio_mutex_up(&ff->lock);
		if (!refs) {
			flist_del_init(&ff->list);
			put_filelock(ff);
		}
	} else
		log_err("fio: file not found for unlocking\n");

	fio_mutex_up(&fld->lock);
}
