"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-sem.c" (15 Mar 2019, 3965 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-sem.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 int stress_set_semaphore_posix_procs(const char *opt)
   28 {
   29     uint64_t semaphore_posix_procs;
   30 
   31     semaphore_posix_procs = get_uint64(opt);
   32     check_range("sem-procs", semaphore_posix_procs,
   33         MIN_SEMAPHORE_PROCS, MAX_SEMAPHORE_PROCS);
   34     return set_setting("sem-procs", TYPE_ID_UINT64, &semaphore_posix_procs);
   35 }
   36 
   37 #if defined(HAVE_SEMAPHORE_H) && \
   38     defined(HAVE_LIB_PTHREAD) && \
   39     defined(HAVE_SEM_POSIX)
   40 
   41 static sem_t sem;
   42 static pthread_t pthreads[MAX_SEMAPHORE_PROCS];
   43 int p_ret[MAX_SEMAPHORE_PROCS];
   44 
   45 /*
   46  *  semaphore_posix_thrash()
   47  *  exercise the semaphore
   48  */
   49 static void *semaphore_posix_thrash(void *arg)
   50 {
   51     const pthread_args_t *p_args = arg;
   52     const args_t *args = p_args->args;
   53     static void *nowt = NULL;
   54 
   55     do {
   56         int i;
   57 
   58         for (i = 0; g_keep_stressing_flag && i < 1000; i++) {
   59             if (sem_trywait(&sem) < 0) {
   60                 if (errno == 0 || errno == EAGAIN)
   61                     continue;
   62                 if (errno != EINTR)
   63                     pr_fail_dbg("sem_trywait");
   64                 break;
   65             }
   66             inc_counter(args);
   67             if (sem_post(&sem) < 0) {
   68                 pr_fail_dbg("sem_post");
   69                 break;
   70             }
   71             if (i & 1)
   72                 (void)shim_sched_yield();
   73             else
   74                 (void)shim_usleep(0);
   75         }
   76     } while (keep_stressing());
   77 
   78     return &nowt;
   79 }
   80 
   81 /*
   82  *  stress_sem()
   83  *  stress system by POSIX sem ops
   84  */
   85 static int stress_sem(const args_t *args)
   86 {
   87     uint64_t semaphore_posix_procs = DEFAULT_SEMAPHORE_PROCS;
   88     uint64_t i;
   89     bool created = false;
   90     pthread_args_t p_args;
   91 
   92     if (!get_setting("sem-procs", &semaphore_posix_procs)) {
   93         if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
   94             semaphore_posix_procs = MAX_SEMAPHORE_PROCS;
   95         if (g_opt_flags & OPT_FLAGS_MINIMIZE)
   96             semaphore_posix_procs = MIN_SEMAPHORE_PROCS;
   97     }
   98 
   99     /* create a semaphore */
  100     if (sem_init(&sem, 0, 1) < 0) {
  101         pr_err("semaphore init (POSIX) failed: errno=%d: "
  102             "(%s)\n", errno, strerror(errno));
  103         return EXIT_FAILURE;
  104     }
  105 
  106     (void)memset(pthreads, 0, sizeof(pthreads));
  107     (void)memset(p_ret, 0, sizeof(p_ret));
  108 
  109     for (i = 0; i < semaphore_posix_procs; i++) {
  110         p_args.args = args;
  111         p_args.data = NULL;
  112         p_ret[i] = pthread_create(&pthreads[i], NULL,
  113                                 semaphore_posix_thrash, (void *)&p_args);
  114         if ((p_ret[i]) && (p_ret[i] != EAGAIN)) {
  115             pr_fail_errno("pthread create", p_ret[i]);
  116             break;
  117         }
  118         if (!g_keep_stressing_flag)
  119             break;
  120         created = true;
  121     }
  122 
  123     if (!created) {
  124         pr_inf("%s: could not create any pthreads\n", args->name);
  125         return EXIT_NO_RESOURCE;
  126     }
  127 
  128     /* Wait for termination */
  129     while (keep_stressing())
  130         (void)shim_usleep(100000);
  131 
  132     for (i = 0; i < semaphore_posix_procs; i++) {
  133         int ret;
  134 
  135         if (p_ret[i])
  136             continue;
  137 
  138         ret = pthread_join(pthreads[i], NULL);
  139         (void)ret;
  140     }
  141     (void)sem_destroy(&sem);
  142 
  143     return EXIT_SUCCESS;
  144 }
  145 
  146 stressor_info_t stress_sem_info = {
  147     .stressor = stress_sem,
  148     .class = CLASS_OS | CLASS_SCHEDULER
  149 };
  150 #else
  151 stressor_info_t stress_sem_info = {
  152     .stressor = stress_not_implemented,
  153     .class = CLASS_OS | CLASS_SCHEDULER
  154 };
  155 #endif