CTC++ Coverage Report - Execution Profile    #6/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: init/calibrate.c
Instrumentation mode: function-decision-multicondition
TER: 37 % ( 18/ 49)

Start/ End/    
True False - Line Source

  1 /* calibrate.c: default delay calibration
  2  *
  3  * Excised from init/main.c
  4  *  Copyright (C) 1991, 1992  Linus Torvalds
  5  */
  6 
  7 #include <linux/sched.h>
  8 #include <linux/delay.h>
  9 #include <linux/init.h>
  10 
  11 #include <asm/timex.h>
  12 
  13 static unsigned long preset_lpj;
 
- 14 static int __init lpj_setup(char *str)
  15 {
  16    preset_lpj = simple_strtoul(str,NULL,0);
 - 17    return 1;
  18 }
  19 
  20 __setup("lpj=", lpj_setup);
  21 
  22 #ifdef ARCH_HAS_READ_CURRENT_TIMER
  23 
  24 /* This routine uses the read_current_timer() routine and gets the
  25  * loops per jiffy directly, instead of guessing it using delay().
  26  * Also, this code tries to handle non-maskable asynchronous events
  27  * (like SMIs)
  28  */
  29 #define DELAY_CALIBRATION_TICKS         ((HZ < 100) ? 1 : (HZ/100))
  30 #define MAX_DIRECT_CALIBRATION_RETRIES      5
  31 
 
  32 static unsigned long __devinit calibrate_delay_direct(void)
  33 {
  34    unsigned long pre_start, start, post_start;
  35    unsigned long pre_end, end, post_end;
  36    unsigned long start_jiffies;
  37    unsigned long tsc_rate_min, tsc_rate_max;
  38    unsigned long good_tsc_sum = 0;
  39    unsigned long good_tsc_count = 0;
  40    int i;
  41 
- 42    if (read_current_timer(&pre_start) < 0 )
 - 43       return 0;
  44 
  45    /*
  46     * A simple loop like
  47     *   while ( jiffies < start_jiffies+1)
  48     *      start = read_current_timer();
  49     * will not do. As we don't really know whether jiffy switch
  50     * happened first or timer_value was read first. And some asynchronous
  51     * event can happen between these two events introducing errors in lpj.
  52     *
  53     * So, we do
  54     * 1. pre_start <- When we are sure that jiffy switch hasn't happened
  55     * 2. check jiffy switch
  56     * 3. start <- timer value before or after jiffy switch
  57     * 4. post_start <- When we are sure that jiffy switch has happened
  58     *
  59     * Note, we don't know anything about order of 2 and 3.
  60     * Now, by looking at post_start and pre_start difference, we can
  61     * check whether any asynchronous event happened or not
  62     */
  63 
15   64    for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) {
  65       pre_start = 0;
  66       read_current_timer(&start);
  67       start_jiffies = jiffies;
7688E3 15   68       while (jiffies <= (start_jiffies + 1)) {
  69          pre_start = start;
  70          read_current_timer(&start);
  71       }
  72       read_current_timer(&post_start);
  73 
  74       pre_end = 0;
  75       end = post_start;
  76       while (jiffies <=
6948E3 15   77              (start_jiffies + 1 + DELAY_CALIBRATION_TICKS)) {
6948E3 - 77   ternary-?: ( 250 < 100 )
  78          pre_end = end;
  79          read_current_timer(&end);
  80       }
  81       read_current_timer(&post_end);
  82 
    83       tsc_rate_max = (post_end - pre_start) / DELAY_CALIBRATION_TICKS;
15 - 83   ternary-?: ( 250 < 100 )
    84       tsc_rate_min = (pre_end - post_start) / DELAY_CALIBRATION_TICKS;
15 - 84   ternary-?: ( 250 < 100 )
  85 
  86       /*
  87         * If the upper limit and lower limit of the tsc_rate is
  88        * >= 12.5% apart, redo calibration.
  89        */
  90       if (pre_start != 0 && pre_end != 0 &&
15 - 91           (tsc_rate_max - tsc_rate_min) < (tsc_rate_max >> 3)) {
15    91     T && T && T
 - 91     T && T && F
 - 91     T && F && _
 - 91     F && _ && _
  92          good_tsc_count++;
  93          good_tsc_sum += tsc_rate_max;
  94       }
  95    }
  96 
- 97    if (good_tsc_count)
   98       return (good_tsc_sum/good_tsc_count);
  99 
  100    printk(KERN_WARNING "calibrate_delay_direct() failed to get a good "
  101           "estimate for loops_per_jiffy.\nProbably due to long platform interrupts. Consider using \"lpj=\" boot option.\n");
 - 102    return 0;
  103 }
  104 #else
  105 static unsigned long __devinit calibrate_delay_direct(void) {return 0;}
  106 #endif
  107 
  108 /*
  109  * This is the number of bits of precision for the loops_per_jiffy.  Each
  110  * bit takes on average 1.5/HZ seconds.  This (like the original) is a little
  111  * better than 1%
  112  */
  113 #define LPS_PREC 8
  114 
 
  115 void __devinit calibrate_delay(void)
  116 {
  117    unsigned long ticks, loopbit;
  118    int lps_precision = LPS_PREC;
  119 
- 120    if (preset_lpj) {
  121       loops_per_jiffy = preset_lpj;
  122       printk("Calibrating delay loop (skipped)... "
  123          "%lu.%02lu BogoMIPS preset\n",
  124          loops_per_jiffy/(500000/HZ),
  125          (loops_per_jiffy/(5000/HZ)) % 100);
- 126    } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
  127       printk("Calibrating delay using timer specific routine.. ");
  128       printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
  129          loops_per_jiffy/(500000/HZ),
  130          (loops_per_jiffy/(5000/HZ)) % 100,
  131          loops_per_jiffy);
    132    } else {
  133       loops_per_jiffy = (1<<12);
  134 
  135       printk(KERN_DEBUG "Calibrating delay loop... ");
- 136       while ((loops_per_jiffy <<= 1) != 0) {
  137          /* wait for "start of" clock tick */
  138          ticks = jiffies;
- 139          while (ticks == jiffies)
  140             /* nothing */;
  141          /* Go .. */
  142          ticks = jiffies;
  143          __delay(loops_per_jiffy);
  144          ticks = jiffies - ticks;
- 145          if (ticks)
 - 146             break;
  147       }
  148 
  149       /*
  150        * Do a binary approximation to get loops_per_jiffy set to
  151        * equal one clock (up to lps_precision bits)
  152        */
  153       loops_per_jiffy >>= 1;
  154       loopbit = loops_per_jiffy;
- 155       while (lps_precision-- && (loopbit >>= 1)) {
 - 155     T && (T)
 - 155     T && (F)
 - 155     F && (_)
  156          loops_per_jiffy |= loopbit;
  157          ticks = jiffies;
- 158          while (ticks == jiffies)
  159             /* nothing */;
  160          ticks = jiffies;
  161          __delay(loops_per_jiffy);
- 162          if (jiffies != ticks)   /* longer than 1 tick */
  163             loops_per_jiffy &= ~loopbit;
  164       }
  165 
  166       /* Round the value and print it */
  167       printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
  168          loops_per_jiffy/(500000/HZ),
  169          (loops_per_jiffy/(5000/HZ)) % 100,
  170          loops_per_jiffy);
  171    }
  172 
  173 }
***TER 37% (18/49) of SOURCE FILE calibrate.c

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last | Top