"Fossies" - the Fresh Open Source Software Archive

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