"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-close.c" (15 Mar 2019, 6101 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-close.c" see the Fossies "Dox" file reference documentation.

    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_LIB_PTHREAD)
   28 
   29 #define MAX_PTHREADS    (3)
   30 
   31 static volatile int fd, dupfd;
   32 static volatile uint64_t max_delay_us = 1;
   33 static sigset_t set;
   34 
   35 static const int domains[] = {
   36 #if defined(AF_UNIX)
   37     AF_UNIX,
   38 #endif
   39 #if defined(AF_LOCAL)
   40     AF_LOCAL,
   41 #endif
   42 /*
   43 #if defined(AF_INET)
   44     AF_INET,
   45 #endif
   46 #if defined(AF_INET6)
   47     AF_INET6,
   48 #endif
   49 */
   50 /*
   51 #if defined(AF_IPX)
   52     AF_IPX,
   53 #endif
   54 #if defined(AF_NETLINK)
   55     AF_NETLINK,
   56 #endif
   57 #if defined(AF_X25)
   58     AF_X25,
   59 #endif
   60 #if defined(AF_AX25)
   61     AF_AX25,
   62 #endif
   63 #if defined(AF_ATMPVC)
   64     AF_ATMPVC,
   65 #endif
   66 */
   67 #if defined(AF_APPLETALK)
   68     AF_APPLETALK,
   69 #endif
   70 #if defined(AF_PACKET)
   71     AF_PACKET,
   72 #endif
   73 #if defined(AF_ALG)
   74     AF_ALG,
   75 #endif
   76     0,
   77 };
   78 
   79 static const int types[] = {
   80 #if defined(SOCK_STREAM)
   81     SOCK_STREAM,
   82 #endif
   83 #if defined(SOCK_DGRAM)
   84     SOCK_DGRAM,
   85 #endif
   86 #if defined(SOCK_SEQPACKET)
   87     SOCK_SEQPACKET,
   88 #endif
   89 #if defined(SOCK_RAW)
   90     SOCK_RAW,
   91 #endif
   92 #if defined(SOCK_RDM)
   93     SOCK_RDM,
   94 #endif
   95     0,
   96 };
   97 
   98 /*
   99  *  stress_close_func()
  100  *  pthread that exits immediately
  101  */
  102 static void *stress_close_func(void *arg)
  103 {
  104     static void *nowt = NULL;
  105     pthread_args_t *pargs = (pthread_args_t *)arg;
  106     const args_t *args = pargs->args;
  107 
  108     /*
  109      *  Block all signals, let controlling thread
  110      *  handle these
  111      */
  112 #if !defined(__APPLE__) && !defined(__DragonFly__)
  113     (void)sigprocmask(SIG_BLOCK, &set, NULL);
  114 #endif
  115 
  116     while (keep_stressing()) {
  117         shim_usleep_interruptible(mwc32() % max_delay_us);
  118         (void)close(fd);
  119         shim_usleep_interruptible(mwc32() % max_delay_us);
  120         (void)close(dupfd);
  121     }
  122 
  123     return &nowt;
  124 }
  125 
  126 /*
  127  *  stress_close()
  128  *  stress by creating pthreads
  129  */
  130 static int stress_close(const args_t *args)
  131 {
  132     pthread_args_t pargs;
  133     pthread_t pthread[MAX_PTHREADS];
  134     int rc = EXIT_NO_RESOURCE;
  135     int ret, rets[MAX_PTHREADS];
  136     size_t i;
  137     const uid_t uid = getuid();
  138     const gid_t gid = getgid();
  139     double max_duration = 0.0;
  140     (void)sigfillset(&set);
  141 
  142     fd = -1;
  143     dupfd = -1;
  144 
  145     pargs.args = args;
  146     pargs.data = NULL;
  147 
  148     for (i = 0; i < MAX_PTHREADS; i++)
  149         rets[i] = -1;
  150 
  151     for (i = 0; i < MAX_PTHREADS; i++) {
  152         rets[i] = pthread_create(&pthread[i], NULL, stress_close_func, (void *)&pargs);
  153         if (rets[i]) {
  154             pr_inf("%s: failed to create a pthread, error=%d (%s)\n",
  155                 args->name, rets[i], strerror(rets[i]));
  156             goto tidy;
  157         }
  158     }
  159 
  160     do {
  161         size_t domain, type;
  162         int pipefds[2];
  163         struct stat statbuf;
  164         fd = -1;
  165         double t1, t2, duration;
  166 
  167         t1 = time_now();
  168 
  169         switch (mwc8() % 10) {
  170         case 0:
  171             domain = mwc8() % SIZEOF_ARRAY(domains);
  172             type = mwc8() % SIZEOF_ARRAY(types);
  173             fd = socket(domains[domain], types[type], 0);
  174             break;
  175         case 1:
  176             fd = open("/dev/zero", O_RDONLY);
  177             break;
  178 #if defined(O_TMPFILE)
  179         case 2:
  180             fd = open("/tmp", O_TMPFILE | O_RDWR,
  181                     S_IRUSR | S_IWUSR);
  182             break;
  183 #endif
  184 #if defined(HAVE_SYS_EPOLL_H)
  185         case 3:
  186             fd = epoll_create(1);
  187             break;
  188 #endif
  189 #if defined(HAVE_SYS_EVENTFD_H) &&  \
  190     defined(HAVE_EVENTFD) &&        \
  191     NEED_GLIBC(2,8,0)
  192         case 4:
  193             fd = eventfd(0, 0);
  194             break;
  195 #endif
  196 #if defined(HAVE_SYS_FANOTIFY_H) && \
  197     defined(HAVE_FANOTIFY)
  198         case 5:
  199             fd = fanotify_init(0, 0);
  200             break;
  201 #endif
  202 #if defined(HAVE_INOTIFY) &&        \
  203     defined(HAVE_SYS_INOTIFY_H)
  204         case 6:
  205             fd = inotify_init();
  206             break;
  207 #endif
  208         case 7:
  209             if (pipe(pipefds) == 0) {
  210                 fd = pipefds[0];
  211                 (void)close(pipefds[1]);
  212             }
  213             break;
  214 #if defined(HAVE_SYS_SIGNALFD_H) &&     \
  215     NEED_GLIBC(2,8,0) &&                \
  216     defined(HAVE_SIGQUEUE) &&       \
  217     defined(SIGRTMIN)
  218         case 8:
  219             {
  220                 sigset_t mask;
  221 
  222                 (void)sigemptyset(&mask);
  223                 (void)sigaddset(&mask, SIGRTMIN);
  224                 fd = signalfd(-1, &mask, 0);
  225             }
  226             break;
  227 #endif
  228 #if defined(HAVE_USERFAULTFD) &&    \
  229     defined(HAVE_LINUX_USERFAULTFD_H)
  230         case 9:
  231             fd = shim_userfaultfd(0);
  232             break;
  233 #endif
  234         default:
  235             break;
  236         }
  237         if (fd == -1)
  238             fd = open("/dev/null", O_RDWR);
  239 
  240         if (fd != -1) {
  241             dupfd = dup(fd);
  242 #if defined(HAVE_FCHOWNAT)
  243             ret = fchownat(fd, "", uid, gid, 0);
  244             (void)ret;
  245 #endif
  246             ret = fchown(fd, uid, gid);
  247             (void)ret;
  248 #if defined(HAVE_FACCESSAT)
  249             ret = faccessat(fd, "", F_OK, 0);
  250             (void)ret;
  251 #endif
  252             ret = fstat(fd, &statbuf);
  253             (void)ret;
  254 
  255             (void)close(fd);
  256             if (dupfd != -1)
  257                 (void)close(dupfd);
  258         }
  259         t2 = time_now();
  260         duration = t2 - t1;
  261         if (duration > max_duration) {
  262             max_duration = duration;
  263             /* max delay is 75% of the duration in microseconds */
  264             max_delay_us = duration * 750000;
  265         }
  266 
  267         max_duration *= 0.995;
  268         if (max_duration < 1.0)
  269             max_duration = 1.0;
  270         inc_counter(args);
  271     } while (keep_stressing());
  272 
  273     rc = EXIT_SUCCESS;
  274 tidy:
  275 
  276     for (i = 0; i < MAX_PTHREADS; i++) {
  277         if (rets[i] == -1)
  278             continue;
  279         ret = pthread_join(pthread[i], NULL);
  280         if ((ret) && (ret != ESRCH)) {
  281             pr_fail("%s pthread_join failed (parent), errno=%d (%s)",
  282                 args->name, ret, strerror(ret));
  283         }
  284     }
  285 
  286     return rc;
  287 }
  288 
  289 stressor_info_t stress_close_info = {
  290     .stressor = stress_close,
  291     .class = CLASS_SCHEDULER | CLASS_OS
  292 };
  293 #else
  294 stressor_info_t stress_close_info = {
  295     .stressor = stress_not_implemented,
  296     .class = CLASS_SCHEDULER | CLASS_OS
  297 };
  298 #endif