コード例 #1
0
ファイル: jevents.c プロジェクト: nkurz/pmu-tools
static int match_field(char *map, jsmntok_t *field, int nz,
		       char **event, jsmntok_t *val)
{
	struct field *f;
	jsmntok_t newval = *val;

	for (f = fields; f->field; f++)
		if (json_streq(map, field, f->field) && nz) {
			if (json_streq(map, val, "0x00") ||
			     json_streq(map, val, "0x0"))
				return 1;
			cut_comma(map, &newval);
			addfield(map, event, ",", f->kernel, &newval);
			return 1;
		}
	return 0;
}
コード例 #2
0
ファイル: jevents.c プロジェクト: nkurz/pmu-tools
static const char *field_to_perf(struct map *table, char *map, jsmntok_t *val)
{
	int i;

	for (i = 0; table[i].json; i++) {
		if (json_streq(map, val, table[i].json))
			return table[i].perf;
	}
	return NULL;
}
コード例 #3
0
ファイル: jevents.c プロジェクト: nikai3d/pmu-tools
static struct msrmap *lookup_msr(char *map, jsmntok_t *val)
{
    jsmntok_t newval = *val;
    static bool warned = false;
    int i;

    cut_comma(map, &newval);
    for (i = 0; msrmap[i].num; i++)
        if (json_streq(map, &newval, msrmap[i].num))
            return &msrmap[i];
    if (!warned) {
        warned = true;
        fprintf(stderr, "Unknown MSR in event file %.*s\n",
                json_len(val), map + val->start);
    }
    return NULL;
}
コード例 #4
0
ファイル: jevents.c プロジェクト: nkurz/pmu-tools
static struct msrmap *lookup_msr(char *map, jsmntok_t *val)
{
	jsmntok_t newval = *val;
	static bool warned = false;
	int i;

	cut_comma(map, &newval);
	for (i = 0; msrmap[i].num; i++)
		if (json_streq(map, &newval, msrmap[i].num))
			return &msrmap[i];
	if (!warned && strncmp(map + val->start, "0x3F7", 5)) {
		/* no warning for Skylake PEBS Frontend MSR */
		warned = true;
		fprintf(stderr, "Unknown MSR in event file %.*s\n",
			json_len(val), map + val->start);
	}
	return NULL;
}
コード例 #5
0
ファイル: jevents.c プロジェクト: nkurz/pmu-tools
/**
 * json_events - Read JSON event file from disk and call event callback.
 * @fn: File name to read or NULL for default.
 * @func: Callback to call for each event
 * @data: Abstract pointer to pass to func.
 *
 * The callback gets the data pointer, the event name, the event 
 * in perf format and a description passed.
 *
 * Call func with each event in the json file 
 * Return: -1 on failure, otherwise 0.
 */
int json_events(const char *fn,
	  int (*func)(void *data, char *name, char *event, char *desc, char *pmu),
	  void *data)
{
	int err = -EIO;
	size_t size;
	jsmntok_t *tokens, *tok;
	int i, j, len;
	char *map;
	char buf[128];
	const char *orig_fn = fn;

	if (!fn)
		fn = json_default_name("-core");
	tokens = parse_json(fn, &map, &size, &len);
	if (!tokens)
		return -EIO;
	EXPECT(tokens->type == JSMN_ARRAY, tokens, "expected top level array");
	tok = tokens + 1;
	for (i = 0; i < tokens->size; i++) {
		char *event = NULL, *desc = NULL, *name = NULL;
		char *pmu = NULL;
		char *filter = NULL;
		unsigned long long eventcode = 0;
		struct msrmap *msr = NULL;
		jsmntok_t *msrval = NULL;
		jsmntok_t *precise = NULL;
		jsmntok_t *obj = tok++;

		EXPECT(obj->type == JSMN_OBJECT, obj, "expected object");
		for (j = 0; j < obj->size; j += 2) {
			jsmntok_t *field, *val;
			int nz;

			field = tok + j;
			EXPECT(field->type == JSMN_STRING, tok + j,
			       "Expected field name");
			val = tok + j + 1;
			EXPECT(val->type == JSMN_STRING, tok + j + 1,
			       "Expected string value");

			nz = !json_streq(map, val, "0");
			if (match_field(map, field, nz, &event, val)) {
				/* ok */
			} else if (json_streq(map, field, "EventCode")) {
				char *code = NULL;
				addfield(map, &code, "", "", val);
				eventcode |= strtoul(code, NULL, 0);
				free(code);
			} else if (json_streq(map, field, "ExtSel")) {
				char *code = NULL;
				addfield(map, &code, "", "", val);
				eventcode |= strtoul(code, NULL, 0) << 21;
				free(code);
			} else if (json_streq(map, field, "EventName")) {
				addfield(map, &name, "", "", val);
			} else if (json_streq(map, field, "BriefDescription")) {
				addfield(map, &desc, "", "", val);
				fixdesc(desc);
			} else if (json_streq(map, field, "PEBS") && nz && desc &&
				   !strstr(desc, "(Precise Event)")) {
				precise = val;
			} else if (json_streq(map, field, "MSRIndex") && nz) {
				msr = lookup_msr(map, val);
			} else if (json_streq(map, field, "MSRValue")) {
				msrval = val;
			} else if (json_streq(map, field, "Errata") &&
				   !json_streq(map, val, "null")) {
				addfield(map, &desc, ". ",
					" Spec update: ", val);
			} else if (json_streq(map, field, "Data_LA") && nz) {
				addfield(map, &desc, ". ",
					" Supports address when precise",
					NULL);
			} else if (json_streq(map, field, "Unit")) {
				const char *ppmu;
				char *s;

				ppmu = field_to_perf(unit_to_pmu, map, val);
				if (ppmu) {
					pmu = strdup(ppmu);
				} else {
					addfield(map, &pmu, "", "", val);
					for (s = pmu; *s; s++)
						*s = tolower(*s);
				}
				addfield(map, &desc, ". ", "Unit: ", NULL);
				addfield(map, &desc, "", pmu, NULL);
			} else if (json_streq(map, field, "Filter")) {
				addfield(map, &filter, "", "", val);
			}
			/* ignore unknown fields */
		}
		if (precise) {
			if (json_streq(map, precise, "2"))
				addfield(map, &desc, " ", "(Must be precise)",
						NULL);
			else
				addfield(map, &desc, " ",
						"(Precise event)", NULL);
		}
		snprintf(buf, sizeof buf, "event=%#llx", eventcode);
		addfield(map, &event, ",", buf, NULL);
		if (filter)
			addfield(map, &event, ",", filter, NULL);
		if (msr != NULL)
			addfield(map, &event, ",", msr->pname, msrval);
		if (!pmu)
			pmu = strdup("cpu");
		err = -EIO;
		if (name && event) {
			fixname(name);
			err = func(data, name, event, desc, pmu);
		}
		free(event);
		free(desc);
		free(name);
		free(pmu);
		free(filter);
		if (err)
			break;
		tok += j;
	}
	EXPECT(tok - tokens == len, tok, "unexpected objects at end");
	err = 0;
out_free:
	free_json(map, size, tokens);
	if (!orig_fn && !err) {
		fn = json_default_name("-uncore");
		err = json_events(fn, func, data);
		/* Ignore open error */
		if (err == -EIO)
			return 0;
	}
	if (!orig_fn)
		free((char *)fn);
	return err;
}
コード例 #6
0
ファイル: jevents.c プロジェクト: nikai3d/pmu-tools
/**
 * json_events - Read JSON event file from disk and call event callback.
 * @fn: File name to read or NULL for default.
 * @func: Callback to call for each event
 * @data: Abstract pointer to pass to func.
 *
 * The callback gets the data pointer, the event name, the event
 * in perf format and a description passed.
 *
 * Call func with each event in the json file
 * Return: -1 on failure, otherwise 0.
 */
int json_events(const char *fn,
                int (*func)(void *data, char *name, char *event, char *desc),
                void *data)
{
    int err = -EIO;
    size_t size;
    jsmntok_t *tokens, *tok;
    int i, j, len;
    char *map;

    if (!fn)
        fn = json_default_name();
    tokens = parse_json(fn, &map, &size, &len);
    if (!tokens)
        return -EIO;
    EXPECT(tokens->type == JSMN_ARRAY, tokens, "expected top level array");
    tok = tokens + 1;
    for (i = 0; i < tokens->size; i++) {
        char *event = NULL, *desc = NULL, *name = NULL;
        struct msrmap *msr = NULL;
        jsmntok_t *msrval = NULL;
        jsmntok_t *precise = NULL;
        jsmntok_t *obj = tok++;

        EXPECT(obj->type == JSMN_OBJECT, obj, "expected object");
        for (j = 0; j < obj->size; j += 2) {
            jsmntok_t *field, *val;
            int nz;

            field = tok + j;
            EXPECT(field->type == JSMN_STRING, tok + j,
                   "Expected field name");
            val = tok + j + 1;
            EXPECT(val->type == JSMN_STRING, tok + j + 1,
                   "Expected string value");

            nz = !json_streq(map, val, "0");
            if (match_field(map, field, nz, &event, val)) {
                /* ok */
            } else if (json_streq(map, field, "EventName")) {
                addfield(map, &name, "", "", val);
            } else if (json_streq(map, field, "BriefDescription")) {
                addfield(map, &desc, "", "", val);
                fixdesc(desc);
            } else if (json_streq(map, field, "PEBS") && nz && desc &&
                       !strstr(desc, "(Precise Event)")) {
                precise = val;
            } else if (json_streq(map, field, "MSRIndex") && nz) {
                msr = lookup_msr(map, val);
            } else if (json_streq(map, field, "MSRValue")) {
                msrval = val;
            } else if (json_streq(map, field, "Errata") &&
                       !json_streq(map, val, "null")) {
                addfield(map, &desc, ". ",
                         " Spec update: ", val);
            } else if (json_streq(map, field, "Data_LA") && nz) {
                addfield(map, &desc, ". ",
                         " Supports address when precise",
                         NULL);
            }
            /* ignore unknown fields */
        }
        if (precise) {
            if (json_streq(map, precise, "2"))
                addfield(map, &desc, " ", "(Must be precise)",
                         NULL);
            else
                addfield(map, &desc, " ",
                         "(Precise event)", NULL);
        }
        if (msr != NULL)
            addfield(map, &event, ",", msr->pname, msrval);
        err = -EIO;
        if (name && event) {
            fixname(name);
            err = func(data, name, event, desc);
        }
        free(event);
        free(desc);
        free(name);
        if (err)
            break;
        tok += j;
    }
    EXPECT(tok - tokens == len, tok, "unexpected objects at end");
    err = 0;
out_free:
    free_json(map, size, tokens);
    return err;
}