| /** |
| * @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; |
| } |
| |