~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/timers/freq-step.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/testing/selftests/timers/freq-step.c (Version linux-6.12-rc7) and /tools/testing/selftests/timers/freq-step.c (Version unix-v6-master)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * This test checks the response of the system    
  4  * steps made with adjtimex(). The frequency e    
  5  * the CLOCK_MONOTONIC clock relative to the C    
  6  * is measured in two intervals following the     
  7  * values from the second interval exceed spec    
  8  *                                                
  9  * Copyright (C) Miroslav Lichvar <mlichvar@re    
 10  */                                               
 11                                                   
 12 #include <math.h>                                 
 13 #include <stdio.h>                                
 14 #include <sys/timex.h>                            
 15 #include <time.h>                                 
 16 #include <unistd.h>                               
 17                                                   
 18 #include "../kselftest.h"                         
 19                                                   
 20 #define SAMPLES 100                               
 21 #define SAMPLE_READINGS 10                        
 22 #define MEAN_SAMPLE_INTERVAL 0.1                  
 23 #define STEP_INTERVAL 1.0                         
 24 #define MAX_PRECISION 500e-9                      
 25 #define MAX_FREQ_ERROR 0.02e-6                    
 26 #define MAX_STDDEV 50e-9                          
 27                                                   
 28 #ifndef ADJ_SETOFFSET                             
 29   #define ADJ_SETOFFSET 0x0100                    
 30 #endif                                            
 31                                                   
 32 struct sample {                                   
 33         double offset;                            
 34         double time;                              
 35 };                                                
 36                                                   
 37 static time_t mono_raw_base;                      
 38 static time_t mono_base;                          
 39 static long user_hz;                              
 40 static double precision;                          
 41 static double mono_freq_offset;                   
 42                                                   
 43 static double diff_timespec(struct timespec *t    
 44 {                                                 
 45         return ts1->tv_sec - ts2->tv_sec + (ts    
 46 }                                                 
 47                                                   
 48 static double get_sample(struct sample *sample    
 49 {                                                 
 50         double delay, mindelay = 0.0;             
 51         struct timespec ts1, ts2, ts3;            
 52         int i;                                    
 53                                                   
 54         for (i = 0; i < SAMPLE_READINGS; i++)     
 55                 clock_gettime(CLOCK_MONOTONIC_    
 56                 clock_gettime(CLOCK_MONOTONIC,    
 57                 clock_gettime(CLOCK_MONOTONIC_    
 58                                                   
 59                 ts1.tv_sec -= mono_raw_base;      
 60                 ts2.tv_sec -= mono_base;          
 61                 ts3.tv_sec -= mono_raw_base;      
 62                                                   
 63                 delay = diff_timespec(&ts3, &t    
 64                 if (delay <= 1e-9) {              
 65                         i--;                      
 66                         continue;                 
 67                 }                                 
 68                                                   
 69                 if (!i || delay < mindelay) {     
 70                         sample->offset = diff_    
 71                         sample->offset -= dela    
 72                         sample->time = ts1.tv_    
 73                         mindelay = delay;         
 74                 }                                 
 75         }                                         
 76                                                   
 77         return mindelay;                          
 78 }                                                 
 79                                                   
 80 static void reset_ntp_error(void)                 
 81 {                                                 
 82         struct timex txc;                         
 83                                                   
 84         txc.modes = ADJ_SETOFFSET;                
 85         txc.time.tv_sec = 0;                      
 86         txc.time.tv_usec = 0;                     
 87                                                   
 88         if (adjtimex(&txc) < 0) {                 
 89                 perror("[FAIL] adjtimex");        
 90                 ksft_exit_fail();                 
 91         }                                         
 92 }                                                 
 93                                                   
 94 static void set_frequency(double freq)            
 95 {                                                 
 96         struct timex txc;                         
 97         int tick_offset;                          
 98                                                   
 99         tick_offset = 1e6 * freq / user_hz;       
100                                                   
101         txc.modes = ADJ_TICK | ADJ_FREQUENCY;     
102         txc.tick = 1000000 / user_hz + tick_of    
103         txc.freq = (1e6 * freq - user_hz * tic    
104                                                   
105         if (adjtimex(&txc) < 0) {                 
106                 perror("[FAIL] adjtimex");        
107                 ksft_exit_fail();                 
108         }                                         
109 }                                                 
110                                                   
111 static void regress(struct sample *samples, in    
112                     double *slope, double *r_s    
113 {                                                 
114         double x, y, r, x_sum, y_sum, xy_sum,     
115         int i;                                    
116                                                   
117         x_sum = 0.0, y_sum = 0.0, xy_sum = 0.0    
118                                                   
119         for (i = 0; i < n; i++) {                 
120                 x = samples[i].time;              
121                 y = samples[i].offset;            
122                                                   
123                 x_sum += x;                       
124                 y_sum += y;                       
125                 xy_sum += x * y;                  
126                 x2_sum += x * x;                  
127         }                                         
128                                                   
129         *slope = (xy_sum - x_sum * y_sum / n)     
130         *intercept = (y_sum - *slope * x_sum)     
131                                                   
132         *r_max = 0.0, r2_sum = 0.0;               
133                                                   
134         for (i = 0; i < n; i++) {                 
135                 x = samples[i].time;              
136                 y = samples[i].offset;            
137                 r = fabs(x * *slope + *interce    
138                 if (*r_max < r)                   
139                         *r_max = r;               
140                 r2_sum += r * r;                  
141         }                                         
142                                                   
143         *r_stddev = sqrt(r2_sum / n);             
144 }                                                 
145                                                   
146 static int run_test(int calibration, double fr    
147 {                                                 
148         struct sample samples[SAMPLES];           
149         double intercept, slope, stddev1, max1    
150         double freq_error1, freq_error2;          
151         int i;                                    
152                                                   
153         set_frequency(freq_base);                 
154                                                   
155         for (i = 0; i < 10; i++)                  
156                 usleep(1e6 * MEAN_SAMPLE_INTER    
157                                                   
158         reset_ntp_error();                        
159                                                   
160         set_frequency(freq_base + freq_step);     
161                                                   
162         for (i = 0; i < 10; i++)                  
163                 usleep(rand() % 2000000 * STEP    
164                                                   
165         set_frequency(freq_base);                 
166                                                   
167         for (i = 0; i < SAMPLES; i++) {           
168                 usleep(rand() % 2000000 * MEAN    
169                 get_sample(&samples[i]);          
170         }                                         
171                                                   
172         if (calibration) {                        
173                 regress(samples, SAMPLES, &int    
174                 mono_freq_offset = slope;         
175                 printf("CLOCK_MONOTONIC_RAW fr    
176                        1e6 * mono_freq_offset)    
177                 return 0;                         
178         }                                         
179                                                   
180         regress(samples, SAMPLES / 2, &interce    
181         freq_error1 = slope * (1.0 - mono_freq    
182                         freq_base;                
183                                                   
184         regress(samples + SAMPLES / 2, SAMPLES    
185                 &stddev2, &max2);                 
186         freq_error2 = slope * (1.0 - mono_freq    
187                         freq_base;                
188                                                   
189         printf("%6.0f %+10.3f %6.0f %7.0f %+10    
190                1e6 * freq_step,                   
191                1e6 * freq_error1, 1e9 * stddev    
192                1e6 * freq_error2, 1e9 * stddev    
193                                                   
194         if (fabs(freq_error2) > MAX_FREQ_ERROR    
195                 printf("[FAIL]\n");               
196                 return 1;                         
197         }                                         
198                                                   
199         printf("[OK]\n");                         
200         return 0;                                 
201 }                                                 
202                                                   
203 static void init_test(void)                       
204 {                                                 
205         struct timespec ts;                       
206         struct sample sample;                     
207                                                   
208         if (clock_gettime(CLOCK_MONOTONIC_RAW,    
209                 perror("[FAIL] clock_gettime(C    
210                 ksft_exit_fail();                 
211         }                                         
212                                                   
213         mono_raw_base = ts.tv_sec;                
214                                                   
215         if (clock_gettime(CLOCK_MONOTONIC, &ts    
216                 perror("[FAIL] clock_gettime(C    
217                 ksft_exit_fail();                 
218         }                                         
219                                                   
220         mono_base = ts.tv_sec;                    
221                                                   
222         user_hz = sysconf(_SC_CLK_TCK);           
223                                                   
224         precision = get_sample(&sample) / 2.0;    
225         printf("CLOCK_MONOTONIC_RAW+CLOCK_MONO    
226                1e9 * precision);                  
227                                                   
228         if (precision > MAX_PRECISION)            
229                 ksft_exit_skip("precision: %.0    
230                                 1e9 * precisio    
231                                                   
232         printf("[OK]\n");                         
233         srand(ts.tv_sec ^ ts.tv_nsec);            
234                                                   
235         run_test(1, 0.0, 0.0);                    
236 }                                                 
237                                                   
238 int main(int argc, char **argv)                   
239 {                                                 
240         double freq_base, freq_step;              
241         int i, j, fails = 0;                      
242                                                   
243         init_test();                              
244                                                   
245         printf("Checking response to frequency    
246         printf("  Step           1st interval     
247         printf("             Freq    Dev     M    
248                                                   
249         for (i = 2; i >= 0; i--) {                
250                 for (j = 0; j < 5; j++) {         
251                         freq_base = (rand() %     
252                         freq_step = 10e-6 * (1    
253                         fails += run_test(0, f    
254                 }                                 
255         }                                         
256                                                   
257         set_frequency(0.0);                       
258                                                   
259         if (fails)                                
260                 ksft_exit_fail();                 
261                                                   
262         ksft_exit_pass();                         
263 }                                                 
264                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php