Skip to content

Commit e43956e

Browse files
kconfig: implement KCONFIG_PROBABILITY for randconfig
Currently the odds to set each symbol is (rounded): booleans: y: 50% n: 50% tristates: y: 33% m: 33% n: 33% Introduce a KCONFIG_PROBABILITY environment variable to tweak the probabilities (in percentage), as such: KCONFIG_PROBABILITY y:n split y:m:n split ----------------------------------------------------------------- [1] unset or empty 50 : 50 33 : 33 : 34 [2] N N : 100-N N/2 : N/2 : 100-N N:M N+M : 100-(N+M) N : M : 100-(N+M) N:M:L N : 100-N M : L : 100-(M+L) [1] The current behaviour is kept as default, for backward compatibility [2] The solution initially implemented by Peter for Buildroot, see: http://git.buildroot.org/buildroot/commit/?id=3435c1afb5 Signed-off-by: Peter Korsgaard <[email protected]> [[email protected]: add to Documentation/] Signed-off-by: "Yann E. MORIN" <[email protected]>
1 parent 0d8024c commit e43956e

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

Documentation/kbuild/kconfig.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,33 @@ You can set this to the integer value used to seed the RNG, if you want
9898
to somehow debug the behaviour of the kconfig parser/frontends.
9999
If not set, the current time will be used.
100100

101+
KCONFIG_PROBABILITY
102+
--------------------------------------------------
103+
This variable can be used to skew the probabilities. This variable can
104+
be unset or empty, or set to three different formats:
105+
KCONFIG_PROBABILITY y:n split y:m:n split
106+
-----------------------------------------------------------------
107+
unset or empty 50 : 50 33 : 33 : 34
108+
N N : 100-N N/2 : N/2 : 100-N
109+
[1] N:M N+M : 100-(N+M) N : M : 100-(N+M)
110+
[2] N:M:L N : 100-N M : L : 100-(M+L)
111+
112+
where N, M and L are integers (in base 10) in the range [0,100], and so
113+
that:
114+
[1] N+M is in the range [0,100]
115+
[2] M+L is in the range [0,100]
116+
117+
Examples:
118+
KCONFIG_PROBABILITY=10
119+
10% of booleans will be set to 'y', 90% to 'n'
120+
5% of tristates will be set to 'y', 5% to 'm', 90% to 'n'
121+
KCONFIG_PROBABILITY=15:25
122+
40% of booleans will be set to 'y', 60% to 'n'
123+
15% of tristates will be set to 'y', 25% to 'm', 60% to 'n'
124+
KCONFIG_PROBABILITY=10:15:15
125+
10% of booleans will be set to 'y', 90% to 'n'
126+
15% of tristates will be set to 'y', 15% to 'm', 70% to 'n'
127+
101128
______________________________________________________________________
102129
Environment variables for 'silentoldconfig'
103130

scripts/kconfig/confdata.c

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,51 @@ static void set_all_choice_values(struct symbol *csym)
11071107
void conf_set_all_new_symbols(enum conf_def_mode mode)
11081108
{
11091109
struct symbol *sym, *csym;
1110-
int i, cnt;
1110+
int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y
1111+
* pty: probability of tristate = y
1112+
* ptm: probability of tristate = m
1113+
*/
1114+
1115+
pby = 50; pty = ptm = 33; /* can't go as the default in switch-case
1116+
* below, otherwise gcc whines about
1117+
* -Wmaybe-uninitialized */
1118+
if (mode == def_random) {
1119+
int n, p[3];
1120+
char *env = getenv("KCONFIG_PROBABILITY");
1121+
n = 0;
1122+
while( env && *env ) {
1123+
char *endp;
1124+
int tmp = strtol( env, &endp, 10 );
1125+
if( tmp >= 0 && tmp <= 100 ) {
1126+
p[n++] = tmp;
1127+
} else {
1128+
errno = ERANGE;
1129+
perror( "KCONFIG_PROBABILITY" );
1130+
exit( 1 );
1131+
}
1132+
env = (*endp == ':') ? endp+1 : endp;
1133+
if( n >=3 ) {
1134+
break;
1135+
}
1136+
}
1137+
switch( n ) {
1138+
case 1:
1139+
pby = p[0]; ptm = pby/2; pty = pby-ptm;
1140+
break;
1141+
case 2:
1142+
pty = p[0]; ptm = p[1]; pby = pty + ptm;
1143+
break;
1144+
case 3:
1145+
pby = p[0]; pty = p[1]; ptm = p[2];
1146+
break;
1147+
}
1148+
1149+
if( pty+ptm > 100 ) {
1150+
errno = ERANGE;
1151+
perror( "KCONFIG_PROBABILITY" );
1152+
exit( 1 );
1153+
}
1154+
}
11111155

11121156
for_all_symbols(i, sym) {
11131157
if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
@@ -1126,8 +1170,15 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
11261170
sym->def[S_DEF_USER].tri = no;
11271171
break;
11281172
case def_random:
1129-
cnt = sym->type == S_TRISTATE ? 3 : 2;
1130-
sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
1173+
sym->def[S_DEF_USER].tri = no;
1174+
cnt = rand() % 100;
1175+
if (sym->type == S_TRISTATE) {
1176+
if (cnt < pty)
1177+
sym->def[S_DEF_USER].tri = yes;
1178+
else if (cnt < (pty+ptm))
1179+
sym->def[S_DEF_USER].tri = mod;
1180+
} else if (cnt < pby)
1181+
sym->def[S_DEF_USER].tri = yes;
11311182
break;
11321183
default:
11331184
continue;

0 commit comments

Comments
 (0)