"Fossies" - the Fresh Open Source Software Archive

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

    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 /*
   28  *  stress_set_fork_max()
   29  *  set maximum number of forks allowed
   30  */
   31 int stress_set_fork_max(const char *opt)
   32 {
   33     uint64_t fork_max;
   34 
   35     fork_max = get_uint64(opt);
   36     check_range("fork-max", fork_max,
   37         MIN_FORKS, MAX_FORKS);
   38     return set_setting("fork-max", TYPE_ID_UINT64, &fork_max);
   39 }
   40 
   41 /*
   42  *  stress_set_vfork_max()
   43  *  set maximum number of vforks allowed
   44  */
   45 int stress_set_vfork_max(const char *opt)
   46 {
   47     uint64_t vfork_max;
   48 
   49     vfork_max = get_uint64(opt);
   50     check_range("vfork-max", vfork_max,
   51         MIN_VFORKS, MAX_VFORKS);
   52     return set_setting("vfork-max", TYPE_ID_UINT64, &vfork_max);
   53 }
   54 
   55 /*
   56  *  stress_fork_fn()
   57  *  stress by forking and exiting using
   58  *  fork function fork_fn (fork or vfork)
   59  */
   60 static int stress_fork_fn(
   61     const args_t *args,
   62     pid_t (*fork_fn)(void),
   63     const char *fork_fn_name,
   64     const uint64_t fork_max)
   65 {
   66     pid_t pids[MAX_FORKS];
   67     int errnos[MAX_FORKS];
   68     int ret;
   69 
   70     set_oom_adjustment(args->name, true);
   71 
   72     /* Explicitly drop capabilites, makes it more OOM-able */
   73     ret = stress_drop_capabilities(args->name);
   74     (void)ret;
   75 
   76     do {
   77         unsigned int i;
   78 
   79         (void)memset(pids, 0, sizeof(pids));
   80         (void)memset(errnos, 0, sizeof(errnos));
   81 
   82         for (i = 0; i < fork_max; i++) {
   83             pid_t pid = fork_fn();
   84 
   85             if (pid == 0) {
   86                 /* Child, immediately exit */
   87                 _exit(0);
   88             } else if (pid < 0) {
   89                 errnos[i] = errno;
   90             }
   91             if (pid > -1)
   92                 (void)setpgid(pids[i], g_pgrp);
   93             pids[i] = pid;
   94             if (!g_keep_stressing_flag)
   95                 break;
   96         }
   97         for (i = 0; i < fork_max; i++) {
   98             if (pids[i] > 0) {
   99                 int status;
  100                 /* Parent, wait for child */
  101                 (void)waitpid(pids[i], &status, 0);
  102                 inc_counter(args);
  103             }
  104         }
  105 
  106         for (i = 0; i < fork_max; i++) {
  107             if ((pids[i] < 0) && (g_opt_flags & OPT_FLAGS_VERIFY)) {
  108                 switch (errnos[i]) {
  109                 case EAGAIN:
  110                 case ENOMEM:
  111                     break;
  112                 default:
  113                     pr_fail("%s: %s failed, errno=%d (%s)\n", args->name,
  114                         fork_fn_name, errnos[i], strerror(errnos[i]));
  115                     break;
  116                 }
  117             }
  118         }
  119     } while (keep_stressing());
  120 
  121     return EXIT_SUCCESS;
  122 }
  123 
  124 /*
  125  *  stress_fork()
  126  *  stress by forking and exiting
  127  */
  128 static int stress_fork(const args_t *args)
  129 {
  130     uint64_t fork_max = DEFAULT_FORKS;
  131 
  132     if (!get_setting("fork-max", &fork_max)) {
  133         if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
  134             fork_max = MAX_FORKS;
  135         if (g_opt_flags & OPT_FLAGS_MINIMIZE)
  136             fork_max = MIN_FORKS;
  137     }
  138 
  139     return stress_fork_fn(args, fork, "fork", fork_max);
  140 }
  141 
  142 
  143 /*
  144  *  stress_vfork()
  145  *  stress by vforking and exiting
  146  */
  147 static int stress_vfork(const args_t *args)
  148 {
  149     uint64_t vfork_max = DEFAULT_VFORKS;
  150     register int ret;
  151 
  152     if (!get_setting("vfork-max", &vfork_max)) {
  153         if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
  154             vfork_max = MAX_VFORKS;
  155         if (g_opt_flags & OPT_FLAGS_MINIMIZE)
  156             vfork_max = MIN_VFORKS;
  157     }
  158 
  159 PRAGMA_PUSH
  160 PRAGMA_WARN_OFF
  161     ret = stress_fork_fn(args, vfork, "vfork", vfork_max);
  162 PRAGMA_POP
  163     return ret;
  164 }
  165 
  166 stressor_info_t stress_fork_info = {
  167     .stressor = stress_fork,
  168     .class = CLASS_SCHEDULER | CLASS_OS
  169 };
  170 
  171 stressor_info_t stress_vfork_info = {
  172     .stressor = stress_vfork,
  173     .class = CLASS_SCHEDULER | CLASS_OS
  174 };