"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-membarrier.c" (15 Mar 2019, 4125 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-membarrier.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 #if defined(HAVE_LIB_PTHREAD) && \
   28     defined(HAVE_MEMBARRIER)
   29 
   30 #define MAX_MEMBARRIER_THREADS  (4)
   31 
   32 static volatile bool keep_running;
   33 static sigset_t set;
   34 
   35 #if !defined(HAVE_LINUX_MEMBARRIER_H)
   36 enum membarrier_cmd {
   37     MEMBARRIER_CMD_QUERY = 0,
   38     MEMBARRIER_CMD_SHARED = (1 << 0),
   39     MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3),
   40     MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4)
   41 };
   42 #endif
   43 
   44 static void *stress_membarrier_thread(void *parg)
   45 {
   46     static void *nowt = NULL;
   47     uint8_t stack[SIGSTKSZ + STACK_ALIGNMENT];
   48     const args_t *args = ((pthread_args_t *)parg)->args;
   49 
   50     /*
   51      *  Block all signals, let controlling thread
   52      *  handle these
   53      */
   54     (void)sigprocmask(SIG_BLOCK, &set, NULL);
   55 
   56     /*
   57      *  According to POSIX.1 a thread should have
   58      *  a distinct alternative signal stack.
   59      *  However, we block signals in this thread
   60      *  so this is probably just totally unncessary.
   61      */
   62     (void)memset(stack, 0, sizeof(stack));
   63     if (stress_sigaltstack(stack, SIGSTKSZ) < 0)
   64         return &nowt;
   65 
   66     while (keep_running && g_keep_stressing_flag) {
   67         int ret;
   68 
   69         ret = shim_membarrier(MEMBARRIER_CMD_QUERY, 0);
   70         if (ret < 0) {
   71             pr_fail_err("membarrier CMD QUERY");
   72             break;
   73         }
   74         /* CMD SHARED not available; skip it */
   75         if (!(ret & MEMBARRIER_CMD_SHARED))
   76             continue;
   77         if (shim_membarrier(MEMBARRIER_CMD_SHARED, 0) < 0) {
   78             pr_fail_err("membarrier CMD SHARED");
   79             break;
   80         }
   81     }
   82 
   83     return &nowt;
   84 }
   85 
   86 /*
   87  *  stress on membarrier()
   88  *  stress system by IO sync calls
   89  */
   90 static int stress_membarrier(const args_t *args)
   91 {
   92     int ret;
   93     pthread_t pthreads[MAX_MEMBARRIER_THREADS];
   94     size_t i;
   95     int pthread_ret[MAX_MEMBARRIER_THREADS];
   96     pthread_args_t pargs = { args, NULL };
   97 
   98     ret = shim_membarrier(MEMBARRIER_CMD_QUERY, 0);
   99     if (ret < 0) {
  100         if (errno == ENOSYS) {
  101             pr_inf("%s: stressor will be skipped, "
  102                 "membarrier not supported\n",
  103                 args->name);
  104             return EXIT_NOT_IMPLEMENTED;
  105         }
  106         pr_err("%s: membarrier failed: errno=%d: (%s)\n",
  107             args->name, errno, strerror(errno));
  108         return EXIT_FAILURE;
  109     }
  110     if (!(ret & MEMBARRIER_CMD_SHARED)) {
  111         pr_inf("%s: membarrier MEMBARRIER_CMD_SHARED "
  112             "not supported\n", args->name);
  113         return EXIT_FAILURE;
  114     }
  115 
  116     (void)sigfillset(&set);
  117     (void)memset(pthread_ret, 0, sizeof(pthread_ret));
  118     keep_running = true;
  119 
  120     for (i = 0; i < MAX_MEMBARRIER_THREADS; i++) {
  121         pthread_ret[i] =
  122             pthread_create(&pthreads[i], NULL,
  123                 stress_membarrier_thread, (void *)&pargs);
  124     }
  125 
  126     do {
  127         ret = shim_membarrier(MEMBARRIER_CMD_SHARED, 0);
  128         if (ret < 0) {
  129             pr_err("%s: membarrier failed: errno=%d: (%s)\n",
  130                 args->name, errno, strerror(errno));
  131         }
  132         inc_counter(args);
  133     } while (keep_stressing());
  134 
  135     keep_running = false;
  136 
  137     for (i = 0; i < MAX_MEMBARRIER_THREADS; i++) {
  138         if (pthread_ret[i] == 0)
  139             (void)pthread_join(pthreads[i], NULL);
  140     }
  141     return EXIT_SUCCESS;
  142 }
  143 
  144 stressor_info_t stress_membarrier_info = {
  145     .stressor = stress_membarrier,
  146     .class = CLASS_CPU_CACHE | CLASS_MEMORY
  147 };
  148 #else
  149 stressor_info_t stress_membarrier_info = {
  150     .stressor = stress_not_implemented,
  151     .class = CLASS_CPU_CACHE | CLASS_MEMORY
  152 };
  153 #endif