/* * stress_mergesort() * stress mergesort */ static int stress_mergesort(const args_t *args) { uint64_t mergesort_size = DEFAULT_MERGESORT_SIZE; int32_t *data, *ptr; size_t n, i; struct sigaction old_action; int ret; if (!get_setting("mergesort-size", &mergesort_size)) { if (g_opt_flags & OPT_FLAGS_MAXIMIZE) mergesort_size = MAX_MERGESORT_SIZE; if (g_opt_flags & OPT_FLAGS_MINIMIZE) mergesort_size = MIN_MERGESORT_SIZE; } n = (size_t)mergesort_size; if ((data = calloc(n, sizeof(*data))) == NULL) { pr_fail_dbg("malloc"); return EXIT_NO_RESOURCE; } if (stress_sighandler(args->name, SIGALRM, stress_mergesort_handler, &old_action) < 0) { free(data); return EXIT_FAILURE; } ret = sigsetjmp(jmp_env, 1); if (ret) { /* * We return here if SIGALRM jmp'd back */ (void)stress_sigrestore(args->name, SIGALRM, &old_action); goto tidy; } /* This is expensive, do it once */ for (ptr = data, i = 0; i < n; i++) *ptr++ = mwc32(); do { /* Sort "random" data */ if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_1) < 0) { pr_fail("%s: mergesort of random data failed: %d (%s)\n", args->name, errno, strerror(errno)); } else { if (g_opt_flags & OPT_FLAGS_VERIFY) { for (ptr = data, i = 0; i < n - 1; i++, ptr++) { if (*ptr > *(ptr+1)) { pr_fail("%s: sort error " "detected, incorrect ordering " "found\n", args->name); break; } } } } if (!g_keep_stressing_flag) break; /* Reverse sort */ if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_2) < 0) { pr_fail("%s: reversed mergesort of random data failed: %d (%s)\n", args->name, errno, strerror(errno)); } else { if (g_opt_flags & OPT_FLAGS_VERIFY) { for (ptr = data, i = 0; i < n - 1; i++, ptr++) { if (*ptr < *(ptr+1)) { pr_fail("%s: reverse sort " "error detected, incorrect " "ordering found\n", args->name); break; } } } } if (!g_keep_stressing_flag) break; /* And re-order by random compare to remix the data */ if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_3) < 0) { pr_fail("%s: mergesort failed: %d (%s)\n", args->name, errno, strerror(errno)); } /* Reverse sort this again */ if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_2) < 0) { pr_fail("%s: reversed mergesort of random data failed: %d (%s)\n", args->name, errno, strerror(errno)); } if (g_opt_flags & OPT_FLAGS_VERIFY) { for (ptr = data, i = 0; i < n - 1; i++, ptr++) { if (*ptr < *(ptr+1)) { pr_fail("%s: reverse sort " "error detected, incorrect " "ordering found\n", args->name); break; } } } if (!g_keep_stressing_flag) break; inc_counter(args); } while (keep_stressing()); do_jmp = false; (void)stress_sigrestore(args->name, SIGALRM, &old_action); tidy: free(data); return EXIT_SUCCESS; }
/* * stress_mergesort() * stress mergesort */ int stress_mergesort( uint64_t *const counter, const uint32_t instance, const uint64_t max_ops, const char *name) { int32_t *data, *ptr; size_t n, i; struct sigaction old_action; int ret; (void)instance; if (!set_mergesort_size) { if (opt_flags & OPT_FLAGS_MAXIMIZE) opt_mergesort_size = MAX_MERGESORT_SIZE; if (opt_flags & OPT_FLAGS_MINIMIZE) opt_mergesort_size = MIN_MERGESORT_SIZE; } n = (size_t)opt_mergesort_size; if ((data = calloc(n, sizeof(int32_t))) == NULL) { pr_fail_dbg(name, "malloc"); return EXIT_FAILURE; } if (stress_sighandler(name, SIGALRM, stress_mergesort_handler, &old_action) < 0) { free(data); return EXIT_FAILURE; } ret = sigsetjmp(jmp_env, 1); if (ret) { /* * We return here if SIGALRM jmp'd back */ (void)stress_sigrestore(name, SIGALRM, &old_action); goto tidy; } /* This is expensive, do it once */ for (ptr = data, i = 0; i < n; i++) *ptr++ = mwc32(); do { /* Sort "random" data */ mergesort(data, n, sizeof(uint32_t), stress_mergesort_cmp_1); if (opt_flags & OPT_FLAGS_VERIFY) { for (ptr = data, i = 0; i < n - 1; i++, ptr++) { if (*ptr > *(ptr+1)) { pr_fail(stderr, "%s: sort error " "detected, incorrect ordering " "found\n", name); break; } } } if (!opt_do_run) break; /* Reverse sort */ mergesort(data, n, sizeof(uint32_t), stress_mergesort_cmp_2); if (opt_flags & OPT_FLAGS_VERIFY) { for (ptr = data, i = 0; i < n - 1; i++, ptr++) { if (*ptr < *(ptr+1)) { pr_fail(stderr, "%s: reverse sort " "error detected, incorrect " "ordering found\n", name); break; } } } if (!opt_do_run) break; /* And re-order by byte compare */ mergesort(data, n * 4, sizeof(uint8_t), stress_mergesort_cmp_3); /* Reverse sort this again */ mergesort(data, n, sizeof(uint32_t), stress_mergesort_cmp_2); if (opt_flags & OPT_FLAGS_VERIFY) { for (ptr = data, i = 0; i < n - 1; i++, ptr++) { if (*ptr < *(ptr+1)) { pr_fail(stderr, "%s: reverse sort " "error detected, incorrect " "ordering found\n", name); break; } } } if (!opt_do_run) break; (*counter)++; } while (opt_do_run && (!max_ops || *counter < max_ops)); do_jmp = false; (void)stress_sigrestore(name, SIGALRM, &old_action); tidy: free(data); return EXIT_SUCCESS; }