1/**
2 * @file opd_extended.c
3 * OProfile Extended Feature
4 *
5 * @remark Copyright 2007-2009 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
9 * Copyright (c) 2009 Advanced Micro Devices, Inc.
10 */
11
12#include "opd_extended.h"
13#include "op_string.h"
14
15#include <string.h>
16#include <stdio.h>
17
18/* This global variable is >= 0
19 * if extended feature is enabled */
20static int opd_ext_feat_index;
21
22extern struct opd_ext_handlers ibs_handlers;
23
24/**
25 * OProfile Extended Feature Table
26 *
27 * This table contains a list of extended features.
28 */
29static struct opd_ext_feature ext_feature_table[] = {
30	{"ibs", &ibs_handlers },
31	{ NULL, NULL }
32};
33
34
35static int get_index_for_feature(char const * name)
36{
37	int ret = -1;
38	unsigned int i;
39
40	if(!name)
41		return ret;
42
43	for (i = 0 ; ext_feature_table[i].feature != NULL ; i++ ) {
44		if(!strncmp(name, ext_feature_table[i].feature,
45			strlen(ext_feature_table[i].feature))) {
46			ret = i;
47			break;
48		}
49	}
50
51	return ret;
52}
53
54
55static inline int is_ext_enabled()
56{
57	if (opd_ext_feat_index >= 0
58	&& ext_feature_table[opd_ext_feat_index].handlers != NULL)
59		return 1;
60	else
61		return 0;
62}
63
64
65static inline int is_ext_sfile_enabled()
66{
67	if (opd_ext_feat_index >= 0
68	&& ext_feature_table[opd_ext_feat_index].handlers != NULL
69	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile != NULL)
70		return 1;
71	else
72		return 0;
73}
74
75
76/**
77 * Param "value" is the input from CML option with the format:
78 *
79 * <feature name>:<param1>:<param2>:<param3>:.....
80 *
81 * where param1,2.3,..n are optional.
82 */
83int opd_ext_initialize(char const * value)
84{
85	int ret = EXIT_FAILURE;
86	char * tmp = NULL, * name = NULL, * args = NULL;
87
88	if(!value) {
89		opd_ext_feat_index = -1;
90		return 0;
91	}
92
93	tmp = op_xstrndup(value, strlen(value));
94
95	/* Parse feature name*/
96	if((name = strtok_r(tmp, ":", &args)) == NULL)
97		goto err_out;
98
99	if((opd_ext_feat_index = get_index_for_feature(name)) < 0)
100		goto err_out;
101
102	ret = ext_feature_table[opd_ext_feat_index].handlers->ext_init(args);
103
104	return ret;
105
106err_out:
107	fprintf(stderr,"opd_ext_initialize: Invalid extended feature option: %s\n", value);
108	return ret;
109}
110
111
112int opd_ext_deinitialize()
113{
114	int ret = EXIT_FAILURE;
115
116	if(opd_ext_feat_index == -1) {
117		return 0;
118	}
119
120	ret = ext_feature_table[opd_ext_feat_index].handlers->ext_deinit();
121
122	return ret;
123}
124
125
126void opd_ext_print_stats()
127{
128	if (is_ext_enabled()
129	&& ext_feature_table[opd_ext_feat_index].handlers->ext_print_stats != NULL) {
130		printf("\n-- OProfile Extended-Feature Statistics --\n");
131		ext_feature_table[opd_ext_feat_index].handlers->ext_print_stats();
132	}
133}
134
135
136/**
137 * opd_sfile extended APIs
138 */
139void opd_ext_sfile_create(struct sfile * sf)
140{
141	/* Creating ext sfile only if extended feature is enable*/
142	if (is_ext_sfile_enabled()
143	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->create != NULL)
144		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->create(sf);
145}
146
147
148void opd_ext_sfile_dup (struct sfile * to, struct sfile * from)
149{
150	/* Duplicate ext sfile only if extended feature is enable*/
151	if (is_ext_sfile_enabled()
152	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->dup != NULL)
153		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->dup(to, from);
154}
155
156
157void opd_ext_sfile_close (struct sfile * sf)
158{
159	/* Close ext sfile only if extended feature is enable*/
160	if (is_ext_sfile_enabled()
161	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->close != NULL)
162		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->close(sf);
163}
164
165
166void opd_ext_sfile_sync(struct sfile * sf)
167{
168	/* Sync ext sfile only if extended feature is enable*/
169	if (is_ext_sfile_enabled()
170	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->sync != NULL)
171		ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->sync(sf);
172}
173
174
175odb_t * opd_ext_sfile_get(struct transient const * trans, int is_cg)
176{
177	/* Get ext sfile only if extended feature is enable*/
178	if (is_ext_sfile_enabled()
179	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->get != NULL)
180		return	ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->get(trans, is_cg);
181
182	return NULL;
183}
184
185
186struct opd_event * opd_ext_find_counter_event(unsigned long counter)
187{
188	/* Only if extended feature is enable*/
189	if (is_ext_sfile_enabled()
190	&& ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->find_counter_event != NULL)
191		return	ext_feature_table[opd_ext_feat_index].handlers->ext_sfile->find_counter_event(counter);
192
193	return NULL;
194}
195
196