/**
 * @file daemon/opd_sfile.c
 * Management of sample files
 *
 * @remark Copyright 2002, 2005 OProfile authors
 * @remark Read the file COPYING
 *
 * @author John Levon
 * @author Philippe Elie
 */

#include "opd_sfile.h"

#include "opd_trans.h"
#include "opd_kernel.h"
#include "opd_mangling.h"
#include "opd_anon.h"
#include "opd_printf.h"
#include "opd_stats.h"
#include "oprofiled.h"

#include "op_libiberty.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HASH_SIZE 2048
#define HASH_BITS (HASH_SIZE - 1)

/** All sfiles are hashed into these lists */
static struct list_head hashes[HASH_SIZE];

/** All sfiles are on this list. */
static LIST_HEAD(lru_list);


/* FIXME: can undoubtedly improve this hashing */
/** Hash the transient parameters for lookup. */
static unsigned long
sfile_hash(struct transient const * trans, struct kernel_image * ki)
{
	unsigned long val = 0;
	
	if (separate_thread) {
		val ^= trans->tid << 2;
		val ^= trans->tgid << 2;
	}

	if (separate_kernel || ((trans->anon || separate_lib) && !ki))
		val ^= trans->app_cookie >> (DCOOKIE_SHIFT + 3);

	if (separate_cpu)
		val ^= trans->cpu;

	/* cookie meaningless for kernel, shouldn't hash */
	if (trans->in_kernel) {
		val ^= ki->start >> 14;
		val ^= ki->end >> 7;
		return val & HASH_BITS;
	}

	if (trans->cookie != NO_COOKIE) {
		val ^= trans->cookie >> DCOOKIE_SHIFT;
		return val & HASH_BITS;
	}

	if (!separate_thread)
		val ^= trans->tgid << 2;

	if (trans->anon) {
		val ^= trans->anon->start >> VMA_SHIFT;
		val ^= trans->anon->end >> (VMA_SHIFT + 1);
	}

	return val & HASH_BITS;
}


static int
do_match(struct sfile const * sf, cookie_t cookie, cookie_t app_cookie,
         struct kernel_image const * ki, struct anon_mapping const * anon,
         pid_t tgid, pid_t tid, unsigned int cpu)
{
	/* this is a simplified check for "is a kernel image" AND
	 * "is the right kernel image". Also handles no-vmlinux
	 * correctly.
	 */
	if (sf->kernel != ki)
		return 0;

	if (separate_thread) {
		if (sf->tid != tid || sf->tgid != tgid)
			return 0;
	}

	if (separate_cpu) {
		if (sf->cpu != cpu)
			return 0;
	}

	if (separate_kernel || ((anon || separate_lib) && !ki)) {
		if (sf->app_cookie != app_cookie)
			return 0;
	}

	/* ignore the cached trans->cookie for kernel images,
	 * it's meaningless and we checked all others already
	 */
	if (ki)
		return 1;

	if (sf->anon != anon)
		return 0;

	return sf->cookie == cookie;
}


static int
trans_match(struct transient const * trans, struct sfile const * sfile,
            struct kernel_image const * ki)
{
	return do_match(sfile, trans->cookie, trans->app_cookie, ki,
	                trans->anon, trans->tgid, trans->tid, trans->cpu);
}


static int
sfile_equal(struct sfile const * sf, struct sfile const * sf2)
{
	return do_match(sf, sf2->cookie, sf2->app_cookie, sf2->kernel,
	                sf2->anon, sf2->tgid, sf2->tid, sf2->cpu);
}


static int
is_sf_ignored(struct sfile const * sf)
{
	if (sf->kernel) {
		if (!is_image_ignored(sf->kernel->name))
			return 0;

		/* Let a dependent kernel image redeem the sf if we're
		 * executing on behalf of an application.
		 */
		return is_cookie_ignored(sf->app_cookie);
	}

	/* Anon regions are always dependent on the application.
 	 * Otherwise, let a dependent image redeem the sf.
	 */
	if (sf->anon || is_cookie_ignored(sf->cookie))
		return is_cookie_ignored(sf->app_cookie);

	return 0;
}


/** create a new sfile matching the current transient parameters */
static struct sfile *
create_sfile(unsigned long hash, struct transient const * trans,
             struct kernel_image * ki)
{
	size_t i;
	struct sfile * sf;

	sf = xmalloc(sizeof(struct sfile));

	sf->hashval = hash;

	/* The logic here: if we're in the kernel, the cached cookie is
	 * meaningless (though not the app_cookie if separate_kernel)
	 */
	sf->cookie = trans->in_kernel ? INVALID_COOKIE : trans->cookie;
	sf->app_cookie = INVALID_COOKIE;
	sf->tid = (pid_t)-1;
	sf->tgid = (pid_t)-1;
	sf->cpu = 0;
	sf->kernel = ki;
	sf->anon = trans->anon;

	for (i = 0 ; i < op_nr_counters ; ++i)
		odb_init(&sf->files[i]);

	for (i = 0; i < CG_HASH_SIZE; ++i)
		list_init(&sf->cg_hash[i]);

	if (separate_thread)
		sf->tid = trans->tid;
	if (separate_thread || trans->cookie == NO_COOKIE)
		sf->tgid = trans->tgid;

	if (separate_cpu)
		sf->cpu = trans->cpu;

	if (separate_kernel || ((trans->anon || separate_lib) && !ki))
		sf->app_cookie = trans->app_cookie;

	sf->ignored = is_sf_ignored(sf);

	return sf;
}


struct sfile * sfile_find(struct transient const * trans)
{
	struct sfile * sf;
	struct list_head * pos;
	struct kernel_image * ki = NULL;
	unsigned long hash;

	if (trans->tracing != TRACING_ON) {
		opd_stats[OPD_SAMPLES]++;
		opd_stats[trans->in_kernel == 1 ? OPD_KERNEL : OPD_PROCESS]++;
	}

	/* There is a small race where this *can* happen, see
	 * caller of cpu_buffer_reset() in the kernel
	 */
	if (trans->in_kernel == -1) {
		verbprintf(vsamples, "Losing sample at 0x%llx of unknown provenance.\n",
		           trans->pc);
		opd_stats[OPD_NO_CTX]++;
		return NULL;
	}

	/* we might need a kernel image start/end to hash on */
	if (trans->in_kernel) {
		ki = find_kernel_image(trans);
		if (!ki) {
			verbprintf(vsamples, "Lost kernel sample %llx\n", trans->pc);
			opd_stats[OPD_LOST_KERNEL]++;
			return NULL;
		}
	} else if (trans->cookie == NO_COOKIE && !trans->anon) {
		if (vsamples) {
			char const * app = verbose_cookie(trans->app_cookie);
			printf("No anon map for pc %llx, app %s.\n",
			       trans->pc, app);
		}
		opd_stats[OPD_LOST_NO_MAPPING]++;
		return NULL;
	}

	hash = sfile_hash(trans, ki);
	list_for_each(pos, &hashes[hash]) {
		sf = list_entry(pos, struct sfile, hash);
		if (trans_match(trans, sf, ki)) {
			sfile_get(sf);
			goto lru;
		}
	}

	sf = create_sfile(hash, trans, ki);
	list_add(&sf->hash, &hashes[hash]);

lru:
	sfile_put(sf);
	return sf;
}


static void sfile_dup(struct sfile * to, struct sfile * from)
{
	size_t i;

	memcpy(to, from, sizeof (struct sfile));

	for (i = 0 ; i < op_nr_counters ; ++i)
		odb_init(&to->files[i]);

	for (i = 0; i < CG_HASH_SIZE; ++i)
		list_init(&to->cg_hash[i]);

	list_init(&to->hash);
	list_init(&to->lru);
}


static odb_t * get_file(struct transient const * trans, int is_cg)
{
	struct sfile * sf = trans->current;
	struct sfile * last = trans->last;
	struct cg_entry * cg;
	struct list_head * pos;
	unsigned long hash;
	odb_t * file;

	if (trans->event >= op_nr_counters) {
		fprintf(stderr, "%s: Invalid counter %lu\n", __FUNCTION__,
			trans->event);
		abort();
	}

	file = &sf->files[trans->event];

	if (!is_cg)
		goto open;

	hash = last->hashval & (CG_HASH_SIZE - 1);

	/* Need to look for the right 'to'. Since we're looking for
	 * 'last', we use its hash.
	 */
	list_for_each(pos, &sf->cg_hash[hash]) {
		cg = list_entry(pos, struct cg_entry, hash);
		if (sfile_equal(last, &cg->to)) {
			file = &cg->to.files[trans->event];
			goto open;
		}
	}

	cg = xmalloc(sizeof(struct cg_entry));
	sfile_dup(&cg->to, last);
	list_add(&cg->hash, &sf->cg_hash[hash]);
	file = &cg->to.files[trans->event];

open:
	if (!odb_open_count(file))
		opd_open_sample_file(file, last, sf, trans->event, is_cg);

	/* Error is logged by opd_open_sample_file */
	if (!odb_open_count(file))
		return NULL;

	return file;
}


static void verbose_print_sample(struct sfile * sf, vma_t pc, uint counter)
{
	char const * app = verbose_cookie(sf->app_cookie);
	printf("0x%llx(%u): ", pc, counter);
	if (sf->anon) {
		printf("anon (tgid %u, 0x%llx-0x%llx), ",
		       (unsigned int)sf->anon->tgid,
		       sf->anon->start, sf->anon->end);
	} else if (sf->kernel) {
		printf("kern (name %s, 0x%llx-0x%llx), ", sf->kernel->name,
		       sf->kernel->start, sf->kernel->end);
	} else {
		printf("%s(%llx), ", verbose_cookie(sf->cookie),  sf->cookie);
	}
	printf("app %s(%llx)", app, sf->app_cookie);
}


static void verbose_sample(struct transient const * trans, vma_t pc)
{
	printf("Sample ");
	verbose_print_sample(trans->current, pc, trans->event);
	printf("\n");
}


static void
verbose_arc(struct transient const * trans, vma_t from, vma_t to)
{
	printf("Arc ");
	verbose_print_sample(trans->current, from, trans->event);
	printf(" -> 0x%llx", to);
	printf("\n");
}


static void sfile_log_arc(struct transient const * trans)
{
	int err;
	vma_t from = trans->pc;
	vma_t to = trans->last_pc;
	uint64_t key;
	odb_t * file;

	file = get_file(trans, 1);

	/* absolute value -> offset */
	if (trans->current->kernel)
		from -= trans->current->kernel->start;

	if (trans->last->kernel)
		to -= trans->last->kernel->start;

	if (trans->current->anon)
		from -= trans->current->anon->start;

	if (trans->last->anon)
		to -= trans->last->anon->start;

	if (varcs)
		verbose_arc(trans, from, to);

	if (!file) {
		opd_stats[OPD_LOST_SAMPLEFILE]++;
		return;
	}

	/* Possible narrowings to 32-bit value only. */
	key = to & (0xffffffff);
	key |= ((uint64_t)from) << 32;

	err = odb_insert(file, key, 1);
	if (err) {
		fprintf(stderr, "%s: %s\n", __FUNCTION__, strerror(err));
		abort();
	}
}


void sfile_log_sample(struct transient const * trans)
{
	int err;
	vma_t pc = trans->pc;
	odb_t * file;

	if (trans->tracing == TRACING_ON) {
		/* can happen if kernel sample falls through the cracks,
		 * see opd_put_sample() */
		if (trans->last)
			sfile_log_arc(trans);
		return;
	}

	file = get_file(trans, 0);

	/* absolute value -> offset */
	if (trans->current->kernel)
		pc -= trans->current->kernel->start;

	if (trans->current->anon)
		pc -= trans->current->anon->start;
 
	if (vsamples)
		verbose_sample(trans, pc);

	if (!file) {
		opd_stats[OPD_LOST_SAMPLEFILE]++;
		return;
	}

	err = odb_insert(file, (uint64_t)pc, 1);
	if (err) {
		fprintf(stderr, "%s: %s\n", __FUNCTION__, strerror(err));
		abort();
	}
}


static int close_sfile(struct sfile * sf)
{
	size_t i;

	/* it's OK to close a non-open odb file */
	for (i = 0; i < op_nr_counters; ++i)
		odb_close(&sf->files[i]);

	return 0;
}


static void kill_sfile(struct sfile * sf)
{
	close_sfile(sf);
	list_del(&sf->hash);
	list_del(&sf->lru);
}


static int sync_sfile(struct sfile * sf)
{
	size_t i;

	for (i = 0; i < op_nr_counters; ++i)
		odb_sync(&sf->files[i]);

	return 0;
}


static int is_sfile_kernel(struct sfile * sf)
{
	return !!sf->kernel;
}


static int is_sfile_anon(struct sfile * sf)
{
	return !!sf->anon;
}


static void for_one_sfile(struct sfile * sf, int (*func)(struct sfile *))
{
	size_t i;
	int free_sf = func(sf);

	for (i = 0; i < CG_HASH_SIZE; ++i) {
		struct list_head * pos;
		struct list_head * pos2;
		list_for_each_safe(pos, pos2, &sf->cg_hash[i]) {
			struct cg_entry * cg =
				list_entry(pos, struct cg_entry, hash);
			if (free_sf || func(&cg->to)) {
				kill_sfile(&cg->to);
				list_del(&cg->hash);
				free(cg);
			}
		}
	}

	if (free_sf) {
		kill_sfile(sf);
		free(sf);
	}
}


static void for_each_sfile(int (*func)(struct sfile *))
{
	struct list_head * pos;
	struct list_head * pos2;

	list_for_each_safe(pos, pos2, &lru_list) {
		struct sfile * sf = list_entry(pos, struct sfile, lru);
		for_one_sfile(sf, func);
	}
}


void sfile_clear_kernel(void)
{
	for_each_sfile(is_sfile_kernel);
}


void sfile_clear_anon(void)
{
	for_each_sfile(is_sfile_anon);
}


void sfile_sync_files(void)
{
	for_each_sfile(sync_sfile);
}


void sfile_close_files(void)
{
	for_each_sfile(close_sfile);
}


static int always_true(void)
{
	return 1;
}


#define LRU_AMOUNT 256

/*
 * Clear out older sfiles. Note the current sfiles we're using
 * will not be present in this list, due to sfile_get/put() pairs
 * around the caller of this.
 */
int sfile_lru_clear(void)
{
	struct list_head * pos;
	struct list_head * pos2;
	int amount = LRU_AMOUNT;

	if (list_empty(&lru_list))
		return 1;

	list_for_each_safe(pos, pos2, &lru_list) {
		struct sfile * sf;
		if (!--amount)
			break;
		sf = list_entry(pos, struct sfile, lru);
		for_one_sfile(sf, (int (*)(struct sfile *))always_true);
	}

	return 0;
}


void sfile_get(struct sfile * sf)
{
	if (sf)
		list_del(&sf->lru);
}


void sfile_put(struct sfile * sf)
{
	if (sf)
		list_add_tail(&sf->lru, &lru_list);
}


void sfile_init(void)
{
	size_t i = 0;

	for (; i < HASH_SIZE; ++i)
		list_init(&hashes[i]);
}
