1 /* $NetBSD: ntp_fp.h,v 1.4 2013/12/28 03:20:13 christos Exp $ */ 2 3 /* 4 * ntp_fp.h - definitions for NTP fixed/floating-point arithmetic 5 */ 6 7 #ifndef NTP_FP_H 8 #define NTP_FP_H 9 10 #include "ntp_types.h" 11 12 /* 13 * NTP uses two fixed point formats. The first (l_fp) is the "long" 14 * format and is 64 bits long with the decimal between bits 31 and 32. 15 * This is used for time stamps in the NTP packet header (in network 16 * byte order) and for internal computations of offsets (in local host 17 * byte order). We use the same structure for both signed and unsigned 18 * values, which is a big hack but saves rewriting all the operators 19 * twice. Just to confuse this, we also sometimes just carry the 20 * fractional part in calculations, in both signed and unsigned forms. 21 * Anyway, an l_fp looks like: 22 * 23 * 0 1 2 3 24 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 25 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 26 * | Integral Part | 27 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 28 * | Fractional Part | 29 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 30 * 31 */ 32 typedef struct { 33 union { 34 u_int32 Xl_ui; 35 int32 Xl_i; 36 } Ul_i; 37 u_int32 l_uf; 38 } l_fp; 39 40 #define l_ui Ul_i.Xl_ui /* unsigned integral part */ 41 #define l_i Ul_i.Xl_i /* signed integral part */ 42 43 /* 44 * Fractional precision (of an l_fp) is actually the number of 45 * bits in a long. 46 */ 47 #define FRACTION_PREC (32) 48 49 50 /* 51 * The second fixed point format is 32 bits, with the decimal between 52 * bits 15 and 16. There is a signed version (s_fp) and an unsigned 53 * version (u_fp). This is used to represent synchronizing distance 54 * and synchronizing dispersion in the NTP packet header (again, in 55 * network byte order) and internally to hold both distance and 56 * dispersion values (in local byte order). In network byte order 57 * it looks like: 58 * 59 * 0 1 2 3 60 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 61 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 62 * | Integer Part | Fraction Part | 63 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 64 * 65 */ 66 typedef int32 s_fp; 67 typedef u_int32 u_fp; 68 69 /* 70 * A unit second in fp format. Actually 2**(half_the_bits_in_a_long) 71 */ 72 #define FP_SECOND (0x10000) 73 74 /* 75 * Byte order conversions 76 */ 77 #define HTONS_FP(x) (htonl(x)) 78 #define NTOHS_FP(x) (ntohl(x)) 79 80 #define NTOHL_MFP(ni, nf, hi, hf) \ 81 do { \ 82 (hi) = ntohl(ni); \ 83 (hf) = ntohl(nf); \ 84 } while (FALSE) 85 86 #define HTONL_MFP(hi, hf, ni, nf) \ 87 do { \ 88 (ni) = htonl(hi); \ 89 (nf) = htonl(hf); \ 90 } while (FALSE) 91 92 #define HTONL_FP(h, n) \ 93 HTONL_MFP((h)->l_ui, (h)->l_uf, (n)->l_ui, (n)->l_uf) 94 95 #define NTOHL_FP(n, h) \ 96 NTOHL_MFP((n)->l_ui, (n)->l_uf, (h)->l_ui, (h)->l_uf) 97 98 /* Convert unsigned ts fraction to net order ts */ 99 #define HTONL_UF(uf, nts) \ 100 do { \ 101 (nts)->l_ui = 0; \ 102 (nts)->l_uf = htonl(uf); \ 103 } while (FALSE) 104 105 /* 106 * Conversions between the two fixed point types 107 */ 108 #define MFPTOFP(x_i, x_f) (((x_i) >= 0x00010000) ? 0x7fffffff : \ 109 (((x_i) <= -0x00010000) ? 0x80000000 : \ 110 (((x_i)<<16) | (((x_f)>>16)&0xffff)))) 111 #define LFPTOFP(v) MFPTOFP((v)->l_i, (v)->l_uf) 112 113 #define UFPTOLFP(x, v) ((v)->l_ui = (u_fp)(x)>>16, (v)->l_uf = (x)<<16) 114 #define FPTOLFP(x, v) (UFPTOLFP((x), (v)), (x) < 0 ? (v)->l_ui -= 0x10000 : 0) 115 116 #define MAXLFP(v) ((v)->l_ui = 0x7fffffffu, (v)->l_uf = 0xffffffffu) 117 #define MINLFP(v) ((v)->l_ui = 0x80000000u, (v)->l_uf = 0u) 118 119 /* 120 * Primitive operations on long fixed point values. If these are 121 * reminiscent of assembler op codes it's only because some may 122 * be replaced by inline assembler for particular machines someday. 123 * These are the (kind of inefficient) run-anywhere versions. 124 */ 125 #define M_NEG(v_i, v_f) /* v = -v */ \ 126 do { \ 127 (v_f) = ~(v_f) + 1u; \ 128 (v_i) = ~(v_i) + ((v_f) == 0); \ 129 } while (FALSE) 130 131 #define M_NEGM(r_i, r_f, a_i, a_f) /* r = -a */ \ 132 do { \ 133 (r_f) = ~(a_f) + 1u; \ 134 (r_i) = ~(a_i) + ((r_f) == 0); \ 135 } while (FALSE) 136 137 #define M_ADD(r_i, r_f, a_i, a_f) /* r += a */ \ 138 do { \ 139 u_int32 add_t = (r_f); \ 140 (r_f) += (a_f); \ 141 (r_i) += (a_i) + ((u_int32)(r_f) < add_t); \ 142 } while (FALSE) 143 144 #define M_ADD3(r_o, r_i, r_f, a_o, a_i, a_f) /* r += a, three word */ \ 145 do { \ 146 u_int32 add_t, add_c; \ 147 add_t = (r_f); \ 148 (r_f) += (a_f); \ 149 add_c = ((u_int32)(r_f) < add_t); \ 150 (r_i) += add_c; \ 151 add_c = ((u_int32)(r_i) < add_c); \ 152 add_t = (r_i); \ 153 (r_i) += (a_i); \ 154 add_c |= ((u_int32)(r_i) < add_t); \ 155 (r_o) += (a_o) + add_c; \ 156 } while (FALSE) 157 158 #define M_SUB(r_i, r_f, a_i, a_f) /* r -= a */ \ 159 do { \ 160 u_int32 sub_t = (r_f); \ 161 (r_f) -= (a_f); \ 162 (r_i) -= (a_i) + ((u_int32)(r_f) > sub_t); \ 163 } while (FALSE) 164 165 #define M_RSHIFTU(v_i, v_f) /* v >>= 1, v is unsigned */ \ 166 do { \ 167 (v_f) = ((u_int32)(v_f) >> 1) | ((u_int32)(v_i) << 31); \ 168 (v_i) = ((u_int32)(v_i) >> 1); \ 169 } while (FALSE) 170 171 #define M_RSHIFT(v_i, v_f) /* v >>= 1, v is signed */ \ 172 do { \ 173 (v_f) = ((u_int32)(v_f) >> 1) | ((u_int32)(v_i) << 31); \ 174 (v_i) = ((u_int32)(v_i) >> 1) | ((u_int32)(v_i) & 0x80000000); \ 175 } while (FALSE) 176 177 #define M_LSHIFT(v_i, v_f) /* v <<= 1 */ \ 178 do { \ 179 (v_i) = ((u_int32)(v_i) << 1) | ((u_int32)(v_f) >> 31); \ 180 (v_f) = ((u_int32)(v_f) << 1); \ 181 } while (FALSE) 182 183 #define M_LSHIFT3(v_o, v_i, v_f) /* v <<= 1, with overflow */ \ 184 do { \ 185 (v_o) = ((u_int32)(v_o) << 1) | ((u_int32)(v_i) >> 31); \ 186 (v_i) = ((u_int32)(v_i) << 1) | ((u_int32)(v_f) >> 31); \ 187 (v_f) = ((u_int32)(v_f) << 1); \ 188 } while (FALSE) 189 190 #define M_ADDUF(r_i, r_f, uf) /* r += uf, uf is u_int32 fraction */ \ 191 M_ADD((r_i), (r_f), 0, (uf)) /* let optimizer worry about it */ 192 193 #define M_SUBUF(r_i, r_f, uf) /* r -= uf, uf is u_int32 fraction */ \ 194 M_SUB((r_i), (r_f), 0, (uf)) /* let optimizer worry about it */ 195 196 #define M_ADDF(r_i, r_f, f) /* r += f, f is a int32 fraction */ \ 197 do { \ 198 int32 add_f = (int32)(f); \ 199 if (add_f >= 0) \ 200 M_ADD((r_i), (r_f), 0, (uint32)( add_f)); \ 201 else \ 202 M_SUB((r_i), (r_f), 0, (uint32)(-add_f)); \ 203 } while(0) 204 205 #define M_ISNEG(v_i) /* v < 0 */ \ 206 (((v_i) & 0x80000000) != 0) 207 208 #define M_ISGT(a_i, a_f, b_i, b_f) /* a > b signed */ \ 209 (((int32)(a_i)) > ((int32)(b_i)) || \ 210 ((a_i) == (b_i) && ((u_int32)(a_f)) > ((u_int32)(b_f)))) 211 212 #define M_ISGTU(a_i, a_f, b_i, b_f) /* a > b unsigned */ \ 213 (((u_int32)(a_i)) > ((u_int32)(b_i)) || \ 214 ((a_i) == (b_i) && ((u_int32)(a_f)) > ((u_int32)(b_f)))) 215 216 #define M_ISHIS(a_i, a_f, b_i, b_f) /* a >= b unsigned */ \ 217 (((u_int32)(a_i)) > ((u_int32)(b_i)) || \ 218 ((a_i) == (b_i) && ((u_int32)(a_f)) >= ((u_int32)(b_f)))) 219 220 #define M_ISGEQ(a_i, a_f, b_i, b_f) /* a >= b signed */ \ 221 (((u_int32)(a_i) - (u_int32)(b_i) + 0x80000000 > 0x80000000) || \ 222 ((a_i) == (b_i) && (u_int32)(a_f) >= (u_int32)(b_f))) 223 224 #define M_ISEQU(a_i, a_f, b_i, b_f) /* a == b unsigned */ \ 225 ((a_i) == (b_i) && (a_f) == (b_f)) 226 227 /* 228 * Operations on the long fp format 229 */ 230 #define L_ADD(r, a) M_ADD((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf) 231 #define L_SUB(r, a) M_SUB((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf) 232 #define L_NEG(v) M_NEG((v)->l_ui, (v)->l_uf) 233 #define L_ADDUF(r, uf) M_ADDUF((r)->l_ui, (r)->l_uf, (uf)) 234 #define L_SUBUF(r, uf) M_SUBUF((r)->l_ui, (r)->l_uf, (uf)) 235 #define L_ADDF(r, f) M_ADDF((r)->l_ui, (r)->l_uf, (f)) 236 #define L_RSHIFT(v) M_RSHIFT((v)->l_i, (v)->l_uf) 237 #define L_RSHIFTU(v) M_RSHIFTU((v)->l_ui, (v)->l_uf) 238 #define L_LSHIFT(v) M_LSHIFT((v)->l_ui, (v)->l_uf) 239 #define L_CLR(v) ((v)->l_ui = (v)->l_uf = 0) 240 241 #define L_ISNEG(v) M_ISNEG((v)->l_ui) 242 #define L_ISZERO(v) (((v)->l_ui | (v)->l_uf) == 0) 243 #define L_ISGT(a, b) M_ISGT((a)->l_i, (a)->l_uf, (b)->l_i, (b)->l_uf) 244 #define L_ISGTU(a, b) M_ISGTU((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf) 245 #define L_ISHIS(a, b) M_ISHIS((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf) 246 #define L_ISGEQ(a, b) M_ISGEQ((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf) 247 #define L_ISEQU(a, b) M_ISEQU((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf) 248 249 /* 250 * s_fp/double and u_fp/double conversions 251 */ 252 #define FRIC 65536.0 /* 2^16 as a double */ 253 #define DTOFP(r) ((s_fp)((r) * FRIC)) 254 #define DTOUFP(r) ((u_fp)((r) * FRIC)) 255 #define FPTOD(r) ((double)(r) / FRIC) 256 257 /* 258 * l_fp/double conversions 259 */ 260 #define FRAC 4294967296.0 /* 2^32 as a double */ 261 262 /* 263 * Use 64 bit integers if available. Solaris on SPARC has a problem 264 * compiling parsesolaris.c if ntp_fp.h includes math.h, due to 265 * archaic gets() and printf() prototypes used in Solaris kernel 266 * headers. So far the problem has only been seen with gcc, but it 267 * may also affect Sun compilers, in which case the defined(__GNUC__) 268 * term should be removed. 269 */ 270 #if defined(HAVE_U_INT64) && \ 271 !(defined(__SVR4) && defined(__sun) && \ 272 defined(sparc) && defined(__GNUC__)) 273 274 #include <math.h> /* ldexp() */ 275 276 #define M_DTOLFP(d, r_ui, r_uf) /* double to l_fp */ \ 277 do { \ 278 double d_tmp; \ 279 u_int64 q_tmp; \ 280 int M_isneg; \ 281 \ 282 d_tmp = (d); \ 283 M_isneg = (d_tmp < 0.); \ 284 if (M_isneg) { \ 285 d_tmp = -d_tmp; \ 286 } \ 287 q_tmp = (u_int64)ldexp(d_tmp, 32); \ 288 if (M_isneg) { \ 289 q_tmp = ~q_tmp + 1; \ 290 } \ 291 (r_uf) = (u_int32)q_tmp; \ 292 (r_ui) = (u_int32)(q_tmp >> 32); \ 293 } while (FALSE) 294 295 #define M_LFPTOD(r_ui, r_uf, d) /* l_fp to double */ \ 296 do { \ 297 double d_tmp; \ 298 u_int64 q_tmp; \ 299 int M_isneg; \ 300 \ 301 q_tmp = ((u_int64)(r_ui) << 32) + (r_uf); \ 302 M_isneg = M_ISNEG(r_ui); \ 303 if (M_isneg) { \ 304 q_tmp = ~q_tmp + 1; \ 305 } \ 306 d_tmp = ldexp((double)q_tmp, -32); \ 307 if (M_isneg) { \ 308 d_tmp = -d_tmp; \ 309 } \ 310 (d) = d_tmp; \ 311 } while (FALSE) 312 313 #else /* use only 32 bit unsigned values */ 314 315 #define M_DTOLFP(d, r_ui, r_uf) /* double to l_fp */ \ 316 do { \ 317 double d_tmp; \ 318 if ((d_tmp = (d)) < 0) { \ 319 (r_ui) = (u_int32)(-d_tmp); \ 320 (r_uf) = (u_int32)(-(d_tmp + (double)(r_ui)) * FRAC); \ 321 M_NEG((r_ui), (r_uf)); \ 322 } else { \ 323 (r_ui) = (u_int32)d_tmp; \ 324 (r_uf) = (u_int32)((d_tmp - (double)(r_ui)) * FRAC); \ 325 } \ 326 } while (0) 327 #define M_LFPTOD(r_ui, r_uf, d) /* l_fp to double */ \ 328 do { \ 329 u_int32 l_thi, l_tlo; \ 330 l_thi = (r_ui); l_tlo = (r_uf); \ 331 if (M_ISNEG(l_thi)) { \ 332 M_NEG(l_thi, l_tlo); \ 333 (d) = -((double)l_thi + (double)l_tlo / FRAC); \ 334 } else { \ 335 (d) = (double)l_thi + (double)l_tlo / FRAC; \ 336 } \ 337 } while (0) 338 #endif 339 340 #define DTOLFP(d, v) M_DTOLFP((d), (v)->l_ui, (v)->l_uf) 341 #define LFPTOD(v, d) M_LFPTOD((v)->l_ui, (v)->l_uf, (d)) 342 343 /* 344 * Prototypes 345 */ 346 extern char * dofptoa (u_fp, int, short, int); 347 extern char * dolfptoa (u_int32, u_int32, int, short, int); 348 349 extern int atolfp (const char *, l_fp *); 350 extern int buftvtots (const char *, l_fp *); 351 extern char * fptoa (s_fp, short); 352 extern char * fptoms (s_fp, short); 353 extern int hextolfp (const char *, l_fp *); 354 extern void gpstolfp (int, int, unsigned long, l_fp *); 355 extern int mstolfp (const char *, l_fp *); 356 extern char * prettydate (l_fp *); 357 extern char * gmprettydate (l_fp *); 358 extern char * uglydate (l_fp *); 359 extern void mfp_mul (int32 *, u_int32 *, int32, u_int32, int32, u_int32); 360 361 extern void set_sys_fuzz (double); 362 extern void init_systime (void); 363 extern void get_systime (l_fp *); 364 extern int step_systime (double); 365 extern int adj_systime (double); 366 367 extern struct tm * ntp2unix_tm (u_int32 ntp, int local); 368 369 #define lfptoa(fpv, ndec) mfptoa((fpv)->l_ui, (fpv)->l_uf, (ndec)) 370 #define lfptoms(fpv, ndec) mfptoms((fpv)->l_ui, (fpv)->l_uf, (ndec)) 371 372 #define stoa(addr) socktoa(addr) 373 #define ntoa(addr) stoa(addr) 374 #define sptoa(addr) sockporttoa(addr) 375 #define stohost(addr) socktohost(addr) 376 377 #define ufptoa(fpv, ndec) dofptoa((fpv), 0, (ndec), 0) 378 #define ufptoms(fpv, ndec) dofptoa((fpv), 0, (ndec), 1) 379 #define ulfptoa(fpv, ndec) dolfptoa((fpv)->l_ui, (fpv)->l_uf, 0, (ndec), 0) 380 #define ulfptoms(fpv, ndec) dolfptoa((fpv)->l_ui, (fpv)->l_uf, 0, (ndec), 1) 381 #define umfptoa(fpi, fpf, ndec) dolfptoa((fpi), (fpf), 0, (ndec), 0) 382 383 /* 384 * Optional callback from libntp step_systime() to ntpd. Optional 385 * because other libntp clients like ntpdate don't use it. 386 */ 387 typedef void (*time_stepped_callback)(void); 388 extern time_stepped_callback step_callback; 389 390 /* 391 * Multi-thread locking for get_systime() 392 * 393 * On most systems, get_systime() is used solely by the main ntpd 394 * thread, but on Windows it's also used by the dedicated I/O thread. 395 * The [Bug 2037] changes to get_systime() have it keep state between 396 * calls to ensure time moves in only one direction, which means its 397 * use on Windows needs to be protected against simultaneous execution 398 * to avoid falsely detecting Lamport violations by ensuring only one 399 * thread at a time is in get_systime(). 400 */ 401 #ifdef SYS_WINNT 402 extern CRITICAL_SECTION get_systime_cs; 403 # define INIT_GET_SYSTIME_CRITSEC() \ 404 InitializeCriticalSection(&get_systime_cs) 405 # define ENTER_GET_SYSTIME_CRITSEC() \ 406 EnterCriticalSection(&get_systime_cs) 407 # define LEAVE_GET_SYSTIME_CRITSEC() \ 408 LeaveCriticalSection(&get_systime_cs) 409 # define INIT_WIN_PRECISE_TIME() \ 410 init_win_precise_time() 411 #else /* !SYS_WINNT follows */ 412 # define INIT_GET_SYSTIME_CRITSEC() \ 413 do {} while (FALSE) 414 # define ENTER_GET_SYSTIME_CRITSEC() \ 415 do {} while (FALSE) 416 # define LEAVE_GET_SYSTIME_CRITSEC() \ 417 do {} while (FALSE) 418 # define INIT_WIN_PRECISE_TIME() \ 419 do {} while (FALSE) 420 #endif 421 422 #endif /* NTP_FP_H */ 423