"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-zombie.c" (15 Mar 2019, 4383 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-zombie.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 typedef struct zombie {
   28     struct zombie *next;
   29     pid_t   pid;
   30 } zombie_t;
   31 
   32 typedef struct {
   33     zombie_t *head;     /* Head of zombie procs list */
   34     zombie_t *tail;     /* Tail of zombie procs list */
   35     zombie_t *free;     /* List of free'd zombies */
   36     uint64_t length;    /* Length of list */
   37 } zombie_list_t;
   38 
   39 static zombie_list_t zombies;
   40 
   41 /*
   42  *  stress_zombie_new()
   43  *  allocate a new zombie, add to end of list
   44  */
   45 static zombie_t *stress_zombie_new(void)
   46 {
   47     zombie_t *new;
   48 
   49     if (zombies.free) {
   50         /* Pop an old one off the free list */
   51         new = zombies.free;
   52         zombies.free = new->next;
   53         new->next = NULL;
   54     } else {
   55         new = calloc(1, sizeof(*new));
   56         if (!new)
   57             return NULL;
   58     }
   59 
   60     if (zombies.head)
   61         zombies.tail->next = new;
   62     else
   63         zombies.head = new;
   64 
   65     zombies.tail = new;
   66     zombies.length++;
   67 
   68     return new;
   69 }
   70 
   71 /*
   72  *  stress_zombie_head_remove
   73  *  reap a zombie and remove a zombie from head of list, put it onto
   74  *  the free zombie list
   75  */
   76 static void stress_zombie_head_remove(void)
   77 {
   78     if (zombies.head) {
   79         int status;
   80 
   81         (void)waitpid(zombies.head->pid, &status, 0);
   82 
   83         zombie_t *head = zombies.head;
   84 
   85         if (zombies.tail == zombies.head) {
   86             zombies.tail = NULL;
   87             zombies.head = NULL;
   88         } else {
   89             zombies.head = head->next;
   90         }
   91 
   92         /* Shove it on the free list */
   93         head->next = zombies.free;
   94         zombies.free = head;
   95 
   96         zombies.length--;
   97     }
   98 }
   99 
  100 /*
  101  *  stress_zombie_free()
  102  *  free the zombies off the zombie free lists
  103  */
  104 static void stress_zombie_free(void)
  105 {
  106     while (zombies.head) {
  107         zombie_t *next = zombies.head->next;
  108 
  109         free(zombies.head);
  110         zombies.head = next;
  111     }
  112     while (zombies.free) {
  113         zombie_t *next = zombies.free->next;
  114 
  115         free(zombies.free);
  116         zombies.free = next;
  117     }
  118 }
  119 
  120 /*
  121  *  stress_set_zombie_max()
  122  *  set maximum number of zombies allowed
  123  */
  124 int stress_set_zombie_max(const char *opt)
  125 {
  126     uint64_t zombie_max;
  127 
  128     zombie_max = get_uint64(opt);
  129     check_range("zombie-max", zombie_max,
  130         MIN_ZOMBIES, MAX_ZOMBIES);
  131     return set_setting("zombie-max", TYPE_ID_INT64, &zombie_max);
  132 }
  133 
  134 /*
  135  *  stress_zombie()
  136  *  stress by zombieing and exiting
  137  */
  138 static int stress_zombie(const args_t *args)
  139 {
  140     uint64_t max_zombies = 0;
  141     uint64_t zombie_max = DEFAULT_ZOMBIES;
  142 
  143     if (!get_setting("zombie-max", &zombie_max)) {
  144         if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
  145             zombie_max = MAX_ZOMBIES;
  146         if (g_opt_flags & OPT_FLAGS_MINIMIZE)
  147             zombie_max = MIN_ZOMBIES;
  148     }
  149 
  150     do {
  151         if (zombies.length < zombie_max) {
  152             zombie_t *zombie;
  153 
  154             zombie = stress_zombie_new();
  155             if (!zombie)
  156                 break;
  157 
  158             zombie->pid = fork();
  159             if (zombie->pid == 0) {
  160                 (void)setpgid(0, g_pgrp);
  161                 stress_parent_died_alarm();
  162 
  163                 stress_zombie_free();
  164                 _exit(0);
  165             }
  166             if (zombie->pid == -1) {
  167                 /* Reached max forks? .. then reap */
  168                 stress_zombie_head_remove();
  169                 continue;
  170             }
  171             (void)setpgid(zombie->pid, g_pgrp);
  172 
  173             if (max_zombies < zombies.length)
  174                 max_zombies = zombies.length;
  175             inc_counter(args);
  176         } else {
  177             stress_zombie_head_remove();
  178         }
  179     } while (keep_stressing());
  180 
  181     pr_inf("%s: created a maximum of %" PRIu64 " zombies\n",
  182         args->name, max_zombies);
  183 
  184     /* And reap */
  185     while (zombies.head) {
  186         stress_zombie_head_remove();
  187     }
  188     /* And free */
  189     stress_zombie_free();
  190 
  191     return EXIT_SUCCESS;
  192 }
  193 
  194 stressor_info_t stress_zombie_info = {
  195     .stressor = stress_zombie,
  196     .class = CLASS_SCHEDULER | CLASS_OS
  197 };