15a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng/**
25a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * @file opd_extended.c
35a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * OProfile Extended Feature
45a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng *
55a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * @remark Copyright 2007-2009 OProfile authors
65a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * @remark Read the file COPYING
75a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng *
85a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
95a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * Copyright (c) 2009 Advanced Micro Devices, Inc.
105a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng */
115a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
125a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#include "opd_extended.h"
135a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#include "op_string.h"
145a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
155a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#include <string.h>
165a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#include <stdio.h>
175a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
185a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng/* This global variable is >= 0
195a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * if extended feature is enabled */
205a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengstatic int opd_ext_feat_index;
215a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
225a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengextern struct opd_ext_handlers ibs_handlers;
235a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
245a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng/**
255a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * OProfile Extended Feature Table
265a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng *
275a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * This table contains a list of extended features.
285a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng */
295a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengstatic struct opd_ext_feature ext_feature_table[] = {
305a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	{"ibs", &ibs_handlers },
315a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	{ NULL, NULL }
325a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng};
335a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
345a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
355a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengstatic int get_index_for_feature(char const * name)
365a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
375a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	int ret = -1;
385a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	unsigned int i;
395a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
405a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if(!name)
415a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		return ret;
425a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
435a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	for (i = 0 ; ext_feature_table[i].feature != NULL ; i++ ) {
445a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		if(!strncmp(name, ext_feature_table[i].feature,
455a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			strlen(ext_feature_table[i].feature))) {
465a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			ret = i;
475a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			break;
485a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		}
495a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
505a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
515a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	return ret;
525a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
535a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
545a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
555a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengstatic inline int is_ext_enabled()
565a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
575a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (opd_ext_feat_index >= 0
585a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	&& ext_feature_table[opd_ext_feat_index].handlers != NULL)
595a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		return 1;
605a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	else
615a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		return 0;
625a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
635a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
645a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
655a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengstatic inline int is_ext_sfile_enabled()
665a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
675a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (opd_ext_feat_index >= 0
685a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	&& ext_feature_table[opd_ext_feat_index].handlers != NULL
695a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile != NULL)
705a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		return 1;
715a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	else
725a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		return 0;
735a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
745a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
755a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
765a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng/**
775a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * Param "value" is the input from CML option with the format:
785a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng *
795a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * <feature name>:<param1>:<param2>:<param3>:.....
805a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng *
815a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * where param1,2.3,..n are optional.
825a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng */
835a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengint opd_ext_initialize(char const * value)
845a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
855a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	int ret = EXIT_FAILURE;
865a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char * tmp = NULL, * name = NULL, * args = NULL;
875a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
885a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if(!value) {
895a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		opd_ext_feat_index = -1;
905a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		return 0;
915a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
925a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
935a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	tmp = op_xstrndup(value, strlen(value));
945a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
955a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	/* Parse feature name*/
965a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if((name = strtok_r(tmp, ":", &args)) == NULL)
975a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		goto err_out;
985a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
995a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if((opd_ext_feat_index = get_index_for_feature(name)) < 0)
1005a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		goto err_out;
1015a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1025a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	ret = ext_feature_table[opd_ext_feat_index].handlers->ext_init(args);
1035a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1045a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	return ret;
1055a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1065a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengerr_out:
1075a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	fprintf(stderr,"opd_ext_initialize: Invalid extended feature option: %s\n", value);
1085a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	return ret;
1095a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1105a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1115a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1127a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brownint opd_ext_deinitialize()
1137a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown{
1147a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown	int ret = EXIT_FAILURE;
1157a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown
1167a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown	if(opd_ext_feat_index == -1) {
1177a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown		return 0;
1187a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown	}
1197a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown
1207a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown	ret = ext_feature_table[opd_ext_feat_index].handlers->ext_deinit();
1217a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown
1227a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown	return ret;
1237a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown}
1247a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown
1257a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown
1265a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengvoid opd_ext_print_stats()
1275a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1285a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (is_ext_enabled()
1295a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	&& ext_feature_table[opd_ext_feat_index].handlers->ext_print_stats != NULL) {
1305a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		printf("\n-- OProfile Extended-Feature Statistics --\n");
1315a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		ext_feature_table[opd_ext_feat_index].handlers->ext_print_stats();
1325a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
1335a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1345a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1355a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1365a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng/**
1375a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * opd_sfile extended APIs
1385a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng */
1395a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengvoid opd_ext_sfile_create(struct sfile * sf)
1405a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1415a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	/* Creating ext sfile only if extended feature is enable*/
1425a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (is_ext_sfile_enabled()
1435a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->create != NULL)
1445a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->create(sf);
1455a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1465a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1475a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1485a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengvoid opd_ext_sfile_dup (struct sfile * to, struct sfile * from)
1495a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1505a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	/* Duplicate ext sfile only if extended feature is enable*/
1515a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (is_ext_sfile_enabled()
1525a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->dup != NULL)
1535a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->dup(to, from);
1545a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1555a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1565a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1575a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengvoid opd_ext_sfile_close (struct sfile * sf)
1585a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1595a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	/* Close ext sfile only if extended feature is enable*/
1605a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (is_ext_sfile_enabled()
1615a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->close != NULL)
1625a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->close(sf);
1635a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1645a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1655a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1665a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengvoid opd_ext_sfile_sync(struct sfile * sf)
1675a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1685a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	/* Sync ext sfile only if extended feature is enable*/
1695a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (is_ext_sfile_enabled()
1705a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->sync != NULL)
1715a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->sync(sf);
1725a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1735a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1745a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1755a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengodb_t * opd_ext_sfile_get(struct transient const * trans, int is_cg)
1765a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1775a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	/* Get ext sfile only if extended feature is enable*/
1785a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (is_ext_sfile_enabled()
1795a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->get != NULL)
1805a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		return	ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->get(trans, is_cg);
1815a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1825a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	return NULL;
1835a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1845a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1855a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1865a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengstruct opd_event * opd_ext_find_counter_event(unsigned long counter)
1875a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1885a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	/* Only if extended feature is enable*/
1895a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (is_ext_sfile_enabled()
1905a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->find_counter_event != NULL)
1915a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		return	ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->find_counter_event(counter);
1925a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1935a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	return NULL;
1945a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1955a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
196