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/

Reply via email to