"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-heapsort.c" (15 Mar 2019, 5742 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-heapsort.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_heapsort_size()
   34  *  set heapsort size
   35  */
   36 int stress_set_heapsort_size(const char *opt)
   37 {
   38     uint64_t heapsort_size;
   39 
   40     heapsort_size = get_uint64(opt);
   41     check_range("heapsort-size", heapsort_size,
   42         MIN_HEAPSORT_SIZE, MAX_HEAPSORT_SIZE);
   43     return set_setting("heapsort-size", TYPE_ID_UINT64, &heapsort_size);
   44 }
   45 
   46 #if defined(HAVE_LIB_BSD)
   47 
   48 /*
   49  *  stress_heapsort_handler()
   50  *  SIGALRM generic handler
   51  */
   52 static void MLOCKED_TEXT stress_heapsort_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_heapsort_cmp_1()
   64  *  heapsort comparison - sort on int32 values
   65  */
   66 static int stress_heapsort_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_heapsort_cmp_1()
   81  *  heapsort comparison - reverse sort on int32 values
   82  */
   83 static int stress_heapsort_cmp_2(const void *p1, const void *p2)
   84 {
   85     return stress_heapsort_cmp_1(p2, p1);
   86 }
   87 
   88 /*
   89  *  stress_heapsort_cmp_1()
   90  *  heapsort comparison - sort on int8 values
   91  */
   92 static int stress_heapsort_cmp_3(const void *p1, const void *p2)
   93 {
   94     const int8_t *i1 = (const int8_t *)p1;
   95     const int8_t *i2 = (const int8_t *)p2;
   96 
   97     /* Force re-ordering on 8 bit value */
   98     return *i1 - *i2;
   99 }
  100 
  101 /*
  102  *  stress_heapsort()
  103  *  stress heapsort
  104  */
  105 static int stress_heapsort(const args_t *args)
  106 {
  107     uint64_t heapsort_size = DEFAULT_HEAPSORT_SIZE;
  108     int32_t *data, *ptr;
  109     size_t n, i;
  110     struct sigaction old_action;
  111     int ret;
  112 
  113     if (!get_setting("heapsort-size", &heapsort_size)) {
  114         if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
  115             heapsort_size = MAX_HEAPSORT_SIZE;
  116         if (g_opt_flags & OPT_FLAGS_MINIMIZE)
  117             heapsort_size = MIN_HEAPSORT_SIZE;
  118     }
  119     n = (size_t)heapsort_size;
  120 
  121     if ((data = calloc(n, sizeof(*data))) == NULL) {
  122         pr_fail_dbg("malloc");
  123         return EXIT_NO_RESOURCE;
  124     }
  125 
  126     if (stress_sighandler(args->name, SIGALRM, stress_heapsort_handler, &old_action) < 0) {
  127         free(data);
  128         return EXIT_FAILURE;
  129     }
  130 
  131     ret = sigsetjmp(jmp_env, 1);
  132     if (ret) {
  133         /*
  134          * We return here if SIGALRM jmp'd back
  135          */
  136         (void)stress_sigrestore(args->name, SIGALRM, &old_action);
  137         goto tidy;
  138     }
  139 
  140     /* This is expensive, do it once */
  141     for (ptr = data, i = 0; i < n; i++)
  142         *ptr++ = mwc32();
  143 
  144     do {
  145         /* Sort "random" data */
  146         if (heapsort(data, n, sizeof(*data), stress_heapsort_cmp_1) < 0) {
  147             pr_fail("%s: heapsort of random data failed: %d (%s)\n",
  148                 args->name, errno, strerror(errno));
  149         } else {
  150             if (g_opt_flags & OPT_FLAGS_VERIFY) {
  151                 for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
  152                     if (*ptr > *(ptr+1)) {
  153                         pr_fail("%s: sort error "
  154                             "detected, incorrect ordering "
  155                             "found\n", args->name);
  156                         break;
  157                     }
  158                 }
  159             }
  160         }
  161         if (!g_keep_stressing_flag)
  162             break;
  163 
  164         /* Reverse sort */
  165         if (heapsort(data, n, sizeof(*data), stress_heapsort_cmp_2) < 0) {
  166             pr_fail("%s: reversed heapsort of random data failed: %d (%s)\n",
  167                 args->name, errno, strerror(errno));
  168         } else {
  169             if (g_opt_flags & OPT_FLAGS_VERIFY) {
  170                 for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
  171                     if (*ptr < *(ptr+1)) {
  172                         pr_fail("%s: reverse sort "
  173                             "error detected, incorrect "
  174                             "ordering found\n", args->name);
  175                         break;
  176                     }
  177                 }
  178             }
  179         }
  180         if (!g_keep_stressing_flag)
  181             break;
  182         /* And re-order by byte compare */
  183         if (heapsort(data, n * 4, sizeof(uint8_t), stress_heapsort_cmp_3) < 0) {
  184             pr_fail("%s: heapsort failed: %d (%s)\n",
  185                 args->name, errno, strerror(errno));
  186         }
  187 
  188         /* Reverse sort this again */
  189         if (heapsort(data, n, sizeof(*data), stress_heapsort_cmp_2) < 0) {
  190             pr_fail("%s: reversed heapsort of random data failed: %d (%s)\n",
  191                 args->name, errno, strerror(errno));
  192         } else {
  193             if (g_opt_flags & OPT_FLAGS_VERIFY) {
  194                 for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
  195                     if (*ptr < *(ptr+1)) {
  196                         pr_fail("%s: reverse sort "
  197                             "error detected, incorrect "
  198                             "ordering found\n", args->name);
  199                         break;
  200                     }
  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_heapsort_info = {
  219     .stressor = stress_heapsort,
  220     .class = CLASS_CPU_CACHE | CLASS_CPU | CLASS_MEMORY
  221 };
  222 #else
  223 stressor_info_t stress_heapsort_info = {
  224     .stressor = stress_not_implemented,
  225     .class = CLASS_CPU_CACHE | CLASS_CPU | CLASS_MEMORY
  226 };
  227 #endif