"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.60/stress-sigio.c" (22 Jun 2019, 4232 Bytes) of package /linux/privat/stress-ng-0.09.60.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-sigio.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.57_vs_0.09.58.

    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 static const help_t help[] = {
   28     { NULL, "sigio N",  "start N workers that exercise SIGIO signals" },
   29     { NULL, "sigio-ops N",  "stop after N bogo sigio signals" },
   30     { NULL, NULL,       NULL }
   31 };
   32 
   33 #if defined(O_ASYNC) && \
   34     defined(O_NONBLOCK) && \
   35     defined(F_SETOWN) && \
   36     defined(F_GETFL) && \
   37     defined(F_SETFL)
   38 
   39 #define BUFFER_SIZE (4096)
   40 
   41 static volatile int got_err;
   42 static int rd_fd;
   43 static const args_t *sigio_args;
   44 static pid_t pid;
   45 static double time_end;
   46 
   47 /*
   48  *  stress_sigio_handler()
   49  *      SIGIO handler
   50  */
   51 static void MLOCKED_TEXT stress_sigio_handler(int signum)
   52 {
   53     static char buffer[BUFFER_SIZE];
   54     const args_t *args = sigio_args;
   55 
   56         (void)signum;
   57 
   58     if (!keep_stressing() || (time_now() > time_end)) {
   59         if (pid > 0)
   60             (void)kill(pid, SIGKILL);
   61 
   62         (void)shim_sched_yield();
   63         return;
   64     }
   65 
   66     if (rd_fd > 0) {
   67         int ret;
   68 
   69         got_err = 0;
   70         ret = read(rd_fd, buffer, sizeof(buffer));
   71         if ((ret < 0) && (errno != EAGAIN))
   72             got_err = errno;
   73         else if (sigio_args)
   74             inc_counter(sigio_args);
   75         (void)shim_sched_yield();
   76     }
   77 }
   78 
   79 /*
   80  *  stress_sigio
   81  *  stress reading of /dev/zero using SIGIO
   82  */
   83 static int stress_sigio(const args_t *args)
   84 {
   85     int ret, rc = EXIT_FAILURE, fds[2], status;
   86 
   87     rd_fd = -1;
   88     sigio_args = args;
   89 
   90     time_end = time_now() + (double)g_opt_timeout;
   91 
   92     if (stress_sighandler(args->name, SIGIO, stress_sigio_handler, NULL) < 0)
   93         return rc;
   94 
   95     if (pipe(fds) < 0) {
   96         pr_fail_err("pipe");
   97         return rc;
   98     }
   99     rd_fd = fds[0];
  100 
  101 #if !defined(__minix__)
  102     ret = fcntl(fds[0], F_SETOWN, getpid());
  103     if (ret < 0) {
  104         if (errno != EINVAL) {
  105             pr_fail_err("fcntl F_SETOWN");
  106             goto err;
  107         }
  108     }
  109 #endif
  110     ret = fcntl(fds[0], F_GETFL);
  111     if (ret < 0) {
  112         pr_fail_err("fcntl F_GETFL");
  113         goto err;
  114     }
  115     ret = fcntl(fds[0], F_SETFL, ret | O_ASYNC | O_NONBLOCK);
  116     if (ret < 0) {
  117         pr_fail_err("fcntl F_SETFL");
  118         goto err;
  119     }
  120 
  121     pid = fork();
  122     if (pid < 0) {
  123         pr_fail_err("fork");
  124         goto err;
  125     } else if (pid == 0) {
  126         /* Child */
  127 
  128         char buffer[BUFFER_SIZE >> 4];
  129 
  130         (void)setpgid(0, g_pgrp);
  131                 stress_parent_died_alarm();
  132 
  133                 /* Make sure this is killable by OOM killer */
  134                 set_oom_adjustment(args->name, true);
  135 
  136         (void)close(fds[0]);
  137 
  138         (void)memset(buffer, 0, sizeof buffer);
  139 
  140         while (keep_stressing()) {
  141             ssize_t n;
  142 
  143             n = write(fds[1], buffer, sizeof buffer);
  144             if (n < 0)
  145                 break;
  146             (void)shim_sched_yield();
  147         }
  148         (void)close(fds[1]);
  149         _exit(1);
  150     }
  151 
  152     /* Parent */
  153     do {
  154         struct timeval timeout;
  155 
  156         timeout.tv_sec = 1;
  157         timeout.tv_usec = 0000;
  158 
  159         (void)select(0, NULL, NULL, NULL, &timeout);
  160         if (got_err) {
  161             pr_inf("%s: read error, errno=%d (%s)\n",
  162                 args->name, got_err, strerror(got_err));
  163             break;
  164         }
  165     } while (keep_stressing());
  166 
  167     if (pid > 0) {
  168         (void)kill(pid, SIGKILL);
  169         (void)shim_waitpid(pid, &status, 0);
  170     }
  171 
  172     rc = EXIT_SUCCESS;
  173 
  174 err:
  175     (void)close(fds[0]);
  176     (void)close(fds[1]);
  177 
  178     return rc;
  179 }
  180 
  181 stressor_info_t stress_sigio_info = {
  182     .stressor = stress_sigio,
  183     .class = CLASS_INTERRUPT | CLASS_OS,
  184     .help = help
  185 };
  186 #else
  187 stressor_info_t stress_sigio_info = {
  188     .stressor = stress_not_implemented,
  189     .class = CLASS_INTERRUPT | CLASS_OS,
  190     .help = help
  191 };
  192 #endif