Hi Stephane, On Mon June 12 2006 2:45 am, Stephane Eranian wrote: > I looked at the patch and it looks good!
Great! > I have the following remarks: > - I would use a #define instead of hardcoding 32 Certainly. > - I would define the following macro to simplify code reading: > #define PFM_HAS_EVENT_MASK() \ > (pfm_current->get_num_event_masks && > pfm_current->get_event_mask_name) Ok. > I think we should only have one function to return the maximum name length > for both event and unit mask names. Otherwise, it gets a little bit too > complicated. I would add a function called pfm_get_max_name_len(size_t > *len). If it is not too much pain, we could replace the existing function > with this one. Sounds like a good idea. I've replaced pfm_get_max_event_mask_name_len() with pfm_get_max_name_len(). For now I've left pfm_get_max_event_name_len(), but changed it to simply call pfm_get_max_name_len(). Once we fix up all the callers of that API we can drop the old one. > Another question is about unit mask enumeration. How would a user > application enumerate all the unit masks for a given event? > I think if we guarantee that unit mask indexes are contiguous then we can > ierate from 0 to pfm_get_num_event_masks() with a simple for loop. Yeah, that's what I had in mind, and how I've been coding the pentium4 module. Here's a new patch with the above changes. -- Kevin Corry [EMAIL PROTECTED] http://www.ibm.com/linux/ http://evms.sourceforge.net/ Add unit-mask APIs to libpfm. Signed-Off-By: Kevin Corry <[EMAIL PROTECTED]> Index: include/perfmon/pfmlib.h =================================================================== RCS file: /cvsroot/perfmon2/libpfm/include/perfmon/pfmlib.h,v retrieving revision 1.3 diff -u -r1.3 pfmlib.h --- include/perfmon/pfmlib.h 15 May 2006 13:57:01 -0000 1.3 +++ include/perfmon/pfmlib.h 12 Jun 2006 14:44:18 -0000 @@ -72,6 +72,8 @@ } pfmlib_regmask_t; +#define PFMLIB_MAX_MASKS_PER_EVENT 32 + /* * event description for pfmlib_input_param_t */ @@ -79,6 +81,8 @@ unsigned int event; /* event descriptor */ unsigned int plm; /* event privilege level mask */ unsigned long flags; /* per-event flag */ + unsigned int unit_masks[PFMLIB_MAX_MASKS_PER_EVENT]; /* unit-mask identifiers */ + unsigned int num_masks; /* number of masks specified in 'unit_masks' */ unsigned long reserved[2]; /* for future use */ } pfmlib_event_t; @@ -164,14 +168,19 @@ extern int pfm_find_event_byname(const char *name, unsigned int *idx); extern int pfm_find_event_bycode(int code, unsigned int *idx); extern int pfm_find_event_bycode_next(int code, unsigned int start, unsigned int *next); +extern int pfm_find_event_mask(unsigned int event_idx, const char *str, unsigned int *mask_idx); extern int pfm_get_max_event_name_len(size_t *len); +extern int pfm_get_max_name_len(size_t *len); extern int pfm_get_num_events(unsigned int *count); +extern int pfm_get_num_event_masks(unsigned int event_idx, unsigned int *count); extern int pfm_get_event_name(unsigned int idx, char *name, size_t maxlen); extern int pfm_get_event_code(unsigned int idx, int *code); extern int pfm_get_event_counters(unsigned int idx, pfmlib_regmask_t *counters); extern int pfm_get_event_description(unsigned int idx, char **str); extern int pfm_get_event_code_counter(unsigned int idx, unsigned int cnt, int *code); +extern int pfm_get_event_mask_name(unsigned int event_idx, unsigned int mask_idx, char *name, size_t maxlen); +extern int pfm_get_event_mask_description(unsigned int event_idx, unsigned int mask_idx, char **desc); extern int pfm_print_event_info(const char *name, int (*pf)(const char *fmt,...)); extern int pfm_print_event_info_byindex(unsigned int idx, int (*pf)(const char *fmt,...)); Index: lib/pfmlib_common.c =================================================================== RCS file: /cvsroot/perfmon2/libpfm/lib/pfmlib_common.c,v retrieving revision 1.4 diff -u -r1.4 pfmlib_common.c --- lib/pfmlib_common.c 2 Jun 2006 12:55:01 -0000 1.4 +++ lib/pfmlib_common.c 12 Jun 2006 14:44:18 -0000 @@ -335,6 +335,28 @@ } int +pfm_find_event_mask(unsigned int event_idx, const char *str, unsigned int *mask_idx) +{ + unsigned int i, num_masks = 0; + + if (PFMLIB_INITIALIZED() == 0) return PFMLIB_ERR_NOINIT; + + if (str == NULL || mask_idx == NULL) return PFMLIB_ERR_INVAL; + + if (PFMLIB_HAS_EVENT_MASKS()) { + pfm_current->get_num_event_masks(event_idx, &num_masks); + for (i = 0; i < num_masks; i++) { + if (!strcasecmp(pfm_current->get_event_mask_name(event_idx, i), str)) { + *mask_idx = i; + return PFMLIB_SUCCESS; + } + } + } + + return PFMLIB_ERR_NOTFOUND; +} + +int pfm_get_event_name(unsigned int i, char *name, size_t maxlen) { if (PFMLIB_INITIALIZED() == 0) return PFMLIB_ERR_NOINIT; @@ -381,6 +403,22 @@ return PFMLIB_SUCCESS; } +int +pfm_get_event_mask_name(unsigned int event_idx, unsigned int mask_idx, char *name, size_t maxlen) +{ + if (PFMLIB_INITIALIZED() == 0) return PFMLIB_ERR_NOINIT; + + if (event_idx >= pfm_current->pme_count || name == NULL || maxlen < 1) return PFMLIB_ERR_INVAL; + + if (!PFMLIB_HAS_EVENT_MASKS()) { + return PFMLIB_ERR_NOTSUPP; + } + + strncpy(name, pfm_current->get_event_mask_name(event_idx, mask_idx), maxlen-1); + name[maxlen-1] = '\0'; + + return PFMLIB_SUCCESS; +} int pfm_get_num_events(unsigned int *count) @@ -394,6 +432,20 @@ return PFMLIB_SUCCESS; } +int +pfm_get_num_event_masks(unsigned int event_idx, unsigned int *count) +{ + if (PFMLIB_INITIALIZED() == 0) return PFMLIB_ERR_NOINIT; + + if (event_idx >= pfm_current->pme_count || count == NULL) return PFMLIB_ERR_INVAL; + + if (!PFMLIB_HAS_EVENT_MASKS()) { + *count = 0; + return PFMLIB_SUCCESS; + } + + return pfm_current->get_num_event_masks(event_idx, count); +} /* * Function used to print information about a specific events. More than @@ -408,6 +460,7 @@ int code, ret, n; int event_is_digit = 0; unsigned int idx, next_idx, num_counters, i; + unsigned int num_masks; if (PFMLIB_INITIALIZED() == 0) return PFMLIB_ERR_NOINIT; @@ -457,6 +510,14 @@ } (*pf)( "]\n"); + if (PFMLIB_HAS_EVENT_MASKS()) { + pfm_current->get_num_event_masks(idx, &num_masks); + for (i = 0; i < num_masks; i++) { + (*pf)("Unit-mask %d: %s\n", + i, pfm_current->get_event_mask_name(idx, i)); + } + } + /* print PMU specific information */ if (pfm_current->print_info) { pfm_current->print_info(idx, pf); @@ -473,7 +534,7 @@ pfm_print_event_info_byindex(unsigned int v, int (*pf)(const char *fmt,...)) { pfmlib_regmask_t cmask, impl_counters; - unsigned int i, n; + unsigned int i, n, num_masks; int code; if (PFMLIB_INITIALIZED() == 0) return PFMLIB_ERR_NOINIT; @@ -499,6 +560,14 @@ } (*pf)( "]\n"); + if (PFMLIB_HAS_EVENT_MASKS()) { + pfm_current->get_num_event_masks(v, &num_masks); + for (i = 0; i < num_masks; i++) { + (*pf)("Unit-mask %d: %s\n", + v, pfm_current->get_event_mask_name(v, i)); + } + } + /* print PMU specific information */ if (pfm_current->print_info) { pfm_current->print_info(v, pf); @@ -704,9 +773,9 @@ } int -pfm_get_max_event_name_len(size_t *len) +pfm_get_max_name_len(size_t *len) { - unsigned int i; + unsigned int i, j, num_masks; size_t max = 0, l; if (PFMLIB_INITIALIZED() == 0) return PFMLIB_ERR_NOINIT; @@ -715,12 +784,26 @@ for(i=0; i < pfm_current->pme_count; i++) { l = strlen(pfm_current->get_event_name(i)); if (l > max) max = l; + + if (PFMLIB_HAS_EVENT_MASKS()) { + pfm_current->get_num_event_masks(i, &num_masks); + for (j = 0; j < num_masks; j++) { + l = strlen(pfm_current->get_event_mask_name(i, j)); + if (l > max) max = l; + } + } } *len = max; return PFMLIB_SUCCESS; } +int +pfm_get_max_event_name_len(size_t *len) +{ + return pfm_get_max_name_len(len); +} + /* * return the index of the event that counts elapsed cycles */ @@ -768,3 +851,19 @@ } return pfm_current->get_event_desc(i, str); } + +int +pfm_get_event_mask_description(unsigned int event_idx, unsigned int mask_idx, char **desc) +{ + if (PFMLIB_INITIALIZED() == 0) return PFMLIB_ERR_NOINIT; + + if (event_idx >= pfm_current->pme_count || desc == NULL) return PFMLIB_ERR_INVAL; + + if (pfm_current->get_event_mask_desc == NULL) { + *desc = NULL; + return PFMLIB_SUCCESS; + } + + return pfm_current->get_event_mask_desc(event_idx, mask_idx, desc); +} + Index: lib/pfmlib_priv.h =================================================================== RCS file: /cvsroot/perfmon2/libpfm/lib/pfmlib_priv.h,v retrieving revision 1.3 diff -u -r1.3 pfmlib_priv.h --- lib/pfmlib_priv.h 2 Jun 2006 12:55:01 -0000 1.3 +++ lib/pfmlib_priv.h 12 Jun 2006 14:44:18 -0000 @@ -41,7 +41,9 @@ unsigned int flags; int (*get_event_code)(unsigned int i, unsigned int cnt, int *code); char *(*get_event_name)(unsigned int i); + char *(*get_event_mask_name)(unsigned int event_idx, unsigned int mask_idx); void (*get_event_counters)(unsigned int i, pfmlib_regmask_t *counters); + int (*get_num_event_masks)(unsigned int event_idx, unsigned int *count); int (*print_info)(unsigned int v, int (*pf)(const char *fmt,...)); int (*dispatch_events)(pfmlib_input_param_t *p, void *model_in, pfmlib_output_param_t *q, void *model_out); int (*pmu_detect)(void); @@ -50,6 +52,7 @@ void (*get_impl_counters)(pfmlib_regmask_t *impl_counters); void (*get_hw_counter_width)(unsigned int *width); int (*get_event_desc)(unsigned int i, char **buf); + int (*get_event_mask_desc)(unsigned int event_idx, unsigned int mask_idx, char **buf); } pfm_pmu_support_t; #define PFMLIB_MULT_CODE_EVENT 0x1 /* more than one code per event (depending on counter) */ @@ -71,6 +74,9 @@ #define PFMLIB_VERBOSE() pfm_config.options.pfm_verbose #define pfm_current pfm_config.current +#define PFMLIB_HAS_EVENT_MASKS() (pfm_current->get_num_event_masks != NULL && \ + pfm_current->get_event_mask_name != NULL) + extern void __pfm_vbprintf(const char *fmt,...); #ifdef PFMLIB_DEBUG _______________________________________________ perfmon mailing list [email protected] http://www.hpl.hp.com/hosted/linux/mail-archives/perfmon/
