/**
* @file opd_extended.c
* OProfile Extended Feature
*
* @remark Copyright 2007-2009 OProfile authors
* @remark Read the file COPYING
*
* @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
* Copyright (c) 2009 Advanced Micro Devices, Inc.
*/
#include "opd_extended.h"
#include "op_string.h"
#include <string.h>
#include <stdio.h>
/* This global variable is >= 0
* if extended feature is enabled */
static int opd_ext_feat_index;
extern struct opd_ext_handlers ibs_handlers;
/**
* OProfile Extended Feature Table
*
* This table contains a list of extended features.
*/
static struct opd_ext_feature ext_feature_table[] = {
{"ibs", &ibs_handlers },
{ NULL, NULL }
};
static int get_index_for_feature(char const * name)
{
int ret = -1;
unsigned int i;
if(!name)
return ret;
for (i = 0 ; ext_feature_table[i].feature != NULL ; i++ ) {
if(!strncmp(name, ext_feature_table[i].feature,
strlen(ext_feature_table[i].feature))) {
ret = i;
break;
}
}
return ret;
}
static inline int is_ext_enabled()
{
if (opd_ext_feat_index >= 0
&& ext_feature_table[opd_ext_feat_index].handlers != NULL)
return 1;
else
return 0;
}
static inline int is_ext_sfile_enabled()
{
if (opd_ext_feat_index >= 0
&& ext_feature_table[opd_ext_feat_index].handlers != NULL
&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile != NULL)
return 1;
else
return 0;
}
/**
* Param "value" is the input from CML option with the format:
*
* <feature name>:<param1>:<param2>:<param3>:.....
*
* where param1,2.3,..n are optional.
*/
int opd_ext_initialize(char const * value)
{
int ret = EXIT_FAILURE;
char * tmp = NULL, * name = NULL, * args = NULL;
if(!value) {
opd_ext_feat_index = -1;
return 0;
}
tmp = op_xstrndup(value, strlen(value));
/* Parse feature name*/
if((name = strtok_r(tmp, ":", &args)) == NULL)
goto err_out;
if((opd_ext_feat_index = get_index_for_feature(name)) < 0)
goto err_out;
ret = ext_feature_table[opd_ext_feat_index].handlers->ext_init(args);
return ret;
err_out:
fprintf(stderr,"opd_ext_initialize: Invalid extended feature option: %s\n", value);
return ret;
}
int opd_ext_deinitialize()
{
int ret = EXIT_FAILURE;
if(opd_ext_feat_index == -1) {
return 0;
}
ret = ext_feature_table[opd_ext_feat_index].handlers->ext_deinit();
return ret;
}
void opd_ext_print_stats()
{
if (is_ext_enabled()
&& ext_feature_table[opd_ext_feat_index].handlers->ext_print_stats != NULL) {
printf("\n-- OProfile Extended-Feature Statistics --\n");
ext_feature_table[opd_ext_feat_index].handlers->ext_print_stats();
}
}
/**
* opd_sfile extended APIs
*/
void opd_ext_sfile_create(struct sfile * sf)
{
/* Creating ext sfile only if extended feature is enable*/
if (is_ext_sfile_enabled()
&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->create != NULL)
ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->create(sf);
}
void opd_ext_sfile_dup (struct sfile * to, struct sfile * from)
{
/* Duplicate ext sfile only if extended feature is enable*/
if (is_ext_sfile_enabled()
&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->dup != NULL)
ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->dup(to, from);
}
void opd_ext_sfile_close (struct sfile * sf)
{
/* Close ext sfile only if extended feature is enable*/
if (is_ext_sfile_enabled()
&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->close != NULL)
ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->close(sf);
}
void opd_ext_sfile_sync(struct sfile * sf)
{
/* Sync ext sfile only if extended feature is enable*/
if (is_ext_sfile_enabled()
&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->sync != NULL)
ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->sync(sf);
}
odb_t * opd_ext_sfile_get(struct transient const * trans, int is_cg)
{
/* Get ext sfile only if extended feature is enable*/
if (is_ext_sfile_enabled()
&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->get != NULL)
return ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->get(trans, is_cg);
return NULL;
}
struct opd_event * opd_ext_find_counter_event(unsigned long counter)
{
/* Only if extended feature is enable*/
if (is_ext_sfile_enabled()
&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->find_counter_event != NULL)
return ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->find_counter_event(counter);
return NULL;
}