"Fossies" - the Fresh Open Source Software Archive

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

    1 /*
    2  * Copyright (C) 2016-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_LIB_BSD)
   28 static volatile bool do_jmp = true;
   29 static sigjmp_buf jmp_env;
   30 #endif
   31 
   32 /*
   33  *  stress_set_mergesort_size()
   34  *  set mergesort size
   35  */
   36 int stress_set_mergesort_size(const char *opt)
   37 {
   38     uint64_t mergesort_size;
   39 
   40     mergesort_size = get_uint64(opt);
   41     check_range("mergesort-size", mergesort_size,
   42         MIN_MERGESORT_SIZE, MAX_MERGESORT_SIZE);
   43     return set_setting("mergesort-size", TYPE_ID_UINT64, &mergesort_size);
   44 }
   45 
   46 #if defined(HAVE_LIB_BSD)
   47 
   48 /*
   49  *  stress_mergesort_handler()
   50  *  SIGALRM generic handler
   51  */
   52 static void MLOCKED_TEXT stress_mergesort_handler(int signum)
   53 {
   54     (void)signum;
   55 
   56     if (do_jmp) {
   57         do_jmp = false;
   58         siglongjmp(jmp_env, 1);     /* Ugly, bounce back */
   59     }
   60 }
   61 
   62 /*
   63  *  stress_mergesort_cmp_1()
   64  *  mergesort comparison - sort on int32 values
   65  */
   66 static int stress_mergesort_cmp_1(const void *p1, const void *p2)
   67 {
   68     const int32_t *i1 = (const int32_t *)p1;
   69     const int32_t *i2 = (const int32_t *)p2;
   70 
   71     if (*i1 > *i2)
   72         return 1;
   73     else if (*i1 < *i2)
   74         return -1;
   75     else
   76         return 0;
   77 }
   78 
   79 /*
   80  *  stress_mergesort_cmp_2()
   81  *  mergesort comparison - reverse sort on int32 values
   82  */
   83 static int stress_mergesort_cmp_2(const void *p1, const void *p2)
   84 {
   85     return stress_mergesort_cmp_1(p2, p1);
   86 }
   87 
   88 /*
   89  *  stress_mergesort_cmp_3()
   90  *  mergesort comparison - random sort(!)
   91  */
   92 static int stress_mergesort_cmp_3(const void *p1, const void *p2)
   93 {
   94     int r = ((int)mwc8() % 3) - 1;
   95 
   96     (void)p1;
   97     (void)p2;
   98 
   99     return r;
  100 }
  101 
  102 /*
  103  *  stress_mergesort()
  104  *  stress mergesort
  105  */
  106 static int stress_mergesort(const args_t *args)
  107 {
  108     uint64_t mergesort_size = DEFAULT_MERGESORT_SIZE;
  109     int32_t *data, *ptr;
  110     size_t n, i;
  111     struct sigaction old_action;
  112     int ret;
  113 
  114     if (!get_setting("mergesort-size", &mergesort_size)) {
  115         if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
  116             mergesort_size = MAX_MERGESORT_SIZE;
  117         if (g_opt_flags & OPT_FLAGS_MINIMIZE)
  118             mergesort_size = MIN_MERGESORT_SIZE;
  119     }
  120     n = (size_t)mergesort_size;
  121 
  122     if ((data = calloc(n, sizeof(*data))) == NULL) {
  123         pr_fail_dbg("malloc");
  124         return EXIT_NO_RESOURCE;
  125     }
  126 
  127     if (stress_sighandler(args->name, SIGALRM, stress_mergesort_handler, &old_action) < 0) {
  128         free(data);
  129         return EXIT_FAILURE;
  130     }
  131 
  132     ret = sigsetjmp(jmp_env, 1);
  133     if (ret) {
  134         /*
  135          * We return here if SIGALRM jmp'd back
  136          */
  137         (void)stress_sigrestore(args->name, SIGALRM, &old_action);
  138         goto tidy;
  139     }
  140 
  141     /* This is expensive, do it once */
  142     for (ptr = data, i = 0; i < n; i++)
  143         *ptr++ = mwc32();
  144 
  145     do {
  146         /* Sort "random" data */
  147         if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_1) < 0) {
  148             pr_fail("%s: mergesort of random data failed: %d (%s)\n",
  149                 args->name, errno, strerror(errno));
  150         } else {
  151             if (g_opt_flags & OPT_FLAGS_VERIFY) {
  152                 for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
  153                     if (*ptr > *(ptr+1)) {
  154                         pr_fail("%s: sort error "
  155                             "detected, incorrect ordering "
  156                             "found\n", args->name);
  157                         break;
  158                     }
  159                 }
  160             }
  161         }
  162         if (!g_keep_stressing_flag)
  163             break;
  164 
  165         /* Reverse sort */
  166         if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_2) < 0) {
  167             pr_fail("%s: reversed mergesort of random data failed: %d (%s)\n",
  168                                 args->name, errno, strerror(errno));
  169         } else {
  170             if (g_opt_flags & OPT_FLAGS_VERIFY) {
  171                 for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
  172                     if (*ptr < *(ptr+1)) {
  173                         pr_fail("%s: reverse sort "
  174                             "error detected, incorrect "
  175                             "ordering found\n", args->name);
  176                         break;
  177                     }
  178                 }
  179             }
  180         }
  181         if (!g_keep_stressing_flag)
  182             break;
  183         /* And re-order by random compare to remix the data */
  184         if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_3) < 0) {
  185             pr_fail("%s: mergesort failed: %d (%s)\n",
  186                 args->name, errno, strerror(errno));
  187         }
  188 
  189         /* Reverse sort this again */
  190         if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_2) < 0) {
  191             pr_fail("%s: reversed mergesort of random data failed: %d (%s)\n",
  192                 args->name, errno, strerror(errno));
  193         }
  194         if (g_opt_flags & OPT_FLAGS_VERIFY) {
  195             for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
  196                 if (*ptr < *(ptr+1)) {
  197                     pr_fail("%s: reverse sort "
  198                         "error detected, incorrect "
  199                         "ordering found\n", args->name);
  200                     break;
  201                 }
  202             }
  203         }
  204         if (!g_keep_stressing_flag)
  205             break;
  206 
  207         inc_counter(args);
  208     } while (keep_stressing());
  209 
  210     do_jmp = false;
  211     (void)stress_sigrestore(args->name, SIGALRM, &old_action);
  212 tidy:
  213     free(data);
  214 
  215     return EXIT_SUCCESS;
  216 }
  217 
  218 stressor_info_t stress_mergesort_info = {
  219     .stressor = stress_mergesort,
  220     .class = CLASS_CPU_CACHE | CLASS_CPU | CLASS_MEMORY
  221 };
  222 #else
  223 stressor_info_t stress_mergesort_info = {
  224     .stressor = stress_not_implemented,
  225     .class = CLASS_CPU_CACHE | CLASS_CPU | CLASS_MEMORY
  226 };
  227 #endif