fio: support suffixes in expression parser
authorStephen M. Cameron <stephenmcameron@gmail.com>
Mon, 29 Sep 2014 18:15:35 +0000 (12:15 -0600)
committerJens Axboe <axboe@fb.com>
Mon, 29 Sep 2014 18:18:35 +0000 (12:18 -0600)
Note that time values in expressions by default have units of microseconds

Signed-off-by: Stephen M. Cameron <stephenmcameron@gmail.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
exp/expression-parser.l
exp/expression-parser.y
exp/test-expression-parser.c
fio.1
parse.c

index 388515e2c4722bea9c83de692479dd436fe15074..f688da11684e16b68b88df9a1837c894e8b484b3 100644 (file)
@@ -36,12 +36,78 @@ extern int yyerror(long long *result, double *dresult,
 static void __attribute__((unused)) yyunput(int c,char *buf_ptr);
 static int __attribute__((unused)) input(void);
 
+#define set_suffix_value(yylval, i_val, d_val, has_d_val) \
+       (yylval).v.dval = (d_val); \
+       (yylval).v.ival = (i_val); \
+       (yylval).v.has_dval = (has_d_val); \
+       (yylval).v.has_error = 0;
+
 %}
 
 %%
 
 
-bye    return BYE;
+bye            return BYE;
+[kK]|[kK][bB]  {
+                       set_suffix_value(yylval, 1024, 1024.0, 0);
+                       return SUFFIX;
+               }
+[Mm]|[Mm][bB]  {
+                       set_suffix_value(yylval, 1024 * 1024, 1024.0 * 1024.0, 0);
+                       return SUFFIX;
+               }
+[mM][sS]       {
+                       set_suffix_value(yylval, 1000, 1000.0, 1);
+                       return SUFFIX;
+               }
+[uU][sS]       {
+                       set_suffix_value(yylval, 1, 1.0, 1);
+                       return SUFFIX;
+               }
+[gG]|[Gg][Bb]  {
+                       set_suffix_value(yylval, 1024LL * 1024 * 1024, 1024.0 * 1024.0 * 1024, 0);
+                       return SUFFIX;
+               }
+[tT]|[tT][bB]  {       
+                       set_suffix_value(yylval, 1024LL * 1024 * 1024 * 1024,
+                                               1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024, 0);
+                       return SUFFIX;
+               }
+[pP]|[pP][bB]  {       
+                       set_suffix_value(yylval, 1024LL * 1024 * 1024 * 1024 * 1024,
+                                       1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0, 0);
+                       return SUFFIX;
+               }
+[kK][iI][Bb]   {
+                       set_suffix_value(yylval, 1000LL, 1000.0, 0);
+                       return SUFFIX;
+               }
+[mM][Ii][bB]   {
+                       set_suffix_value(yylval, 1000000LL, 1000000.0 , 0);
+                       return SUFFIX;
+               }
+[gG][iI][Bb]   {
+                       set_suffix_value(yylval, 1000000000LL, 1000000000.0 , 0);
+                       return SUFFIX;
+               }
+[pP][iI][Bb]   {       
+                       set_suffix_value(yylval, 1000000000000LL, 1000000000000.0 , 0);
+                       return SUFFIX;
+               }
+[sS]           {
+                       set_suffix_value(yylval, 1000000LL, 1000000.0 , 0);
+                       return SUFFIX;
+               }
+[dD]           {
+                       set_suffix_value(yylval, 60LL * 60LL * 24LL * 1000000LL,
+                                               60.0 * 60.0 * 24.0 * 1000000.0, 0);
+                       return SUFFIX;
+               }
+[hH]           {       
+                       set_suffix_value(yylval, 60LL * 60LL * 1000000LL,
+                                       60.0 * 60.0 * 1000000.0, 0);
+                       return SUFFIX;
+               }
 [ \t] ; /* ignore whitespace */
 #.+ ; /* ignore comments */
 [0-9]*[.][0-9]+ {
index dbd8b6c27c40bf58c598564a8ca2d9283edde74e..1c1ebf88492028c25a91ab935b08c486a916b5ff 100644 (file)
@@ -55,6 +55,7 @@ extern void yyrestart(FILE *file);
 
 %token <v> NUMBER
 %token <v> BYE
+%token <v> SUFFIX 
 %left '-' '+'
 %left '*' '/'
 %nonassoc UMINUS
@@ -119,6 +120,17 @@ expression:        expression '+' expression {
                        $$.has_error = $2.has_error;
                }
        |       '(' expression ')' { $$ = $2; }
+       |       expression SUFFIX {
+                       if (!$1.has_dval && !$2.has_dval)
+                               $$.ival = $1.ival * $2.ival;
+                       else
+                               $$.ival = (long long) $1.dval * $2.dval;
+                       if ($1.has_dval || $2.has_dval)
+                               $$.dval = $1.dval * $2.dval;
+                       else
+                               $$.dval = $1.ival * $2.ival;
+                       $$.has_error = $1.has_error || $2.has_error;
+               }
        |       NUMBER { $$ = $1; }
        |       BYE { $$ = $1; *bye = 1; };
 %%
index 6b4ab5dd9988fd4c33335e48e129f042cf9b6737..a9794dcb50f759948bd44bee2f5c70b898f30ab1 100644 (file)
@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
                        buffer[rc - 1] = '\0';
                rc = evaluate_arithmetic_expression(buffer, &result, &dresult);
                if (!rc) {
-                       printf("%lld (%lf)\n", result, dresult);
+                       printf("%lld (%20.20lf)\n", result, dresult);
                } else {
                        result = 0;
                        dresult = 0;
diff --git a/fio.1 b/fio.1
index 2fbdb00d2f9f1b41ac15c6a3f2d9471d35cae3b6..fb5ca46d0f6d7ff0838499e62fc1e34e771b23e6 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -117,9 +117,12 @@ may override any parameter set in global sections.
 .SS Types
 Some parameters may take arguments of a specific type.
 Anywhere a numeric value is required, an arithmetic expression may be used,
-provided it is surrounded by parentheses.  Suffixes currently do not
-work with arithmetic expressions.  Supported operators are
+provided it is surrounded by parentheses.
+Supported operators are
 addition, subtraction, multiplication and division.
+For time values in expressions
+units are microseconds by default.  This is different than for time
+values not in expressions (not enclosed in parentheses).
 The types used are:
 .TP
 .I str
diff --git a/parse.c b/parse.c
index c2d1cc811f6740a58bf0692a5c9f740e1d085aae..b632bf1adc10dfbeb580c17776a15095400fc90a 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -312,8 +312,12 @@ int str_to_decimal(const char *str, long long *val, int kilo, void *data,
 #ifdef CONFIG_ARITHMETIC
        if (str[0] == '(')
                rc = evaluate_arithmetic_expression(str, &ival, &dval);
-       if (str[0] == '(' && !rc)
-               *val = ival;
+       if (str[0] == '(' && !rc) {
+               if (!kilo && is_seconds)
+                       *val = ival / 1000000LL;
+               else
+                       *val = ival;
+       }
 #endif
 
        if (rc == 1) {