Skip to content

Commit 20105ca

Browse files
Taeungacmel
authored andcommitted
perf config: Introduce perf_config_set class
This infrastructure code was designed for upcoming features of 'perf config'. That collect config key-value pairs from user and system config files (i.e. user wide ~/.perfconfig and system wide $(sysconfdir)/perfconfig) to manage perf's configs. Reviewed-by: Masami Hiramatsu <[email protected]> Signed-off-by: Taeung Song <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent ecfd7a9 commit 20105ca

File tree

2 files changed

+199
-0
lines changed

2 files changed

+199
-0
lines changed

tools/perf/util/config.c

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <subcmd/exec-cmd.h>
1414
#include "util/hist.h" /* perf_hist_config */
1515
#include "util/llvm-utils.h" /* perf_llvm_config */
16+
#include "config.h"
1617

1718
#define MAXNAME (256)
1819

@@ -524,6 +525,178 @@ int perf_config(config_fn_t fn, void *data)
524525
return ret;
525526
}
526527

528+
static struct perf_config_section *find_section(struct list_head *sections,
529+
const char *section_name)
530+
{
531+
struct perf_config_section *section;
532+
533+
list_for_each_entry(section, sections, node)
534+
if (!strcmp(section->name, section_name))
535+
return section;
536+
537+
return NULL;
538+
}
539+
540+
static struct perf_config_item *find_config_item(const char *name,
541+
struct perf_config_section *section)
542+
{
543+
struct perf_config_item *item;
544+
545+
list_for_each_entry(item, &section->items, node)
546+
if (!strcmp(item->name, name))
547+
return item;
548+
549+
return NULL;
550+
}
551+
552+
static struct perf_config_section *add_section(struct list_head *sections,
553+
const char *section_name)
554+
{
555+
struct perf_config_section *section = zalloc(sizeof(*section));
556+
557+
if (!section)
558+
return NULL;
559+
560+
INIT_LIST_HEAD(&section->items);
561+
section->name = strdup(section_name);
562+
if (!section->name) {
563+
pr_debug("%s: strdup failed\n", __func__);
564+
free(section);
565+
return NULL;
566+
}
567+
568+
list_add_tail(&section->node, sections);
569+
return section;
570+
}
571+
572+
static struct perf_config_item *add_config_item(struct perf_config_section *section,
573+
const char *name)
574+
{
575+
struct perf_config_item *item = zalloc(sizeof(*item));
576+
577+
if (!item)
578+
return NULL;
579+
580+
item->name = strdup(name);
581+
if (!item->name) {
582+
pr_debug("%s: strdup failed\n", __func__);
583+
free(item);
584+
return NULL;
585+
}
586+
587+
list_add_tail(&item->node, &section->items);
588+
return item;
589+
}
590+
591+
static int set_value(struct perf_config_item *item, const char *value)
592+
{
593+
char *val = strdup(value);
594+
595+
if (!val)
596+
return -1;
597+
598+
zfree(&item->value);
599+
item->value = val;
600+
return 0;
601+
}
602+
603+
static int collect_config(const char *var, const char *value,
604+
void *perf_config_set)
605+
{
606+
int ret = -1;
607+
char *ptr, *key;
608+
char *section_name, *name;
609+
struct perf_config_section *section = NULL;
610+
struct perf_config_item *item = NULL;
611+
struct perf_config_set *set = perf_config_set;
612+
struct list_head *sections = &set->sections;
613+
614+
key = ptr = strdup(var);
615+
if (!key) {
616+
pr_debug("%s: strdup failed\n", __func__);
617+
return -1;
618+
}
619+
620+
section_name = strsep(&ptr, ".");
621+
name = ptr;
622+
if (name == NULL || value == NULL)
623+
goto out_free;
624+
625+
section = find_section(sections, section_name);
626+
if (!section) {
627+
section = add_section(sections, section_name);
628+
if (!section)
629+
goto out_free;
630+
}
631+
632+
item = find_config_item(name, section);
633+
if (!item) {
634+
item = add_config_item(section, name);
635+
if (!item)
636+
goto out_free;
637+
}
638+
639+
ret = set_value(item, value);
640+
return ret;
641+
642+
out_free:
643+
free(key);
644+
perf_config_set__delete(set);
645+
return -1;
646+
}
647+
648+
struct perf_config_set *perf_config_set__new(void)
649+
{
650+
struct perf_config_set *set = zalloc(sizeof(*set));
651+
652+
if (set) {
653+
INIT_LIST_HEAD(&set->sections);
654+
perf_config(collect_config, set);
655+
}
656+
657+
return set;
658+
}
659+
660+
static void perf_config_item__delete(struct perf_config_item *item)
661+
{
662+
zfree(&item->name);
663+
zfree(&item->value);
664+
free(item);
665+
}
666+
667+
static void perf_config_section__purge(struct perf_config_section *section)
668+
{
669+
struct perf_config_item *item, *tmp;
670+
671+
list_for_each_entry_safe(item, tmp, &section->items, node) {
672+
list_del_init(&item->node);
673+
perf_config_item__delete(item);
674+
}
675+
}
676+
677+
static void perf_config_section__delete(struct perf_config_section *section)
678+
{
679+
perf_config_section__purge(section);
680+
zfree(&section->name);
681+
free(section);
682+
}
683+
684+
static void perf_config_set__purge(struct perf_config_set *set)
685+
{
686+
struct perf_config_section *section, *tmp;
687+
688+
list_for_each_entry_safe(section, tmp, &set->sections, node) {
689+
list_del_init(&section->node);
690+
perf_config_section__delete(section);
691+
}
692+
}
693+
694+
void perf_config_set__delete(struct perf_config_set *set)
695+
{
696+
perf_config_set__purge(set);
697+
free(set);
698+
}
699+
527700
/*
528701
* Call this to report error for your variable that should not
529702
* get a boolean value (i.e. "[my] var" means "true").

tools/perf/util/config.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef __PERF_CONFIG_H
2+
#define __PERF_CONFIG_H
3+
4+
#include <stdbool.h>
5+
#include <linux/list.h>
6+
7+
struct perf_config_item {
8+
char *name;
9+
char *value;
10+
struct list_head node;
11+
};
12+
13+
struct perf_config_section {
14+
char *name;
15+
struct list_head items;
16+
struct list_head node;
17+
};
18+
19+
struct perf_config_set {
20+
struct list_head sections;
21+
};
22+
23+
struct perf_config_set *perf_config_set__new(void);
24+
void perf_config_set__delete(struct perf_config_set *set);
25+
26+
#endif /* __PERF_CONFIG_H */

0 commit comments

Comments
 (0)