"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/core-mwc.c" (15 Mar 2019, 4293 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 "core-mwc.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.54_vs_0.09.55.

    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 static mwc_t __mwc = {
   28     MWC_SEED_W,
   29     MWC_SEED_Z
   30 };
   31 
   32 static uint8_t mwc_n1, mwc_n8, mwc_n16;
   33 
   34 static inline void mwc_flush(void)
   35 {
   36     mwc_n1 = 0;
   37     mwc_n8 = 0;
   38     mwc_n16 = 0;
   39 }
   40 
   41 #if defined(HAVE_SYS_AUXV_H) && \
   42     defined(HAVE_GETAUXVAL) && \
   43     defined(AT_RANDOM)
   44 
   45 #define VAL(ptr, n) (((uint64_t)(*(ptr + n))) << (n << 3))
   46 
   47 /*
   48  *  aux_random_seed()
   49  *  get a fixed random value via getauxval
   50  */
   51 static uint64_t aux_random_seed(void)
   52 {
   53     uint8_t *ptr;
   54     uint64_t val;
   55 
   56     ptr = (uint8_t *)getauxval(AT_RANDOM);
   57     if (!ptr)
   58         return 0ULL;
   59 
   60     val = VAL(ptr, 0) | VAL(ptr, 1) | VAL(ptr, 2) | VAL(ptr, 3) |
   61           VAL(ptr, 4) | VAL(ptr, 5) | VAL(ptr, 6) | VAL(ptr, 7);
   62 
   63     return val;
   64 }
   65 #else
   66 static uint64_t aux_random_seed(void)
   67 {
   68     return 0ULL;
   69 }
   70 #endif
   71 
   72 /*
   73  *  mwc_reseed()
   74  *  dirty mwc reseed, this is expensive as it
   75  *  pulls in various system values for the seeding
   76  */
   77 void mwc_reseed(void)
   78 {
   79     if (g_opt_flags & OPT_FLAGS_NO_RAND_SEED) {
   80         __mwc.w = MWC_SEED_W;
   81         __mwc.z = MWC_SEED_Z;
   82     } else {
   83         struct timeval tv;
   84         struct rusage r;
   85         double m1, m5, m15;
   86         int i, n;
   87         uint64_t aux_rnd = aux_random_seed();
   88         const ptrdiff_t p1 = (ptrdiff_t)&__mwc.z;
   89         const ptrdiff_t p2 = (ptrdiff_t)&tv;
   90 
   91         __mwc.z = aux_rnd >> 32;
   92         __mwc.w = aux_rnd & 0xffffffff;
   93         if (gettimeofday(&tv, NULL) == 0)
   94             __mwc.z ^= (uint64_t)tv.tv_sec ^ (uint64_t)tv.tv_usec;
   95         __mwc.z += ~(p1 - p2);
   96         __mwc.w += (uint64_t)getpid() ^ (uint64_t)getppid()<<12;
   97         if (stress_get_load_avg(&m1, &m5, &m15) == 0) {
   98             __mwc.z += (128 * (m1 + m15));
   99             __mwc.w += (256 * (m5));
  100         }
  101         if (getrusage(RUSAGE_SELF, &r) == 0) {
  102             __mwc.z += r.ru_utime.tv_usec;
  103             __mwc.w += r.ru_utime.tv_sec;
  104         }
  105         __mwc.z ^= stress_get_cpu();
  106         __mwc.w ^= stress_get_phys_mem_size();
  107 
  108         n = (int)__mwc.z % 1733;
  109         for (i = 0; i < n; i++) {
  110             (void)mwc32();
  111         }
  112     }
  113     mwc_flush();
  114 }
  115 
  116 /*
  117  *  mwc_seed()
  118  *      set mwc seeds
  119  */
  120 void mwc_seed(const uint32_t w, const uint32_t z)
  121 {
  122     __mwc.w = w;
  123     __mwc.z = z;
  124 
  125     mwc_flush();
  126 }
  127 
  128 /*
  129  *  mwc32()
  130  *      Multiply-with-carry random numbers
  131  *      fast pseudo random number generator, see
  132  *      http://www.cse.yorku.ca/~oz/marsaglia-rng.html
  133  */
  134 HOT OPTIMIZE3 uint32_t mwc32(void)
  135 {
  136     __mwc.z = 36969 * (__mwc.z & 65535) + (__mwc.z >> 16);
  137     __mwc.w = 18000 * (__mwc.w & 65535) + (__mwc.w >> 16);
  138     return (__mwc.z << 16) + __mwc.w;
  139 }
  140 
  141 /*
  142  *  mwc64()
  143  *  get a 64 bit pseudo random number
  144  */
  145 HOT OPTIMIZE3 uint64_t mwc64(void)
  146 {
  147     return (((uint64_t)mwc32()) << 32) | mwc32();
  148 }
  149 
  150 /*
  151  *  mwc16()
  152  *  get a 16 bit pseudo random number
  153  */
  154 HOT OPTIMIZE3 uint16_t mwc16(void)
  155 {
  156     static uint32_t mwc_saved;
  157 
  158     if (mwc_n16) {
  159         mwc_n16--;
  160         mwc_saved >>= 16;
  161     } else {
  162         mwc_n16 = 1;
  163         mwc_saved = mwc32();
  164     }
  165     return mwc_saved & 0xffff;
  166 }
  167 
  168 /*
  169  *  mwc8()
  170  *  get an 8 bit pseudo random number
  171  */
  172 HOT OPTIMIZE3 uint8_t mwc8(void)
  173 {
  174     static uint32_t mwc_saved;
  175 
  176     if (LIKELY(mwc_n8)) {
  177         mwc_n8--;
  178         mwc_saved >>= 8;
  179     } else {
  180         mwc_n8 = 3;
  181         mwc_saved = mwc32();
  182     }
  183     return mwc_saved & 0xff;
  184 }
  185 
  186 /*
  187  *  mwc1()
  188  *  get an 1 bit pseudo random number
  189  */
  190 HOT OPTIMIZE3 uint8_t mwc1(void)
  191 {
  192     static uint32_t mwc_saved;
  193 
  194     if (LIKELY(mwc_n1)) {
  195         mwc_n1--;
  196         mwc_saved >>= 1;
  197     } else {
  198         mwc_n8 = 31;
  199         mwc_saved = mwc32();
  200     }
  201     return mwc_saved & 0x1;
  202 }