"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-sigrt.c" (15 Mar 2019, 3689 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-sigrt.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(HAVE_SIGQUEUE) &&       \
   28     defined(HAVE_SIGWAITINFO) &&    \
   29     defined(SIGRTMIN) &&        \
   30     defined(SIGRTMAX)
   31 
   32 #define MAX_RTPIDS (SIGRTMAX - SIGRTMIN + 1)
   33 
   34 static void MLOCKED_TEXT stress_sigrthandler(int signum)
   35 {
   36     (void)signum;
   37 }
   38 
   39 /*
   40  *  stress_sigrt
   41  *  stress by heavy real time sigqueue message sending
   42  */
   43 static int stress_sigrt(const args_t *args)
   44 {
   45     pid_t pids[MAX_RTPIDS];
   46     union sigval s;
   47     int i, status;
   48 
   49     (void)memset(pids, 0, sizeof pids);
   50 
   51     for (i = 0; i < MAX_RTPIDS; i++) {
   52         if (stress_sighandler(args->name, i + SIGRTMIN, stress_sigrthandler, NULL) < 0) {
   53             return EXIT_FAILURE;
   54         }
   55     }
   56 
   57     for (i = 0; i < MAX_RTPIDS; i++) {
   58 again:
   59         pids[i] = fork();
   60         if (pids[i] < 0) {
   61             if (g_keep_stressing_flag && (errno == EAGAIN))
   62                 goto again;
   63             pr_fail_dbg("fork");
   64             goto reap;
   65         } else if (pids[i] == 0) {
   66             sigset_t mask;
   67             siginfo_t info;
   68 
   69             (void)setpgid(0, g_pgrp);
   70             stress_parent_died_alarm();
   71 
   72             (void)sigemptyset(&mask);
   73             for (i = 0; i < MAX_RTPIDS; i++)
   74                 (void)sigaddset(&mask, i + SIGRTMIN);
   75 
   76             while (g_keep_stressing_flag) {
   77                 (void)memset(&info, 0, sizeof info);
   78 
   79                 if (sigwaitinfo(&mask, &info) < 0) {
   80                     if (errno == EINTR)
   81                         continue;
   82                     break;
   83                 }
   84                 if (info.si_value.sival_int == 0)
   85                     break;
   86 
   87                 if (info.si_value.sival_int != -1) {
   88                     (void)memset(&s, 0, sizeof(s));
   89                     s.sival_int = -1;
   90                     (void)sigqueue(info.si_value.sival_int, SIGRTMIN, s);
   91                 }
   92             }
   93             /*
   94             pr_dbg("%s: child got termination notice (%d)\n", args->name, info.si_value.sival_int);
   95             pr_dbg("%s: exited on pid [%d] (instance %" PRIu32 ")\n",
   96                 args->name, getpid(), args->instance);
   97             */
   98             _exit(0);
   99         }
  100     }
  101 
  102     /* Parent */
  103     do {
  104         for (i = 0; i < MAX_RTPIDS; i++) {
  105             const int pid = pids[(i + 1) % MAX_RTPIDS];
  106 
  107             (void)memset(&s, 0, sizeof(s));
  108 
  109             /* Inform child which pid to queue a signal to */
  110             s.sival_int = pid;
  111             (void)sigqueue(pids[i], i + SIGRTMIN, s);
  112             inc_counter(args);
  113         }
  114     } while (keep_stressing());
  115 
  116     for (i = 0; i < MAX_RTPIDS; i++) {
  117         if (pids[i] > 0) {
  118             (void)memset(&s, 0, sizeof(s));
  119             s.sival_int = 0;
  120             (void)sigqueue(pids[i], i + SIGRTMIN, s);
  121         }
  122     }
  123     (void)shim_usleep(250);
  124 reap:
  125     for (i = 0; i < MAX_RTPIDS; i++) {
  126         if (pids[i] > 0) {
  127             /* And ensure child is really dead */
  128             (void)kill(pids[i], SIGKILL);
  129             (void)waitpid(pids[i], &status, 0);
  130         }
  131     }
  132 
  133     return EXIT_SUCCESS;
  134 }
  135 
  136 stressor_info_t stress_sigrt_info = {
  137     .stressor = stress_sigrt,
  138     .class = CLASS_INTERRUPT | CLASS_OS
  139 };
  140 #else
  141 stressor_info_t stress_sigrt_info = {
  142     .stressor = stress_not_implemented,
  143     .class = CLASS_INTERRUPT | CLASS_OS
  144 };
  145 #endif