### Eclipse Workspace Patch 1.0
#P papi
Index: src/libpfm4/include/perfmon/pfmlib.h
===================================================================
RCS file: /depot/devenv/bullxde/perftools/papi_repo/papi/src/libpfm4/include/perfmon/pfmlib.h,v
retrieving revision 1.12
diff -u -r1.12 pfmlib.h
--- src/libpfm4/include/perfmon/pfmlib.h	28 Mar 2014 20:54:24 -0000	1.12
+++ src/libpfm4/include/perfmon/pfmlib.h	8 Apr 2014 23:13:13 -0000
@@ -375,6 +375,18 @@
 	} SWIG_NAME(defaults);
 } pfm_event_attr_info_t;
 
+
+#define UNK_ATTR_MAX_COUNT 10
+#define UNK_ATTR_NAME_SIZE 20
+#define UNK_ATTR_VALUE_SIZE 10
+typedef struct {
+	int			used;	/* number of entries used in this table */
+	struct {
+		char	name[UNK_ATTR_NAME_SIZE];	/* attribute symbolic name */
+		char	value[UNK_ATTR_VALUE_SIZE];	/* attribute symbolic value (NULL if value not provided) */
+	} attr[UNK_ATTR_MAX_COUNT];
+} pfm_event_attr_unknown_t;
+
 /*
  * use with PFM_OS_NONE for pfm_get_os_event_encoding()
  */
@@ -419,6 +431,7 @@
  */
 extern int pfm_get_event_next(int idx);
 extern int pfm_find_event(const char *str);
+extern int pfm_find_event_mask(const char *str, pfm_event_attr_unknown_t *unknown_mask_list);
 extern pfm_err_t pfm_get_event_info(int idx, pfm_os_t os, pfm_event_info_t *output);
 
 /*
@@ -427,6 +440,7 @@
  * content of args depends on value of os (refer to man page)
  */
 extern pfm_err_t pfm_get_os_event_encoding(const char *str, int dfl_plm, pfm_os_t os, void *args);
+extern pfm_err_t pfm_get_os_event_encoding_mask(const char *str, int dfl_plm, pfm_os_t uos, void *args, pfm_event_attr_unknown_t *unknown_mask_list);
 
 /*
  * attribute API
Index: src/libpfm4/lib/pfmlib_common.c
===================================================================
RCS file: /depot/devenv/bullxde/perftools/papi_repo/papi/src/libpfm4/lib/pfmlib_common.c,v
retrieving revision 1.14
diff -u -r1.14 pfmlib_common.c
--- src/libpfm4/lib/pfmlib_common.c	28 Mar 2014 20:54:24 -0000	1.14
+++ src/libpfm4/lib/pfmlib_common.c	8 Apr 2014 23:13:14 -0000
@@ -788,6 +788,15 @@
 int
 pfm_find_event(const char *str)
 {
+	DPRINT("ENTER: str: %s\n", str);
+	int ret = pfm_find_event_mask(str, NULL);
+	return ret;
+}
+
+int
+pfm_find_event_mask(const char *str, pfm_event_attr_unknown_t *unknown_mask_list)
+{
+	DPRINT("ENTER: str: %s, unknown_mask_list: %p\n", str, unknown_mask_list);
 	pfmlib_event_desc_t e;
 	int ret;
 
@@ -798,6 +807,12 @@
 		return PFM_ERR_INVAL;
 
 	memset(&e, 0, sizeof(e));
+	// if list of unknown masks was requested, set pointer to where to put them
+	if (unknown_mask_list != NULL) {
+		DPRINT("*unknown_mask_list: %p\n", unknown_mask_list);
+// check structure size before doing this assignment
+		e.uattrs = unknown_mask_list;
+	}
 
 	ret = pfmlib_parse_event(str, &e);
 	if (ret == PFM_SUCCESS)
@@ -895,8 +910,36 @@
 				goto found_attr;
 			}
 		}
-		DPRINT("cannot find attribute %s\n", s);
-		return PFM_ERR_ATTR;
+
+		// if the caller did not request a list of unknown attributes, return unknown attribute error (preserve old behavior)
+		if (d->uattrs == NULL) {
+			DPRINT("cannot find attribute %s\n", s);
+			return PFM_ERR_ATTR;
+		}
+
+		// our caller provided a place to put unknown attributes (they may have added support for additional event masks)
+		// save the attributes not recognized by libpfm4 and give them back to the caller
+		if (d->uattrs->used < UNK_ATTR_MAX_COUNT-1) {
+			int currCnt = d->uattrs->used;
+			DPRINT("put mask: %s, value: %s into %d unknown masks list\n", s, q, d->uattrs->used);
+			strncpy(d->uattrs->attr[currCnt].name, s, UNK_ATTR_NAME_SIZE);
+			d->uattrs->attr[currCnt].name[UNK_ATTR_NAME_SIZE-1] = '\0';
+			// if we have a value, store it
+			if (q != NULL) {
+				strncpy(d->uattrs->attr[currCnt].value, q, UNK_ATTR_VALUE_SIZE);
+				d->uattrs->attr[currCnt].value[UNK_ATTR_VALUE_SIZE-1] = '\0';
+			} else {
+				d->uattrs->attr[currCnt].value[0] = '\0';
+			}
+			d->uattrs->used++;
+			s = p;
+			continue;
+		}
+
+		DPRINT("unknown mask list full, mask: %s, value: %s discarded\n", s, q);
+		s = p;
+		continue;
+
 found_attr:
 		type = ainfo->type;
 
@@ -1289,6 +1332,12 @@
 int
 pfm_get_os_event_encoding(const char *str, int dfl_plm, pfm_os_t uos, void *args)
 {
+	return pfm_get_os_event_encoding_mask(str, dfl_plm, uos, args, NULL);
+}
+
+int
+pfm_get_os_event_encoding_mask(const char *str, int dfl_plm, pfm_os_t uos, void *args, pfm_event_attr_unknown_t *unknown_mask_list)
+{
 	pfmlib_os_t *os;
 
 	if (PFMLIB_INITIALIZED() == 0)
@@ -1304,7 +1353,7 @@
 	if (!os)
 		return PFM_ERR_NOTSUPP;
 
-	return os->encode(os, str, dfl_plm, args);
+	return os->encode(os, str, dfl_plm, args, unknown_mask_list);
 }
 
 /*
@@ -1829,7 +1878,7 @@
 }
 
 static int
-pfmlib_raw_pmu_encode(void *this, const char *str, int dfl_plm, void *data)
+pfmlib_raw_pmu_encode(void *this, const char *str, int dfl_plm, void *data, pfm_event_attr_unknown_t *unknown_mask_list)
 {
 	pfm_pmu_encode_arg_t arg;
 	pfm_pmu_encode_arg_t *uarg = data;
@@ -1854,6 +1903,8 @@
 
 	e.osid    = PFM_OS_NONE;
 	e.dfl_plm = dfl_plm;
+	// raw event encoding does not support unknown masks yet
+//	e.uattrs = unknown_mask_list;
 
 	ret = pfmlib_parse_event(str, &e);
 	if (ret != PFM_SUCCESS)
Index: src/libpfm4/lib/pfmlib_perf_event.c
===================================================================
RCS file: /depot/devenv/bullxde/perftools/papi_repo/papi/src/libpfm4/lib/pfmlib_perf_event.c,v
retrieving revision 1.9
diff -u -r1.9 pfmlib_perf_event.c
--- src/libpfm4/lib/pfmlib_perf_event.c	22 Jan 2014 22:27:17 -0000	1.9
+++ src/libpfm4/lib/pfmlib_perf_event.c	8 Apr 2014 23:13:14 -0000
@@ -71,8 +71,9 @@
 };
 
 static int
-pfmlib_perf_event_encode(void *this, const char *str, int dfl_plm, void *data)
+pfmlib_perf_event_encode(void *this, const char *str, int dfl_plm, void *data, pfm_event_attr_unknown_t *unknown_mask_list)
 {
+	DPRINT("ENTER: str: %s\n", str);
 	pfm_perf_encode_arg_t arg;
 	pfm_perf_encode_arg_t *uarg = data;
 	pfmlib_os_t *os = this;
@@ -129,6 +130,7 @@
 	e.osid = os->id;
 	e.os_data = attr;
 	e.dfl_plm = dfl_plm;
+	e.uattrs = unknown_mask_list;
 
 	/* after this call, need to call pfmlib_release_event() */
 	ret = pfmlib_parse_event(str, &e);
Index: src/libpfm4/lib/pfmlib_priv.h
===================================================================
RCS file: /depot/devenv/bullxde/perftools/papi_repo/papi/src/libpfm4/lib/pfmlib_priv.h,v
retrieving revision 1.15
diff -u -r1.15 pfmlib_priv.h
--- src/libpfm4/lib/pfmlib_priv.h	28 Mar 2014 20:54:24 -0000	1.15
+++ src/libpfm4/lib/pfmlib_priv.h	8 Apr 2014 23:13:14 -0000
@@ -91,6 +91,7 @@
 	pfmlib_attr_t		attrs[PFMLIB_MAX_ATTRS];	/* list of requested attributes */
 
 	pfm_event_attr_info_t	*pattrs;			/* list of possible attributes */
+	pfm_event_attr_unknown_t *uattrs;			/* list of unknown attributes (those provided in call that libpfm4 does not know about) */
 	char			fstr[PFMLIB_EVT_MAX_NAME_LEN];	/* fully qualified event string */
 	uint64_t		codes[PFMLIB_MAX_ENCODING];	/* event encoding */
 	void			*os_data;
@@ -148,7 +149,7 @@
 	int				(*detect)(void *this);
 	int				(*get_os_attr_info)(void *this, pfmlib_event_desc_t *e);
 	int				(*get_os_nattrs)(void *this, pfmlib_event_desc_t *e);
-	int				(*encode)(void *this, const char *str, int dfl_plm, void *args);
+	int				(*encode)(void *this, const char *str, int dfl_plm, void *args, pfm_event_attr_unknown_t *unknown_masks);
 } pfmlib_os_t;
 
 #define PFMLIB_OS_FL_ACTIVATED	0x1	/* OS layer detected */
