"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-itimer.c" (15 Mar 2019, 4560 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-itimer.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 static volatile uint64_t itimer_counter = 0;
   28 static uint64_t max_ops;
   29 static double rate_us;
   30 static double start;
   31 
   32 /*
   33  *  stress_set_itimer_freq()
   34  *  set itimer frequency from given option
   35  */
   36 int stress_set_itimer_freq(const char *opt)
   37 {
   38     uint64_t itimer_freq;
   39 
   40     itimer_freq = get_uint64(opt);
   41     check_range("itimer-freq", itimer_freq,
   42         MIN_TIMER_FREQ, MAX_TIMER_FREQ);
   43     return set_setting("itimer-freq", TYPE_ID_UINT64, &itimer_freq);
   44 }
   45 
   46 /*
   47  *  stress_itimer_set()
   48  *  set timer, ensure it is never zero
   49  */
   50 static void stress_itimer_set(struct itimerval *timer)
   51 {
   52     double rate;
   53 
   54     if (g_opt_flags & OPT_FLAGS_TIMER_RAND) {
   55         /* Mix in some random variation */
   56         double r = ((double)(mwc32() % 10000) - 5000.0) / 40000.0;
   57         rate = rate_us + (rate_us * r);
   58     } else {
   59         rate = rate_us;
   60     }
   61 
   62     timer->it_value.tv_sec = (time_t)rate / 1000000;
   63     timer->it_value.tv_usec = (suseconds_t)rate % 1000000;
   64     if (timer->it_value.tv_sec == 0 &&
   65         timer->it_value.tv_usec < 1)
   66         timer->it_value.tv_usec = 1;
   67 
   68     timer->it_interval.tv_sec = timer->it_value.tv_sec;
   69     timer->it_interval.tv_usec = timer->it_value.tv_usec;
   70 }
   71 
   72 /*
   73  *  stress_itimer_keep_stressing()
   74  *      returns true if we can keep on running a stressor
   75  */
   76 static bool HOT OPTIMIZE3 stress_itimer_keep_stressing(void)
   77 {
   78         return (LIKELY(g_keep_stressing_flag) &&
   79                 LIKELY(!max_ops || (itimer_counter < max_ops)));
   80 }
   81 
   82 /*
   83  *  stress_itimer_handler()
   84  *  catch itimer signal and cancel if no more runs flagged
   85  */
   86 static void stress_itimer_handler(int sig)
   87 {
   88     struct itimerval timer;
   89     sigset_t mask;
   90 
   91     (void)sig;
   92 
   93     if (!stress_itimer_keep_stressing())
   94         goto cancel;
   95     itimer_counter++;
   96 
   97     if (sigpending(&mask) == 0)
   98         if (sigismember(&mask, SIGINT))
   99             goto cancel;
  100     /* High freq timer, check periodically for timeout */
  101     if ((itimer_counter & 65535) == 0)
  102         if ((time_now() - start) > (double)g_opt_timeout)
  103             goto cancel;
  104     if (g_keep_stressing_flag) {
  105         stress_itimer_set(&timer);
  106         return;
  107     }
  108 
  109 cancel:
  110     g_keep_stressing_flag = false;
  111     /* Cancel timer if we detect no more runs */
  112     (void)memset(&timer, 0, sizeof(timer));
  113     (void)setitimer(ITIMER_PROF, &timer, NULL);
  114 }
  115 
  116 /*
  117  *  stress_itimer
  118  *  stress itimer
  119  */
  120 static int stress_itimer(const args_t *args)
  121 {
  122     struct itimerval timer;
  123     sigset_t mask;
  124     uint64_t itimer_freq = DEFAULT_TIMER_FREQ;
  125 
  126     (void)sigemptyset(&mask);
  127     (void)sigaddset(&mask, SIGINT);
  128     (void)sigprocmask(SIG_SETMASK, &mask, NULL);
  129 
  130     max_ops = args->max_ops;
  131     start = time_now();
  132 
  133     if (!get_setting("itimer-freq", &itimer_freq)) {
  134         if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
  135             itimer_freq = MAX_ITIMER_FREQ;
  136         if (g_opt_flags & OPT_FLAGS_MINIMIZE)
  137             itimer_freq = MIN_ITIMER_FREQ;
  138     }
  139     rate_us = itimer_freq ? 1000000.0 / itimer_freq : 1000000.0;
  140 
  141     if (stress_sighandler(args->name, SIGPROF, stress_itimer_handler, NULL) < 0)
  142         return EXIT_FAILURE;
  143 
  144     stress_itimer_set(&timer);
  145     if (setitimer(ITIMER_PROF, &timer, NULL) < 0) {
  146         if (errno == EINVAL) {
  147             pr_inf("%s: skipping stressor, setitimer with "
  148                 "ITIMER_PROF is not implemented\n",
  149                 args->name);
  150             return EXIT_NOT_IMPLEMENTED;
  151         }
  152         pr_fail_err("setitimer");
  153         return EXIT_FAILURE;
  154     }
  155 
  156     do {
  157         struct itimerval t;
  158         (void)getitimer(ITIMER_PROF, &t);
  159 
  160         set_counter(args, itimer_counter);
  161     } while (keep_stressing());
  162 
  163     (void)memset(&timer, 0, sizeof(timer));
  164     (void)setitimer(ITIMER_PROF, &timer, NULL);
  165     return EXIT_SUCCESS;
  166 }
  167 
  168 stressor_info_t stress_itimer_info = {
  169     .stressor = stress_itimer,
  170     .class = CLASS_INTERRUPT | CLASS_OS
  171 };