tools/perf/util/hwmon_pmu.c

Source file repositories/reference/linux-study-clean/tools/perf/util/hwmon_pmu.c

File Facts

System
Linux kernel
Corpus path
tools/perf/util/hwmon_pmu.c
Extension
.c
Size
20391 bytes
Lines
836
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct hwmon_pmu {
	struct perf_pmu pmu;
	struct hashmap events;
	char *hwmon_dir;
};

/**
 * struct hwmon_pmu_event_value: Value in hwmon_pmu->events.
 *
 * Hwmon files are of the form <type><number>_<item> and may have a suffix
 * _alarm.
 */
struct hwmon_pmu_event_value {
	/** @items: which item files are present. */
	DECLARE_BITMAP(items, HWMON_ITEM__MAX);
	/** @alarm_items: which item files are present. */
	DECLARE_BITMAP(alarm_items, HWMON_ITEM__MAX);
	/** @label: contents of <type><number>_label if present. */
	char *label;
	/** @name: name computed from label of the form <type>_<label>. */
	char *name;
};

bool perf_pmu__is_hwmon(const struct perf_pmu *pmu)
{
	return pmu && pmu->type >= PERF_PMU_TYPE_HWMON_START &&
		pmu->type <= PERF_PMU_TYPE_HWMON_END;
}

bool evsel__is_hwmon(const struct evsel *evsel)
{
	return perf_pmu__is_hwmon(evsel->pmu);
}

static size_t hwmon_pmu__event_hashmap_hash(long key, void *ctx __maybe_unused)
{
	return ((union hwmon_pmu_event_key)key).type_and_num;
}

static bool hwmon_pmu__event_hashmap_equal(long key1, long key2, void *ctx __maybe_unused)
{
	return ((union hwmon_pmu_event_key)key1).type_and_num ==
	       ((union hwmon_pmu_event_key)key2).type_and_num;
}

static int hwmon_strcmp(const void *a, const void *b)
{
	const char *sa = a;
	const char * const *sb = b;

	return strcmp(sa, *sb);
}

bool parse_hwmon_filename(const char *filename,
			  enum hwmon_type *type,
			  int *number,
			  enum hwmon_item *item,
			  bool *alarm)
{
	char fn_type[24];
	const char * const *elem;
	const char *fn_item = NULL;
	size_t fn_item_len;

	assert(strlen(LONGEST_HWMON_TYPE_STR) < sizeof(fn_type));
	strlcpy(fn_type, filename, sizeof(fn_type));
	for (size_t i = 0; fn_type[i] != '\0'; i++) {
		if (fn_type[i] >= '0' && fn_type[i] <= '9') {
			fn_type[i] = '\0';
			*number = strtoul(&filename[i], (char **)&fn_item, 10);
			if (*fn_item == '_')
				fn_item++;
			break;
		}
		if (fn_type[i] == '_') {
			fn_type[i] = '\0';
			*number = -1;
			fn_item = &filename[i + 1];
			break;
		}
	}
	if (fn_item == NULL || fn_type[0] == '\0' || (item != NULL && fn_item[0] == '\0')) {
		pr_debug3("hwmon_pmu: not a hwmon file '%s'\n", filename);
		return false;
	}
	elem = bsearch(&fn_type, hwmon_type_strs + 1, ARRAY_SIZE(hwmon_type_strs) - 1,
		       sizeof(hwmon_type_strs[0]), hwmon_strcmp);
	if (!elem) {
		pr_debug3("hwmon_pmu: not a hwmon type '%s' in file name '%s'\n",
			 fn_type, filename);

Annotation

Implementation Notes