"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-rdrand.c" (15 Mar 2019, 5089 Bytes) of package /linux/privat/stress-ng-0.09.56.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "stress-rdrand.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.50_vs_0.09.51.

    1 /*
    2  * Copyright (C) 2013-2019 Canonical, Ltd.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License
    6  * as published by the Free Software Foundation; either version 2
    7  * of the License, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   17  *
   18  * This code is a complete clean re-write of the stress tool by
   19  * Colin Ian King <colin.king@canonical.com> and attempts to be
   20  * backwardly compatible with the stress tool by Amos Waterland
   21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
   22  * functionality.
   23  *
   24  */
   25 #include "stress-ng.h"
   26 
   27 #if defined(HAVE_CPUID_H) &&    \
   28     defined(STRESS_X86) &&  \
   29     defined(HAVE_CPUID) &&  \
   30     NEED_GNUC(4,6,0)
   31 
   32 static bool rdrand_supported = false;
   33 
   34 /*
   35  *  stress_rdrand_supported()
   36  *  check if rdrand is supported
   37  */
   38 static int stress_rdrand_supported(void)
   39 {
   40     uint32_t eax, ebx, ecx, edx;
   41 
   42     /* Intel CPU? */
   43     if (!cpu_is_x86()) {
   44         pr_inf("rdrand stressor will be skipped, "
   45             "not a recognised Intel CPU\n");
   46         return -1;
   47     }
   48     /* ..and supports rdrand? */
   49     __cpuid(1, eax, ebx, ecx, edx);
   50     if (!(ecx & 0x40000000)) {
   51         pr_inf("rdrand stressor will be skipped, CPU "
   52             "does not support the rdrand instruction\n");
   53         return -1;
   54     }
   55     rdrand_supported = true;
   56     return 0;
   57 }
   58 
   59 #if defined(__x86_64__) || defined(__x86_64)
   60 
   61 /*
   62  *  rdrand64()
   63  *  read 64 bit random value
   64  */
   65 static inline uint64_t rdrand64(void)
   66 {
   67     uint64_t        ret;
   68 
   69     asm volatile("1:;\n\
   70     rdrand %0;\n\
   71     jnc 1b;\n":"=r"(ret));
   72 
   73     return ret;
   74 }
   75 
   76 /*
   77  *  Unrolled 32 times
   78  */
   79 #define RDRAND64x32()   \
   80 {           \
   81     rdrand64(); \
   82     rdrand64(); \
   83     rdrand64(); \
   84     rdrand64(); \
   85     rdrand64(); \
   86     rdrand64(); \
   87     rdrand64(); \
   88     rdrand64(); \
   89     rdrand64(); \
   90     rdrand64(); \
   91     rdrand64(); \
   92     rdrand64(); \
   93     rdrand64(); \
   94     rdrand64(); \
   95     rdrand64(); \
   96     rdrand64(); \
   97     rdrand64(); \
   98     rdrand64(); \
   99     rdrand64(); \
  100     rdrand64(); \
  101     rdrand64(); \
  102     rdrand64(); \
  103     rdrand64(); \
  104     rdrand64(); \
  105     rdrand64(); \
  106     rdrand64(); \
  107     rdrand64(); \
  108     rdrand64(); \
  109     rdrand64(); \
  110     rdrand64(); \
  111     rdrand64(); \
  112     rdrand64(); \
  113 }
  114 #else
  115 /*
  116  *  rdrand32()
  117  *  read 32 bit random value
  118  */
  119 static inline uint32_t rdrand32(void)
  120 {
  121     uint32_t        ret;
  122 
  123     asm volatile("1:;\n\
  124     rdrand %0;\n\
  125     jnc 1b;\n":"=r"(ret));
  126 
  127     return ret;
  128 }
  129 
  130 /*
  131  *  Unrolled 64 times
  132  */
  133 #define RDRAND32x64()   \
  134 {           \
  135     rdrand32(); \
  136     rdrand32(); \
  137     rdrand32(); \
  138     rdrand32(); \
  139     rdrand32(); \
  140     rdrand32(); \
  141     rdrand32(); \
  142     rdrand32(); \
  143     rdrand32(); \
  144     rdrand32(); \
  145     rdrand32(); \
  146     rdrand32(); \
  147     rdrand32(); \
  148     rdrand32(); \
  149     rdrand32(); \
  150     rdrand32(); \
  151     rdrand32(); \
  152     rdrand32(); \
  153     rdrand32(); \
  154     rdrand32(); \
  155     rdrand32(); \
  156     rdrand32(); \
  157     rdrand32(); \
  158     rdrand32(); \
  159     rdrand32(); \
  160     rdrand32(); \
  161     rdrand32(); \
  162     rdrand32(); \
  163     rdrand32(); \
  164     rdrand32(); \
  165     rdrand32(); \
  166     rdrand32(); \
  167     rdrand32(); \
  168     rdrand32(); \
  169     rdrand32(); \
  170     rdrand32(); \
  171     rdrand32(); \
  172     rdrand32(); \
  173     rdrand32(); \
  174     rdrand32(); \
  175     rdrand32(); \
  176     rdrand32(); \
  177     rdrand32(); \
  178     rdrand32(); \
  179     rdrand32(); \
  180     rdrand32(); \
  181     rdrand32(); \
  182     rdrand32(); \
  183     rdrand32(); \
  184     rdrand32(); \
  185     rdrand32(); \
  186     rdrand32(); \
  187     rdrand32(); \
  188     rdrand32(); \
  189     rdrand32(); \
  190     rdrand32(); \
  191     rdrand32(); \
  192     rdrand32(); \
  193     rdrand32(); \
  194     rdrand32(); \
  195     rdrand32(); \
  196     rdrand32(); \
  197     rdrand32(); \
  198     rdrand32(); \
  199 }
  200 #endif
  201 
  202 /*
  203  *  stress_rdrand()
  204  *      stress Intel rdrand instruction
  205  */
  206 static int stress_rdrand(const args_t *args)
  207 {
  208     if (rdrand_supported) {
  209         double time_start, duration, billion_bits;
  210         bool lock = false;
  211 
  212         time_start = time_now();
  213         do {
  214 #if defined(__x86_64__) || defined(__x86_64)
  215             RDRAND64x32();
  216 #else
  217             RDRAND32x64();
  218 #endif
  219             inc_counter(args);
  220         } while (keep_stressing());
  221 
  222         duration = time_now() - time_start;
  223         billion_bits = ((double)get_counter(args) * 64.0 * 32.0) / 1000000000.0;
  224 
  225         pr_lock(&lock);
  226         pr_dbg_lock(&lock, "%s: %.3f billion random bits read "
  227             "(instance %" PRIu32")\n",
  228             args->name, billion_bits, args->instance);
  229         if (duration > 0.0) {
  230             pr_dbg_lock(&lock, "%s: %.3f billion random bits per "
  231                 "second (instance %" PRIu32")\n",
  232                 args->name,
  233                 (double)billion_bits / duration,
  234                 args->instance);
  235         }
  236         pr_unlock(&lock);
  237     }
  238     return EXIT_SUCCESS;
  239 }
  240 
  241 stressor_info_t stress_rdrand_info = {
  242     .stressor = stress_rdrand,
  243     .supported = stress_rdrand_supported,
  244     .class = CLASS_CPU
  245 };
  246 #else
  247 
  248 static int stress_rdrand_supported(void)
  249 {   
  250     pr_inf("rdrand stressor will be skipped, CPU "
  251         "does not support the rdrand instruction.\n");
  252     return -1;
  253 }
  254 
  255 stressor_info_t stress_rdrand_info = {
  256     .stressor = stress_not_implemented,
  257     .supported = stress_rdrand_supported,
  258     .class = CLASS_CPU
  259 };
  260 #endif