{"action":"created","comment":{"url":"https://api.github.com/repos/OPAE/opae-sdk/pulls/comments/228677774","pull_request_review_id":169003065,"id":228677774,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyODY3Nzc3NA==","diff_hunk":"@@ -0,0 +1,1286 @@\n+// Copyright(c) 2018, Intel Corporation\n+//\n+// Redistribution  and  use  in source  and  binary  forms,  with  or  without\n+// modification, are permitted provided that the following conditions are met:\n+//\n+// * Redistributions of  source code  must retain the  above copyright notice,\n+//   this list of conditions and the following disclaimer.\n+// * Redistributions in binary form must reproduce the above copyright notice,\n+//   this list of conditions and the following disclaimer in the documentation\n+//   and/or other materials provided with the distribution.\n+// * Neither the name  of Intel Corporation  nor the names of its contributors\n+//   may be used to  endorse or promote  products derived  from this  software\n+//   without specific prior written permission.\n+//\n+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE\n+// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE\n+// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR\n+// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF\n+// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS\n+// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN\n+// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)\n+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE\n+// POSSIBILITY OF SUCH DAMAGE.\n+\n+/**\n+* \\file metrics_utils.c\n+* \\brief fpga metrics utils functions\n+*/\n+\n+#ifdef HAVE_CONFIG_H\n+#include <config.h>\n+#endif // HAVE_CONFIG_H\n+\n+\n+#include <sys/types.h>\n+#include <sys/stat.h>\n+#include <fcntl.h>\n+#include <dirent.h>\n+#include <uuid/uuid.h>\n+#include <dlfcn.h>\n+\n+#include \"common_int.h\"\n+#include \"metrics_int.h\"\n+#include \"types_int.h\"\n+#include \"opae/metrics.h\"\n+#include \"metrics/vector.h\"\n+#include \"xfpga.h\"\n+#include \"metrics/bmc/bmc.h\"\n+#include \"safe_string/safe_string.h\"\n+#include \"metrics/metrics_metadata.h\"\n+\n+\n+fpga_result metric_sysfs_path_is_dir(const char *path)\n+{\n+\tstruct stat astats;\n+\n+\tif (path == NULL) {\n+\t\treturn FPGA_INVALID_PARAM;\n+\t}\n+\n+\tif ((stat(path, &astats)) != 0) {\n+\t\treturn FPGA_NOT_FOUND;\n+\t}\n+\n+\tif (S_ISDIR(astats.st_mode)) {\n+\t\treturn FPGA_OK;\n+\t}\n+\n+\treturn FPGA_NOT_FOUND;\n+}\n+\n+fpga_result metric_sysfs_path_is_file(const char *path)\n+{\n+\tstruct stat astats;\n+\n+\tif (path == NULL) {\n+\t\treturn FPGA_INVALID_PARAM;\n+\t}\n+\n+\tif ((stat(path, &astats)) != 0) {\n+\t\treturn FPGA_NOT_FOUND;\n+\t}\n+\n+\tif (S_ISREG(astats.st_mode)) {\n+\t\treturn FPGA_OK;\n+\t}\n+\n+\treturn FPGA_NOT_FOUND;\n+}\n+\n+// Adds Metrics info to vector\n+fpga_result add_metric_vector(fpga_metric_vector *vector,\n+\t\t\t\tuint64_t metric_num,\n+\t\t\t\tconst char *qualifier_name,\n+\t\t\t\tconst char *group_name,\n+\t\t\t\tconst char *group_sysfs,\n+\t\t\t\tconst char *metric_name,\n+\t\t\t\tconst char *metric_sysfs,\n+\t\t\t\tconst char *metric_units,\n+\t\t\t\tenum fpga_metric_datatype  metric_datatype,\n+\t\t\t\tenum fpga_metric_type\tmetric_type,\n+\t\t\t\tenum fpga_hw_type\thw_type,\n+\t\t\t\tuint64_t mmio_offset)\n+{\n+\n+\tfpga_result result                           = FPGA_OK;\n+\tstruct _fpga_enum_metric *fpga_enum_metric   = NULL;\n+\terrno_t e                                    = 0;\n+\n+\tif (vector == NULL ||\n+\t\tgroup_name == NULL ||\n+\t\tgroup_sysfs == NULL ||\n+\t\tmetric_name == NULL ||\n+\t\tmetric_sysfs == NULL ||\n+\t\tqualifier_name == NULL ||\n+\t\tmetric_units == NULL) {\n+\t\tFPGA_ERR(\"Invlaid Input parameters\");\n+\t\treturn FPGA_INVALID_PARAM;\n+\t}\n+\n+\tfpga_enum_metric = (struct _fpga_enum_metric *)malloc(sizeof(struct _fpga_enum_metric));\n+\tif (fpga_enum_metric == NULL) {\n+\t\tFPGA_ERR(\"Failed to allocate memory\");\n+\t\treturn FPGA_NO_MEMORY;\n+\t}\n+\n+\te = strncpy_s(fpga_enum_metric->group_name, sizeof(fpga_enum_metric->group_name),\n+\t\tgroup_name, SYSFS_PATH_MAX);\n+\tif (EOK != e)\n+\t\tgoto out_free;\n+\n+\te = strncpy_s(fpga_enum_metric->group_sysfs, sizeof(fpga_enum_metric->group_sysfs),\n+\t\tgroup_sysfs, SYSFS_PATH_MAX);\n+\tif (EOK != e)\n+\t\tgoto out_free;\n+\n+\te = strncpy_s(fpga_enum_metric->metric_name, sizeof(fpga_enum_metric->metric_name),\n+\t\tmetric_name, SYSFS_PATH_MAX);\n+\tif (EOK != e)\n+\t\tgoto out_free;\n+\n+\te = strncpy_s(fpga_enum_metric->metric_sysfs, sizeof(fpga_enum_metric->metric_sysfs),\n+\t\tmetric_sysfs, SYSFS_PATH_MAX);\n+\tif (EOK != e)\n+\t\tgoto out_free;\n+\n+\te = strncpy_s(fpga_enum_metric->qualifier_name, sizeof(fpga_enum_metric->qualifier_name),\n+\t\tqualifier_name, SYSFS_PATH_MAX);\n+\tif (EOK != e)\n+\t\tgoto out_free;\n+\n+\te = strncpy_s(fpga_enum_metric->metric_units, sizeof(fpga_enum_metric->metric_units),\n+\t\tmetric_units, SYSFS_PATH_MAX);\n+\tif (EOK != e)\n+\t\tgoto out_free;\n+\n+\n+\tfpga_enum_metric->metric_type = metric_type;\n+\tfpga_enum_metric->metric_datatype = metric_datatype;\n+\tfpga_enum_metric->hw_type = hw_type;\n+\tfpga_enum_metric->metric_num = metric_num;\n+\tfpga_enum_metric->mmio_offset = mmio_offset;\n+\n+\tfpga_vector_push(vector, fpga_enum_metric);\n+\n+\treturn result;\n+\n+out_free:\n+\tfree(fpga_enum_metric);\n+\treturn FPGA_INVALID_PARAM;\n+}\n+\n+\n+fpga_result get_metric_data_info(const char *group_name,\n+\t\t\t\tconst char *metric_name,\n+\t\t\t\tfpga_metric_metadata *metric_data_serach,\n+\t\t\t\tuint64_t size,\n+\t\t\t\tfpga_metric_metadata *metric_data)\n+{\n+\tfpga_result result       = FPGA_OK;\n+\tuint64_t i               = 0;\n+\tint group_indicator      = 0;\n+\tint metric_indicator     = 0;\n+\n+\tif (group_name == NULL ||\n+\t\tmetric_name == NULL ||\n+\t\tmetric_data_serach == NULL ||\n+\t\tmetric_data == NULL) {\n+\t\tFPGA_ERR(\"Invlaid Input Paramters\");\n+\t\treturn FPGA_INVALID_PARAM;\n+\t}\n+\n+\tfor (i = 0; i < size; i++) {\n+\n+\t\tstrcasecmp_s(metric_data_serach[i].group_name, sizeof(metric_data_serach[i].group_name),\n+\t\t\tgroup_name, &group_indicator);\n+\n+\t\tstrcasecmp_s(metric_data_serach[i].metric_name, sizeof(metric_data_serach[i].metric_name),\n+\t\t\tmetric_name, &metric_indicator);\n+\n+\t\tif (group_indicator == 0 &&\n+\t\t\tmetric_indicator == 0) {\n+\n+\t\t\t*metric_data = (struct fpga_metric_metadata)metric_data_serach[i];\n+\t\t\treturn result;\n+\t\t}\n+\n+\t}\n+\n+\treturn FPGA_NOT_SUPPORTED;\n+}\n+\n+// enumurates theraml metrics info\n+fpga_result enum_thermalmgmt_metrics(fpga_metric_vector *vector,\n+\t\t\t\t\tuint64_t *metric_num,\n+\t\t\t\t\tconst char *sysfspath,\n+\t\t\t\t\tenum fpga_hw_type\thw_type)\n+{\n+\tfpga_result result                      = FPGA_OK;\n+\tDIR *dir                                = NULL;\n+\tstruct dirent *dirent                   = NULL;\n+\tchar sysfs_path[SYSFS_PATH_MAX]         = { 0 };\n+\tchar metric_sysfs[SYSFS_PATH_MAX]       = { 0 };\n+\tfpga_metric_metadata metric_data;\n+\n+\tmemset(&metric_data, 0, sizeof(metric_data));\n+\n+\tif (vector == NULL ||\n+\t\tsysfspath == NULL ||\n+\t\tmetric_num == NULL) {\n+\t\tFPGA_ERR(\"Invlaid Input parameters\");\n+\t\treturn FPGA_INVALID_PARAM;\n+\t}\n+\n+\tsnprintf_s_ss(sysfs_path, sizeof(sysfs_path), \"%s/%s\", sysfspath, THERLGMT);\n+\n+\tdir = opendir(sysfs_path);\n+\tif (NULL == dir) {\n+\t\tFPGA_MSG(\"can't find dir %s \", strerror(errno));\n+\t\treturn FPGA_NOT_FOUND;\n+\t}\n+\n+\twhile ((dirent = readdir(dir)) != NULL) {\n+\t\tif (!strcmp(dirent->d_name, \".\"))\n+\t\t\tcontinue;\n+\t\tif (!strcmp(dirent->d_name, \"..\"))\n+\t\t\tcontinue;\n+\t\tif (!strcmp(dirent->d_name, REVISION))\n+\t\t\tcontinue;\n+\n+\t\tsnprintf_s_ss(metric_sysfs, sizeof(metric_sysfs), \"%s/%s\", sysfs_path, dirent->d_name);\n+\n+\t\tresult =  get_metric_data_info(THERLGMT, dirent->d_name, mcp_metric_metadata, MCP_MDATA_SIZE, &metric_data);\n+\t\tif (result != FPGA_OK) {\n+\t\t\tFPGA_MSG(\"Failed to get metric metadata \");\n+\t\t}\n+\n+\t\tresult = add_metric_vector(vector, *metric_num, THERLGMT, THERLGMT, sysfs_path, dirent->d_name, metric_sysfs, metric_data.metric_units,\n+\t\t\t\t\t\t\t\tFPGA_METRIC_DATATYPE_INT, FPGA_METRIC_TYPE_THERMAL, hw_type, 0);\n+\t\tif (result != FPGA_OK) {\n+\t\t\tclosedir(dir);\n+\t\t\tFPGA_MSG(\"Failed to add metrics\");\n+\t\t\treturn result;\n+\t\t}\n+\n+\t\t*metric_num = *metric_num + 1;\n+\n+\t}\n+\tclosedir(dir);\n+\treturn result;\n+}\n+\n+// enumurates power metrics info\n+fpga_result enum_powermgmt_metrics(fpga_metric_vector *vector,\n+\t\t\t\t\tuint64_t *metric_num,\n+\t\t\t\t\tconst char *sysfspath,\n+\t\t\t\t\tenum fpga_hw_type hw_type)\n+{\n+\tfpga_result result                  = FPGA_OK;\n+\tDIR *dir                            = NULL;\n+\tstruct dirent *dirent               = NULL;\n+\tchar sysfs_path[SYSFS_PATH_MAX]     = { 0 };\n+\tchar metric_sysfs[SYSFS_PATH_MAX]   = { 0 };\n+\tfpga_metric_metadata metric_data ;\n+\n+\tmemset(&metric_data, 0, sizeof(metric_data));\n+\n+\tif (vector == NULL ||\n+\t\tsysfspath == NULL ||\n+\t\tmetric_num == NULL) {\n+\t\tFPGA_ERR(\"Invlaid Input parameters\");\n+\t\treturn FPGA_INVALID_PARAM;\n+\t}\n+\n+\tsnprintf_s_ss(sysfs_path, sizeof(sysfs_path), \"%s/%s\", sysfspath, PWRMGMT);\n+\n+\tdir = opendir(sysfs_path);\n+\tif (NULL == dir) {\n+\t\tFPGA_MSG(\"can't find dir %s \", strerror(errno));\n+\t\treturn FPGA_NOT_FOUND;\n+\t}\n+\n+\twhile ((dirent = readdir(dir)) != NULL) {\n+\t\tif (!strcmp(dirent->d_name, \".\"))\n+\t\t\tcontinue;\n+\t\tif (!strcmp(dirent->d_name, \"..\"))\n+\t\t\tcontinue;\n+\t\tif (!strcmp(dirent->d_name, REVISION))\n+\t\t\tcontinue;\n+\n+\t\tsnprintf_s_ss(metric_sysfs, sizeof(metric_sysfs), \"%s/%s\", sysfs_path, dirent->d_name);\n+\n+\t\tresult = get_metric_data_info(PWRMGMT, dirent->d_name, mcp_metric_metadata, MCP_MDATA_SIZE, &metric_data);\n+\t\tif (result != FPGA_OK) {\n+\t\t\tFPGA_MSG(\"Failed to get metric metadata \");\n+\t\t}\n+\n+\t\tresult = add_metric_vector(vector, *metric_num, PWRMGMT, PWRMGMT, sysfs_path, dirent->d_name, metric_sysfs, metric_data.metric_units,\n+\t\t\t\t\t\t\t\t\tFPGA_METRIC_DATATYPE_INT, FPGA_METRIC_TYPE_POWER, hw_type, 0);\n+\t\tif (result != FPGA_OK) {\n+\t\t\tFPGA_MSG(\"Failed to add metrics\");\n+\t\t\tclosedir(dir);\n+\t\t\treturn result;\n+\t\t}\n+\n+\t\t*metric_num = *metric_num + 1;\n+\t}\n+\tclosedir(dir);\n+\treturn result;\n+}\n+\n+// enumurates performance counters metrics info\n+fpga_result enum_perf_counter_items(fpga_metric_vector *vector,\n+\t\t\t\tuint64_t *metric_num,\n+\t\t\t\tconst char *qualifier_name,\n+\t\t\t\tconst char *sysfspath,\n+\t\t\t\tconst char *sysfs_name,\n+\t\t\t\tenum fpga_metric_type metric_type,\n+\t\t\t\tenum fpga_hw_type  hw_type)\n+{\n+\tfpga_result result                  = FPGA_OK;\n+\tDIR *dir                            = NULL;\n+\tstruct dirent *dirent               = NULL;\n+\tchar sysfs_path[SYSFS_PATH_MAX]     = { 0 };\n+\tchar metric_sysfs[SYSFS_PATH_MAX]   = { 0 };\n+\tchar qname[SYSFS_PATH_MAX]          = { 0 };\n+\n+\tif (vector == NULL ||\n+\t\tsysfspath == NULL ||\n+\t\tsysfs_name == NULL ||\n+\t\tqualifier_name == NULL ||\n+\t\tmetric_num == NULL) {\n+\t\tFPGA_ERR(\"Invlaid Input parameters\");\n+\t\treturn FPGA_INVALID_PARAM;\n+\t}\n+\n+\n+\tsnprintf_s_ss(sysfs_path, sizeof(sysfs_path), \"%s/%s\", sysfspath, sysfs_name);\n+\n+\tdir = opendir(sysfs_path);\n+\tif (NULL == dir) {\n+\t\tFPGA_MSG(\"can't find dir %s \", strerror(errno));\n+\t\treturn FPGA_NOT_FOUND;\n+\t}\n+\n+\twhile ((dirent = readdir(dir)) != NULL) {\n+\t\tif (!strcmp(dirent->d_name, \".\"))\n+\t\t\tcontinue;\n+\t\tif (!strcmp(dirent->d_name, \"..\"))\n+\t\t\tcontinue;\n+\t\tif (!strcmp(dirent->d_name, PERF_ENABLE))\n+\t\t\tcontinue;\n+\n+\t\tif (!strcmp(dirent->d_name, PERF_FREEZE))\n+\t\t\tcontinue;\n+\n+\t\tif (dirent->d_type == DT_DIR) {\n+\n+\t\t\tsnprintf_s_ss(qname, sizeof(qname), \"%s:%s\", qualifier_name, dirent->d_name);\n+\n+\t\t\tresult = enum_perf_counter_items(vector, metric_num, qname, sysfs_path, dirent->d_name, metric_type, hw_type);\n+\t\t\tif (result != FPGA_OK) {\n+\t\t\t\tFPGA_MSG(\"Failed to add metrics\");\n+\t\t\t}\n+\t\t\tcontinue;\n+\n+\t\t}\n+\n+\t\tsnprintf_s_ss(metric_sysfs, sizeof(metric_sysfs), \"%s/%s\", sysfs_path, dirent->d_name);\n+\n+\t\tresult = add_metric_vector(vector, *metric_num, qualifier_name, \"performance\", sysfs_path, dirent->d_name,\n+\t\t\tmetric_sysfs, \"\", FPGA_METRIC_DATATYPE_INT, metric_type, hw_type, 0);\n+\t\tif (result != FPGA_OK) {\n+\t\t\tFPGA_MSG(\"Failed to add metrics\");\n+\t\t\tclosedir(dir);\n+\t\t\treturn result;\n+\t\t}\n+\n+\t\t*metric_num = *metric_num + 1;\n+\t}\n+\tclosedir(dir);\n+\treturn result;\n+\n+}\n+\n+// enumurates performance counters metrics info\n+fpga_result enum_perf_counter_metrics(fpga_metric_vector *vector,\n+\t\t\t\t\tuint64_t *metric_num,\n+\t\t\t\t\tconst char *sysfspath,\n+\t\t\t\t\tenum fpga_hw_type  hw_type)\n+{\n+\tfpga_result result                  = FPGA_OK;\n+\tDIR *dir                            = NULL;\n+\tstruct dirent *dirent               = NULL;\n+\tchar sysfs_path[SYSFS_PATH_MAX]     = { 0 };\n+\tchar sysfs_ipath[SYSFS_PATH_MAX]    = { 0 };\n+\tchar sysfs_dpath[SYSFS_PATH_MAX]    = { 0 };\n+\tchar qualifier_name[SYSFS_PATH_MAX] = { 0 };\n+\n+\tif (vector == NULL ||\n+\t\tsysfspath == NULL ||\n+\t\tmetric_num == NULL) {\n+\t\tFPGA_ERR(\"Invlaid Input parameters\");\n+\t\treturn FPGA_INVALID_PARAM;\n+\t}\n+\n+\tsnprintf_s_ss(sysfs_ipath, sizeof(sysfs_ipath), \"%s/%s\", sysfspath, IPERF);\n+\tsnprintf_s_ss(sysfs_dpath, sizeof(sysfs_dpath), \"%s/%s\", sysfspath, DPERF);\n+\n+\n+\tif (metric_sysfs_path_is_dir(sysfs_ipath) == FPGA_OK) {\n+\n+\t\tsnprintf_s_ss(sysfs_path, sizeof(sysfs_path), \"%s/%s\", sysfspath, IPERF);\n+\n+\n+\t} else if (metric_sysfs_path_is_dir(sysfs_dpath) == FPGA_OK) {\n+\n+\t\tsnprintf_s_ss(sysfs_path, sizeof(sysfs_path), \"%s/%s\", sysfspath, DPERF);\n+\n+\t} else {\n+\t\tFPGA_MSG(\"NO Perf Counters\");\n+\t\treturn FPGA_NOT_FOUND;\n+\t}\n+\n+\tdir = opendir(sysfs_path);\n+\tif (NULL == dir) {\n+\t\tFPGA_MSG(\"can't find dirt %s \", strerror(errno));\n+\t\treturn FPGA_NOT_FOUND;\n+\t}\n+\n+\twhile ((dirent = readdir(dir)) != NULL) {\n+\n+\t\tif (!strcmp(dirent->d_name, \".\"))\n+\t\t\tcontinue;\n+\t\tif (!strcmp(dirent->d_name, \"..\"))\n+\t\t\tcontinue;\n+\t\tif (!strcmp(dirent->d_name, REVISION))\n+\t\t\tcontinue;\n+\n+\n+\t\tif (strcmp(dirent->d_name, PERF_CACHE) == 0) {\n+\t\t\tsnprintf_s_ss(qualifier_name, sizeof(qualifier_name), \"%s:%s\", PERF, PERF_CACHE);\n+\t\t\tresult = enum_perf_counter_items(vector, metric_num, qualifier_name, sysfs_path, dirent->d_name, FPGA_METRIC_TYPE_PERFORMANCE_CTR, hw_type);\n+\t\t\tif (result != FPGA_OK) {\n+\t\t\t\tFPGA_MSG(\"Failed to add metrics\");\n+\t\t\t}\n+\n+\t\t}\n+\n+\t\tif (strcmp(dirent->d_name, PERF_FABRIC) == 0) {\n+\t\t\tsnprintf_s_ss(qualifier_name, sizeof(qualifier_name), \"%s:%s\", PERF, PERF_FABRIC);\n+\t\t\tresult = enum_perf_counter_items(vector, metric_num, qualifier_name, sysfs_path, dirent->d_name, FPGA_METRIC_TYPE_PERFORMANCE_CTR, hw_type);\n+\t\t\tif (result != FPGA_OK) {\n+\t\t\t\tFPGA_MSG(\"Failed to add metrics\");\n+\t\t\t}\n+\n+\t\t}\n+\n+\t\tif (strcmp(dirent->d_name, PERF_IOMMU) == 0) {\n+\t\t\tsnprintf_s_ss(qualifier_name, sizeof(qualifier_name), \"%s:%s\", PERF, PERF_IOMMU);\n+\t\t\tresult = enum_perf_counter_items(vector, metric_num, qualifier_name, sysfs_path, dirent->d_name, FPGA_METRIC_TYPE_PERFORMANCE_CTR, hw_type);\n+\t\t\tif (result != FPGA_OK) {\n+\t\t\t\tFPGA_MSG(\"Failed to add metrics\");\n+\t\t\t}\n+\n+\t\t}\n+\n+\t}\n+\tclosedir(dir);\n+\treturn result;\n+}\n+\n+fpga_result xfpga_bmcLoadSDRs(struct _fpga_handle *_handle,\n+\t\tbmc_sdr_handle *records,\n+\t\tuint32_t *num_sensors)\n+{\n+\tfpga_result result = FPGA_NOT_FOUND;\n+\tfpga_result(*bmcLoadSDRs)(fpga_token token, bmc_sdr_handle *records,\n+\t\tuint32_t *num_sensors);\n+\tif (_handle->bmc_handle != NULL) {\n+\t\t\n+\t\tbmcLoadSDRs = dlsym(_handle->bmc_handle, \"bmcLoadSDRs\");\n+\t\tif (bmcLoadSDRs)\n+\t\t\tresult = bmcLoadSDRs(_handle->token, records, num_sensors);\n+\n+\t}\n+\treturn result;\n+}\n+\n+fpga_result xfpga_bmcDestroySDRs(struct _fpga_handle *_handle,\n+\t\tbmc_sdr_handle *records)\n+{\n+\tfpga_result result = FPGA_NOT_FOUND;\n+\tfpga_result(*bmcDestroySDRs)(bmc_sdr_handle *records);\n+\n+\tif (_handle->bmc_handle != NULL) {\n+\n+\t\tbmcDestroySDRs = dlsym(_handle->bmc_handle, \"bmcDestroySDRs\");\n+\t\tif (bmcDestroySDRs)\n+\t\t\tresult = bmcDestroySDRs(records);\n+\n+\t}\n+\treturn result;\n+}\n+\n+\n+fpga_result xfpga_bmcReadSensorValues(struct _fpga_handle *_handle,\n+\t\tbmc_sdr_handle records,\n+\t\tbmc_values_handle *values,\n+\t\tuint32_t *num_values)\n+{\n+\tfpga_result result = FPGA_NOT_FOUND;\n+\tfpga_result(*bmcReadSensorValues)(bmc_sdr_handle records, bmc_values_handle *values, uint32_t *num_values);\n+\n+\tif (_handle->bmc_handle != NULL) {\n+\n+\t\tbmcReadSensorValues = dlsym(_handle->bmc_handle, \"bmcReadSensorValues\");\n+\t\tif (bmcReadSensorValues)","path":"libopae/plugins/xfpga/metrics/metrics_utils.c","position":540,"original_position":540,"commit_id":"e36342447c520c14ced07a9b156889a9802d03aa","original_commit_id":"e36342447c520c14ced07a9b156889a9802d03aa","user":{"login":"tswhison","id":33638304,"node_id":"MDQ6VXNlcjMzNjM4MzA0","avatar_url":"https://avatars3.githubusercontent.com/u/33638304?v=4","gravatar_id":"","url":"https://api.github.com/users/tswhison","html_url":"https://github.com/tswhison","followers_url":"https://api.github.com/users/tswhison/followers","following_url":"https://api.github.com/users/tswhison/following{/other_user}","gists_url":"https://api.github.com/users/tswhison/gists{/gist_id}","starred_url":"https://api.github.com/users/tswhison/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tswhison/subscriptions","organizations_url":"https://api.github.com/users/tswhison/orgs","repos_url":"https://api.github.com/users/tswhison/repos","events_url":"https://api.github.com/users/tswhison/events{/privacy}","received_events_url":"https://api.github.com/users/tswhison/received_events","type":"User","site_admin":false},"body":"Please add\r\n```c\r\nelse\r\n   result = FPGA_EXCEPTION;\r\n```","created_at":"2018-10-26T22:06:54Z","updated_at":"2018-10-26T22:19:22Z","html_url":"https://github.com/OPAE/opae-sdk/pull/873#discussion_r228677774","pull_request_url":"https://api.github.com/repos/OPAE/opae-sdk/pulls/873","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/OPAE/opae-sdk/pulls/comments/228677774"},"html":{"href":"https://github.com/OPAE/opae-sdk/pull/873#discussion_r228677774"},"pull_request":{"href":"https://api.github.com/repos/OPAE/opae-sdk/pulls/873"}}},"pull_request":{"url":"https://api.github.com/repos/OPAE/opae-sdk/pulls/873","id":226227270,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI2MjI3Mjcw","html_url":"https://github.com/OPAE/opae-sdk/pull/873","diff_url":"https://github.com/OPAE/opae-sdk/pull/873.diff","patch_url":"https://github.com/OPAE/opae-sdk/pull/873.patch","issue_url":"https://api.github.com/repos/OPAE/opae-sdk/issues/873","number":873,"state":"open","locked":false,"title":"add Metrics api","user":{"login":"anandaravuri","id":33236856,"node_id":"MDQ6VXNlcjMzMjM2ODU2","avatar_url":"https://avatars2.githubusercontent.com/u/33236856?v=4","gravatar_id":"","url":"https://api.github.com/users/anandaravuri","html_url":"https://github.com/anandaravuri","followers_url":"https://api.github.com/users/anandaravuri/followers","following_url":"https://api.github.com/users/anandaravuri/following{/other_user}","gists_url":"https://api.github.com/users/anandaravuri/gists{/gist_id}","starred_url":"https://api.github.com/users/anandaravuri/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/anandaravuri/subscriptions","organizations_url":"https://api.github.com/users/anandaravuri/orgs","repos_url":"https://api.github.com/users/anandaravuri/repos","events_url":"https://api.github.com/users/anandaravuri/events{/privacy}","received_events_url":"https://api.github.com/users/anandaravuri/received_events","type":"User","site_admin":false},"body":"Changes:\r\n- Added metrics API\r\n- Added test cases\r\n- Support MCP/ DCP cards","created_at":"2018-10-26T21:10:57Z","updated_at":"2018-10-26T22:19:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6db6eea80222690c89e1908dbbf753b0a237c353","assignee":null,"assignees":[],"requested_reviewers":[{"login":"r-rojo","id":22808196,"node_id":"MDQ6VXNlcjIyODA4MTk2","avatar_url":"https://avatars3.githubusercontent.com/u/22808196?v=4","gravatar_id":"","url":"https://api.github.com/users/r-rojo","html_url":"https://github.com/r-rojo","followers_url":"https://api.github.com/users/r-rojo/followers","following_url":"https://api.github.com/users/r-rojo/following{/other_user}","gists_url":"https://api.github.com/users/r-rojo/gists{/gist_id}","starred_url":"https://api.github.com/users/r-rojo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/r-rojo/subscriptions","organizations_url":"https://api.github.com/users/r-rojo/orgs","repos_url":"https://api.github.com/users/r-rojo/repos","events_url":"https://api.github.com/users/r-rojo/events{/privacy}","received_events_url":"https://api.github.com/users/r-rojo/received_events","type":"User","site_admin":false}],"requested_teams":[{"name":"ci","id":2649373,"node_id":"MDQ6VGVhbTI2NDkzNzM=","slug":"ci","description":"Maintainers for the build and CI infrastructure","privacy":"closed","url":"https://api.github.com/teams/2649373","members_url":"https://api.github.com/teams/2649373/members{/member}","repositories_url":"https://api.github.com/teams/2649373/repos","permission":"pull"},{"name":"tools","id":2649384,"node_id":"MDQ6VGVhbTI2NDkzODQ=","slug":"tools","description":"Maintainers for tools","privacy":"closed","url":"https://api.github.com/teams/2649384","members_url":"https://api.github.com/teams/2649384/members{/member}","repositories_url":"https://api.github.com/teams/2649384/repos","permission":"pull"}],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/OPAE/opae-sdk/pulls/873/commits","review_comments_url":"https://api.github.com/repos/OPAE/opae-sdk/pulls/873/comments","review_comment_url":"https://api.github.com/repos/OPAE/opae-sdk/pulls/comments{/number}","comments_url":"https://api.github.com/repos/OPAE/opae-sdk/issues/873/comments","statuses_url":"https://api.github.com/repos/OPAE/opae-sdk/statuses/e36342447c520c14ced07a9b156889a9802d03aa","head":{"label":"OPAE:aravuri/cp_metric_api","ref":"aravuri/cp_metric_api","sha":"e36342447c520c14ced07a9b156889a9802d03aa","user":{"login":"OPAE","id":30705801,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwNzA1ODAx","avatar_url":"https://avatars2.githubusercontent.com/u/30705801?v=4","gravatar_id":"","url":"https://api.github.com/users/OPAE","html_url":"https://github.com/OPAE","followers_url":"https://api.github.com/users/OPAE/followers","following_url":"https://api.github.com/users/OPAE/following{/other_user}","gists_url":"https://api.github.com/users/OPAE/gists{/gist_id}","starred_url":"https://api.github.com/users/OPAE/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OPAE/subscriptions","organizations_url":"https://api.github.com/users/OPAE/orgs","repos_url":"https://api.github.com/users/OPAE/repos","events_url":"https://api.github.com/users/OPAE/events{/privacy}","received_events_url":"https://api.github.com/users/OPAE/received_events","type":"Organization","site_admin":false},"repo":{"id":102083635,"node_id":"MDEwOlJlcG9zaXRvcnkxMDIwODM2MzU=","name":"opae-sdk","full_name":"OPAE/opae-sdk","private":false,"owner":{"login":"OPAE","id":30705801,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwNzA1ODAx","avatar_url":"https://avatars2.githubusercontent.com/u/30705801?v=4","gravatar_id":"","url":"https://api.github.com/users/OPAE","html_url":"https://github.com/OPAE","followers_url":"https://api.github.com/users/OPAE/followers","following_url":"https://api.github.com/users/OPAE/following{/other_user}","gists_url":"https://api.github.com/users/OPAE/gists{/gist_id}","starred_url":"https://api.github.com/users/OPAE/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OPAE/subscriptions","organizations_url":"https://api.github.com/users/OPAE/orgs","repos_url":"https://api.github.com/users/OPAE/repos","events_url":"https://api.github.com/users/OPAE/events{/privacy}","received_events_url":"https://api.github.com/users/OPAE/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/OPAE/opae-sdk","description":"Open Programmable Acceleration Engine","fork":false,"url":"https://api.github.com/repos/OPAE/opae-sdk","forks_url":"https://api.github.com/repos/OPAE/opae-sdk/forks","keys_url":"https://api.github.com/repos/OPAE/opae-sdk/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OPAE/opae-sdk/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OPAE/opae-sdk/teams","hooks_url":"https://api.github.com/repos/OPAE/opae-sdk/hooks","issue_events_url":"https://api.github.com/repos/OPAE/opae-sdk/issues/events{/number}","events_url":"https://api.github.com/repos/OPAE/opae-sdk/events","assignees_url":"https://api.github.com/repos/OPAE/opae-sdk/assignees{/user}","branches_url":"https://api.github.com/repos/OPAE/opae-sdk/branches{/branch}","tags_url":"https://api.github.com/repos/OPAE/opae-sdk/tags","blobs_url":"https://api.github.com/repos/OPAE/opae-sdk/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OPAE/opae-sdk/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OPAE/opae-sdk/git/refs{/sha}","trees_url":"https://api.github.com/repos/OPAE/opae-sdk/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OPAE/opae-sdk/statuses/{sha}","languages_url":"https://api.github.com/repos/OPAE/opae-sdk/languages","stargazers_url":"https://api.github.com/repos/OPAE/opae-sdk/stargazers","contributors_url":"https://api.github.com/repos/OPAE/opae-sdk/contributors","subscribers_url":"https://api.github.com/repos/OPAE/opae-sdk/subscribers","subscription_url":"https://api.github.com/repos/OPAE/opae-sdk/subscription","commits_url":"https://api.github.com/repos/OPAE/opae-sdk/commits{/sha}","git_commits_url":"https://api.github.com/repos/OPAE/opae-sdk/git/commits{/sha}","comments_url":"https://api.github.com/repos/OPAE/opae-sdk/comments{/number}","issue_comment_url":"https://api.github.com/repos/OPAE/opae-sdk/issues/comments{/number}","contents_url":"https://api.github.com/repos/OPAE/opae-sdk/contents/{+path}","compare_url":"https://api.github.com/repos/OPAE/opae-sdk/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OPAE/opae-sdk/merges","archive_url":"https://api.github.com/repos/OPAE/opae-sdk/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OPAE/opae-sdk/downloads","issues_url":"https://api.github.com/repos/OPAE/opae-sdk/issues{/number}","pulls_url":"https://api.github.com/repos/OPAE/opae-sdk/pulls{/number}","milestones_url":"https://api.github.com/repos/OPAE/opae-sdk/milestones{/number}","notifications_url":"https://api.github.com/repos/OPAE/opae-sdk/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OPAE/opae-sdk/labels{/name}","releases_url":"https://api.github.com/repos/OPAE/opae-sdk/releases{/id}","deployments_url":"https://api.github.com/repos/OPAE/opae-sdk/deployments","created_at":"2017-09-01T07:00:50Z","updated_at":"2018-10-26T22:13:20Z","pushed_at":"2018-10-26T22:14:23Z","git_url":"git://github.com/OPAE/opae-sdk.git","ssh_url":"git@github.com:OPAE/opae-sdk.git","clone_url":"https://github.com/OPAE/opae-sdk.git","svn_url":"https://github.com/OPAE/opae-sdk","homepage":"https://01.org/OPAE","size":9514,"stargazers_count":127,"watchers_count":127,"language":"Verilog","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":33,"mirror_url":null,"archived":false,"open_issues_count":29,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":33,"open_issues":29,"watchers":127,"default_branch":"master"}},"base":{"label":"OPAE:master","ref":"master","sha":"0453d7597f6eca077e1c183e8ef2982f33412164","user":{"login":"OPAE","id":30705801,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwNzA1ODAx","avatar_url":"https://avatars2.githubusercontent.com/u/30705801?v=4","gravatar_id":"","url":"https://api.github.com/users/OPAE","html_url":"https://github.com/OPAE","followers_url":"https://api.github.com/users/OPAE/followers","following_url":"https://api.github.com/users/OPAE/following{/other_user}","gists_url":"https://api.github.com/users/OPAE/gists{/gist_id}","starred_url":"https://api.github.com/users/OPAE/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OPAE/subscriptions","organizations_url":"https://api.github.com/users/OPAE/orgs","repos_url":"https://api.github.com/users/OPAE/repos","events_url":"https://api.github.com/users/OPAE/events{/privacy}","received_events_url":"https://api.github.com/users/OPAE/received_events","type":"Organization","site_admin":false},"repo":{"id":102083635,"node_id":"MDEwOlJlcG9zaXRvcnkxMDIwODM2MzU=","name":"opae-sdk","full_name":"OPAE/opae-sdk","private":false,"owner":{"login":"OPAE","id":30705801,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMwNzA1ODAx","avatar_url":"https://avatars2.githubusercontent.com/u/30705801?v=4","gravatar_id":"","url":"https://api.github.com/users/OPAE","html_url":"https://github.com/OPAE","followers_url":"https://api.github.com/users/OPAE/followers","following_url":"https://api.github.com/users/OPAE/following{/other_user}","gists_url":"https://api.github.com/users/OPAE/gists{/gist_id}","starred_url":"https://api.github.com/users/OPAE/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OPAE/subscriptions","organizations_url":"https://api.github.com/users/OPAE/orgs","repos_url":"https://api.github.com/users/OPAE/repos","events_url":"https://api.github.com/users/OPAE/events{/privacy}","received_events_url":"https://api.github.com/users/OPAE/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/OPAE/opae-sdk","description":"Open Programmable Acceleration Engine","fork":false,"url":"https://api.github.com/repos/OPAE/opae-sdk","forks_url":"https://api.github.com/repos/OPAE/opae-sdk/forks","keys_url":"https://api.github.com/repos/OPAE/opae-sdk/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OPAE/opae-sdk/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OPAE/opae-sdk/teams","hooks_url":"https://api.github.com/repos/OPAE/opae-sdk/hooks","issue_events_url":"https://api.github.com/repos/OPAE/opae-sdk/issues/events{/number}","events_url":"https://api.github.com/repos/OPAE/opae-sdk/events","assignees_url":"https://api.github.com/repos/OPAE/opae-sdk/assignees{/user}","branches_url":"https://api.github.com/repos/OPAE/opae-sdk/branches{/branch}","tags_url":"https://api.github.com/repos/OPAE/opae-sdk/tags","blobs_url":"https://api.github.com/repos/OPAE/opae-sdk/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OPAE/opae-sdk/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OPAE/opae-sdk/git/refs{/sha}","trees_url":"https://api.github.com/repos/OPAE/opae-sdk/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OPAE/opae-sdk/statuses/{sha}","languages_url":"https://api.github.com/repos/OPAE/opae-sdk/languages","stargazers_url":"https://api.github.com/repos/OPAE/opae-sdk/stargazers","contributors_url":"https://api.github.com/repos/OPAE/opae-sdk/contributors","subscribers_url":"https://api.github.com/repos/OPAE/opae-sdk/subscribers","subscription_url":"https://api.github.com/repos/OPAE/opae-sdk/subscription","commits_url":"https://api.github.com/repos/OPAE/opae-sdk/commits{/sha}","git_commits_url":"https://api.github.com/repos/OPAE/opae-sdk/git/commits{/sha}","comments_url":"https://api.github.com/repos/OPAE/opae-sdk/comments{/number}","issue_comment_url":"https://api.github.com/repos/OPAE/opae-sdk/issues/comments{/number}","contents_url":"https://api.github.com/repos/OPAE/opae-sdk/contents/{+path}","compare_url":"https://api.github.com/repos/OPAE/opae-sdk/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OPAE/opae-sdk/merges","archive_url":"https://api.github.com/repos/OPAE/opae-sdk/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OPAE/opae-sdk/downloads","issues_url":"https://api.github.com/repos/OPAE/opae-sdk/issues{/number}","pulls_url":"https://api.github.com/repos/OPAE/opae-sdk/pulls{/number}","milestones_url":"https://api.github.com/repos/OPAE/opae-sdk/milestones{/number}","notifications_url":"https://api.github.com/repos/OPAE/opae-sdk/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OPAE/opae-sdk/labels{/name}","releases_url":"https://api.github.com/repos/OPAE/opae-sdk/releases{/id}","deployments_url":"https://api.github.com/repos/OPAE/opae-sdk/deployments","created_at":"2017-09-01T07:00:50Z","updated_at":"2018-10-26T22:13:20Z","pushed_at":"2018-10-26T22:14:23Z","git_url":"git://github.com/OPAE/opae-sdk.git","ssh_url":"git@github.com:OPAE/opae-sdk.git","clone_url":"https://github.com/OPAE/opae-sdk.git","svn_url":"https://github.com/OPAE/opae-sdk","homepage":"https://01.org/OPAE","size":9514,"stargazers_count":127,"watchers_count":127,"language":"Verilog","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":33,"mirror_url":null,"archived":false,"open_issues_count":29,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":33,"open_issues":29,"watchers":127,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/OPAE/opae-sdk/pulls/873"},"html":{"href":"https://github.com/OPAE/opae-sdk/pull/873"},"issue":{"href":"https://api.github.com/repos/OPAE/opae-sdk/issues/873"},"comments":{"href":"https://api.github.com/repos/OPAE/opae-sdk/issues/873/comments"},"review_comments":{"href":"https://api.github.com/repos/OPAE/opae-sdk/pulls/873/comments"},"review_comment":{"href":"https://api.github.com/repos/OPAE/opae-sdk/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/OPAE/opae-sdk/pulls/873/commits"},"statuses":{"href":"https://api.github.com/repos/OPAE/opae-sdk/statuses/e36342447c520c14ced07a9b156889a9802d03aa"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"tswhison"}}