154359Sroberto/* 254359Sroberto * ntp_fp.h - definitions for NTP fixed/floating-point arithmetic 354359Sroberto */ 454359Sroberto 554359Sroberto#ifndef NTP_FP_H 654359Sroberto#define NTP_FP_H 754359Sroberto 854359Sroberto#include "ntp_types.h" 954359Sroberto 1054359Sroberto/* 1154359Sroberto * NTP uses two fixed point formats. The first (l_fp) is the "long" 1254359Sroberto * format and is 64 bits long with the decimal between bits 31 and 32. 1354359Sroberto * This is used for time stamps in the NTP packet header (in network 1454359Sroberto * byte order) and for internal computations of offsets (in local host 1554359Sroberto * byte order). We use the same structure for both signed and unsigned 1654359Sroberto * values, which is a big hack but saves rewriting all the operators 1754359Sroberto * twice. Just to confuse this, we also sometimes just carry the 1854359Sroberto * fractional part in calculations, in both signed and unsigned forms. 1954359Sroberto * Anyway, an l_fp looks like: 2054359Sroberto * 2154359Sroberto * 0 1 2 3 2254359Sroberto * 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 2354359Sroberto * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2454359Sroberto * | Integral Part | 2554359Sroberto * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2654359Sroberto * | Fractional Part | 2754359Sroberto * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2854359Sroberto * 2954359Sroberto */ 3054359Srobertotypedef struct { 3154359Sroberto union { 3254359Sroberto u_int32 Xl_ui; 3354359Sroberto int32 Xl_i; 3454359Sroberto } Ul_i; 35285612Sdelphij u_int32 l_uf; 3654359Sroberto} l_fp; 3754359Sroberto 3854359Sroberto#define l_ui Ul_i.Xl_ui /* unsigned integral part */ 3954359Sroberto#define l_i Ul_i.Xl_i /* signed integral part */ 4054359Sroberto 4154359Sroberto/* 4254359Sroberto * Fractional precision (of an l_fp) is actually the number of 4354359Sroberto * bits in a long. 4454359Sroberto */ 4554359Sroberto#define FRACTION_PREC (32) 4654359Sroberto 4754359Sroberto 4854359Sroberto/* 4954359Sroberto * The second fixed point format is 32 bits, with the decimal between 5054359Sroberto * bits 15 and 16. There is a signed version (s_fp) and an unsigned 5154359Sroberto * version (u_fp). This is used to represent synchronizing distance 5254359Sroberto * and synchronizing dispersion in the NTP packet header (again, in 5354359Sroberto * network byte order) and internally to hold both distance and 5454359Sroberto * dispersion values (in local byte order). In network byte order 5554359Sroberto * it looks like: 5654359Sroberto * 5754359Sroberto * 0 1 2 3 5854359Sroberto * 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 5954359Sroberto * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6054359Sroberto * | Integer Part | Fraction Part | 6154359Sroberto * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 6254359Sroberto * 6354359Sroberto */ 6454359Srobertotypedef int32 s_fp; 6554359Srobertotypedef u_int32 u_fp; 6654359Sroberto 6754359Sroberto/* 68285612Sdelphij * A unit second in fp format. Actually 2**(half_the_bits_in_a_long) 6954359Sroberto */ 7054359Sroberto#define FP_SECOND (0x10000) 7154359Sroberto 7254359Sroberto/* 7354359Sroberto * Byte order conversions 7454359Sroberto */ 7554359Sroberto#define HTONS_FP(x) (htonl(x)) 7654359Sroberto#define NTOHS_FP(x) (ntohl(x)) 7754359Sroberto 78285612Sdelphij#define NTOHL_MFP(ni, nf, hi, hf) \ 79285612Sdelphij do { \ 80285612Sdelphij (hi) = ntohl(ni); \ 81285612Sdelphij (hf) = ntohl(nf); \ 82285612Sdelphij } while (FALSE) 8354359Sroberto 84285612Sdelphij#define HTONL_MFP(hi, hf, ni, nf) \ 85285612Sdelphij do { \ 86285612Sdelphij (ni) = htonl(hi); \ 87285612Sdelphij (nf) = htonl(hf); \ 88285612Sdelphij } while (FALSE) 89285612Sdelphij 90285612Sdelphij#define HTONL_FP(h, n) \ 91285612Sdelphij HTONL_MFP((h)->l_ui, (h)->l_uf, (n)->l_ui, (n)->l_uf) 92285612Sdelphij 93285612Sdelphij#define NTOHL_FP(n, h) \ 94285612Sdelphij NTOHL_MFP((n)->l_ui, (n)->l_uf, (h)->l_ui, (h)->l_uf) 95285612Sdelphij 96285612Sdelphij/* Convert unsigned ts fraction to net order ts */ 97285612Sdelphij#define HTONL_UF(uf, nts) \ 98285612Sdelphij do { \ 99285612Sdelphij (nts)->l_ui = 0; \ 100285612Sdelphij (nts)->l_uf = htonl(uf); \ 101285612Sdelphij } while (FALSE) 102285612Sdelphij 10354359Sroberto/* 10454359Sroberto * Conversions between the two fixed point types 10554359Sroberto */ 10654359Sroberto#define MFPTOFP(x_i, x_f) (((x_i) >= 0x00010000) ? 0x7fffffff : \ 10754359Sroberto (((x_i) <= -0x00010000) ? 0x80000000 : \ 10854359Sroberto (((x_i)<<16) | (((x_f)>>16)&0xffff)))) 109285612Sdelphij#define LFPTOFP(v) MFPTOFP((v)->l_i, (v)->l_uf) 11054359Sroberto 11154359Sroberto#define UFPTOLFP(x, v) ((v)->l_ui = (u_fp)(x)>>16, (v)->l_uf = (x)<<16) 11254359Sroberto#define FPTOLFP(x, v) (UFPTOLFP((x), (v)), (x) < 0 ? (v)->l_ui -= 0x10000 : 0) 11354359Sroberto 114285612Sdelphij#define MAXLFP(v) ((v)->l_ui = 0x7fffffffu, (v)->l_uf = 0xffffffffu) 115285612Sdelphij#define MINLFP(v) ((v)->l_ui = 0x80000000u, (v)->l_uf = 0u) 11654359Sroberto 11754359Sroberto/* 11854359Sroberto * Primitive operations on long fixed point values. If these are 11954359Sroberto * reminiscent of assembler op codes it's only because some may 12054359Sroberto * be replaced by inline assembler for particular machines someday. 12154359Sroberto * These are the (kind of inefficient) run-anywhere versions. 12254359Sroberto */ 123285612Sdelphij#define M_NEG(v_i, v_f) /* v = -v */ \ 12454359Sroberto do { \ 125285612Sdelphij (v_f) = ~(v_f) + 1u; \ 126285612Sdelphij (v_i) = ~(v_i) + ((v_f) == 0); \ 127285612Sdelphij } while (FALSE) 12854359Sroberto 129285612Sdelphij#define M_NEGM(r_i, r_f, a_i, a_f) /* r = -a */ \ 13054359Sroberto do { \ 131285612Sdelphij (r_f) = ~(a_f) + 1u; \ 132285612Sdelphij (r_i) = ~(a_i) + ((r_f) == 0); \ 133285612Sdelphij } while (FALSE) 13454359Sroberto 135285612Sdelphij#define M_ADD(r_i, r_f, a_i, a_f) /* r += a */ \ 13654359Sroberto do { \ 137285612Sdelphij u_int32 add_t = (r_f); \ 138285612Sdelphij (r_f) += (a_f); \ 139285612Sdelphij (r_i) += (a_i) + ((u_int32)(r_f) < add_t); \ 140285612Sdelphij } while (FALSE) 14154359Sroberto 142285612Sdelphij#define M_ADD3(r_o, r_i, r_f, a_o, a_i, a_f) /* r += a, three word */ \ 14354359Sroberto do { \ 144285612Sdelphij u_int32 add_t, add_c; \ 145285612Sdelphij add_t = (r_f); \ 146285612Sdelphij (r_f) += (a_f); \ 147285612Sdelphij add_c = ((u_int32)(r_f) < add_t); \ 148285612Sdelphij (r_i) += add_c; \ 149285612Sdelphij add_c = ((u_int32)(r_i) < add_c); \ 150285612Sdelphij add_t = (r_i); \ 151285612Sdelphij (r_i) += (a_i); \ 152285612Sdelphij add_c |= ((u_int32)(r_i) < add_t); \ 153285612Sdelphij (r_o) += (a_o) + add_c; \ 154285612Sdelphij } while (FALSE) 15554359Sroberto 15654359Sroberto#define M_SUB(r_i, r_f, a_i, a_f) /* r -= a */ \ 15754359Sroberto do { \ 158285612Sdelphij u_int32 sub_t = (r_f); \ 159285612Sdelphij (r_f) -= (a_f); \ 160285612Sdelphij (r_i) -= (a_i) + ((u_int32)(r_f) > sub_t); \ 161285612Sdelphij } while (FALSE) 16254359Sroberto 16354359Sroberto#define M_RSHIFTU(v_i, v_f) /* v >>= 1, v is unsigned */ \ 16454359Sroberto do { \ 165285612Sdelphij (v_f) = ((u_int32)(v_f) >> 1) | ((u_int32)(v_i) << 31); \ 166285612Sdelphij (v_i) = ((u_int32)(v_i) >> 1); \ 167285612Sdelphij } while (FALSE) 16854359Sroberto 16954359Sroberto#define M_RSHIFT(v_i, v_f) /* v >>= 1, v is signed */ \ 17054359Sroberto do { \ 171285612Sdelphij (v_f) = ((u_int32)(v_f) >> 1) | ((u_int32)(v_i) << 31); \ 172285612Sdelphij (v_i) = ((u_int32)(v_i) >> 1) | ((u_int32)(v_i) & 0x80000000); \ 173285612Sdelphij } while (FALSE) 17454359Sroberto 17554359Sroberto#define M_LSHIFT(v_i, v_f) /* v <<= 1 */ \ 17654359Sroberto do { \ 177285612Sdelphij (v_i) = ((u_int32)(v_i) << 1) | ((u_int32)(v_f) >> 31); \ 178285612Sdelphij (v_f) = ((u_int32)(v_f) << 1); \ 179285612Sdelphij } while (FALSE) 18054359Sroberto 181285612Sdelphij#define M_LSHIFT3(v_o, v_i, v_f) /* v <<= 1, with overflow */ \ 18254359Sroberto do { \ 183285612Sdelphij (v_o) = ((u_int32)(v_o) << 1) | ((u_int32)(v_i) >> 31); \ 184285612Sdelphij (v_i) = ((u_int32)(v_i) << 1) | ((u_int32)(v_f) >> 31); \ 185285612Sdelphij (v_f) = ((u_int32)(v_f) << 1); \ 186285612Sdelphij } while (FALSE) 18754359Sroberto 188285612Sdelphij#define M_ADDUF(r_i, r_f, uf) /* r += uf, uf is u_int32 fraction */ \ 18954359Sroberto M_ADD((r_i), (r_f), 0, (uf)) /* let optimizer worry about it */ 19054359Sroberto 19154359Sroberto#define M_SUBUF(r_i, r_f, uf) /* r -= uf, uf is u_int32 fraction */ \ 19254359Sroberto M_SUB((r_i), (r_f), 0, (uf)) /* let optimizer worry about it */ 19354359Sroberto 19454359Sroberto#define M_ADDF(r_i, r_f, f) /* r += f, f is a int32 fraction */ \ 19554359Sroberto do { \ 196285612Sdelphij int32 add_f = (int32)(f); \ 197285612Sdelphij if (add_f >= 0) \ 198285612Sdelphij M_ADD((r_i), (r_f), 0, (uint32)( add_f)); \ 199285612Sdelphij else \ 200285612Sdelphij M_SUB((r_i), (r_f), 0, (uint32)(-add_f)); \ 20154359Sroberto } while(0) 20254359Sroberto 203285612Sdelphij#define M_ISNEG(v_i) /* v < 0 */ \ 20454359Sroberto (((v_i) & 0x80000000) != 0) 20554359Sroberto 206285612Sdelphij#define M_ISGT(a_i, a_f, b_i, b_f) /* a > b signed */ \ 207285612Sdelphij (((u_int32)((a_i) ^ 0x80000000) > (u_int32)((b_i) ^ 0x80000000)) || \ 208285612Sdelphij ((a_i) == (b_i) && ((u_int32)(a_f)) > ((u_int32)(b_f)))) 209285612Sdelphij 210285612Sdelphij#define M_ISGTU(a_i, a_f, b_i, b_f) /* a > b unsigned */ \ 211285612Sdelphij (((u_int32)(a_i)) > ((u_int32)(b_i)) || \ 212285612Sdelphij ((a_i) == (b_i) && ((u_int32)(a_f)) > ((u_int32)(b_f)))) 213285612Sdelphij 21454359Sroberto#define M_ISHIS(a_i, a_f, b_i, b_f) /* a >= b unsigned */ \ 21554359Sroberto (((u_int32)(a_i)) > ((u_int32)(b_i)) || \ 21654359Sroberto ((a_i) == (b_i) && ((u_int32)(a_f)) >= ((u_int32)(b_f)))) 21754359Sroberto 21854359Sroberto#define M_ISGEQ(a_i, a_f, b_i, b_f) /* a >= b signed */ \ 219285612Sdelphij (((u_int32)((a_i) ^ 0x80000000) > (u_int32)((b_i) ^ 0x80000000)) || \ 220285612Sdelphij ((a_i) == (b_i) && (u_int32)(a_f) >= (u_int32)(b_f))) 22154359Sroberto 22254359Sroberto#define M_ISEQU(a_i, a_f, b_i, b_f) /* a == b unsigned */ \ 223285612Sdelphij ((u_int32)(a_i) == (u_int32)(b_i) && (u_int32)(a_f) == (u_int32)(b_f)) 22454359Sroberto 22554359Sroberto/* 22654359Sroberto * Operations on the long fp format 22754359Sroberto */ 22854359Sroberto#define L_ADD(r, a) M_ADD((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf) 22954359Sroberto#define L_SUB(r, a) M_SUB((r)->l_ui, (r)->l_uf, (a)->l_ui, (a)->l_uf) 23054359Sroberto#define L_NEG(v) M_NEG((v)->l_ui, (v)->l_uf) 23154359Sroberto#define L_ADDUF(r, uf) M_ADDUF((r)->l_ui, (r)->l_uf, (uf)) 23254359Sroberto#define L_SUBUF(r, uf) M_SUBUF((r)->l_ui, (r)->l_uf, (uf)) 23354359Sroberto#define L_ADDF(r, f) M_ADDF((r)->l_ui, (r)->l_uf, (f)) 23454359Sroberto#define L_RSHIFT(v) M_RSHIFT((v)->l_i, (v)->l_uf) 235182007Sroberto#define L_RSHIFTU(v) M_RSHIFTU((v)->l_ui, (v)->l_uf) 23654359Sroberto#define L_LSHIFT(v) M_LSHIFT((v)->l_ui, (v)->l_uf) 23754359Sroberto#define L_CLR(v) ((v)->l_ui = (v)->l_uf = 0) 23854359Sroberto 239285612Sdelphij#define L_ISNEG(v) M_ISNEG((v)->l_ui) 240285612Sdelphij#define L_ISZERO(v) (((v)->l_ui | (v)->l_uf) == 0) 241285612Sdelphij#define L_ISGT(a, b) M_ISGT((a)->l_i, (a)->l_uf, (b)->l_i, (b)->l_uf) 242285612Sdelphij#define L_ISGTU(a, b) M_ISGTU((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf) 243285612Sdelphij#define L_ISHIS(a, b) M_ISHIS((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf) 244285612Sdelphij#define L_ISGEQ(a, b) M_ISGEQ((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf) 24554359Sroberto#define L_ISEQU(a, b) M_ISEQU((a)->l_ui, (a)->l_uf, (b)->l_ui, (b)->l_uf) 24654359Sroberto 24754359Sroberto/* 24854359Sroberto * s_fp/double and u_fp/double conversions 24954359Sroberto */ 250285612Sdelphij#define FRIC 65536.0 /* 2^16 as a double */ 25154359Sroberto#define DTOFP(r) ((s_fp)((r) * FRIC)) 25254359Sroberto#define DTOUFP(r) ((u_fp)((r) * FRIC)) 25354359Sroberto#define FPTOD(r) ((double)(r) / FRIC) 25454359Sroberto 25554359Sroberto/* 25654359Sroberto * l_fp/double conversions 25754359Sroberto */ 258285612Sdelphij#define FRAC 4294967296.0 /* 2^32 as a double */ 259285612Sdelphij 260285612Sdelphij/* 261285612Sdelphij * Use 64 bit integers if available. Solaris on SPARC has a problem 262285612Sdelphij * compiling parsesolaris.c if ntp_fp.h includes math.h, due to 263285612Sdelphij * archaic gets() and printf() prototypes used in Solaris kernel 264285612Sdelphij * headers. So far the problem has only been seen with gcc, but it 265285612Sdelphij * may also affect Sun compilers, in which case the defined(__GNUC__) 266285612Sdelphij * term should be removed. 267285612Sdelphij * XSCALE also generates bad code for these, at least with GCC 3.3.5. 268285612Sdelphij * This is unrelated to math.h, but the same solution applies. 269285612Sdelphij */ 270285612Sdelphij#if defined(HAVE_U_INT64) && \ 271285612Sdelphij !(defined(__SVR4) && defined(__sun) && \ 272285612Sdelphij defined(sparc) && defined(__GNUC__) || \ 273285612Sdelphij defined(__arm__) && defined(__XSCALE__) && defined(__GNUC__)) 274285612Sdelphij 275285612Sdelphij#include <math.h> /* ldexp() */ 276285612Sdelphij 277285612Sdelphij#define M_DTOLFP(d, r_ui, r_uf) /* double to l_fp */ \ 278285612Sdelphij do { \ 279285612Sdelphij double d_tmp; \ 280285612Sdelphij u_int64 q_tmp; \ 281285612Sdelphij int M_isneg; \ 282285612Sdelphij \ 283285612Sdelphij d_tmp = (d); \ 284285612Sdelphij M_isneg = (d_tmp < 0.); \ 285285612Sdelphij if (M_isneg) { \ 286285612Sdelphij d_tmp = -d_tmp; \ 287285612Sdelphij } \ 288285612Sdelphij q_tmp = (u_int64)ldexp(d_tmp, 32); \ 289285612Sdelphij if (M_isneg) { \ 290285612Sdelphij q_tmp = ~q_tmp + 1; \ 291285612Sdelphij } \ 292285612Sdelphij (r_uf) = (u_int32)q_tmp; \ 293285612Sdelphij (r_ui) = (u_int32)(q_tmp >> 32); \ 294285612Sdelphij } while (FALSE) 295285612Sdelphij 296285612Sdelphij#define M_LFPTOD(r_ui, r_uf, d) /* l_fp to double */ \ 297285612Sdelphij do { \ 298285612Sdelphij double d_tmp; \ 299285612Sdelphij u_int64 q_tmp; \ 300285612Sdelphij int M_isneg; \ 301285612Sdelphij \ 302285612Sdelphij q_tmp = ((u_int64)(r_ui) << 32) + (r_uf); \ 303285612Sdelphij M_isneg = M_ISNEG(r_ui); \ 304285612Sdelphij if (M_isneg) { \ 305285612Sdelphij q_tmp = ~q_tmp + 1; \ 306285612Sdelphij } \ 307285612Sdelphij d_tmp = ldexp((double)q_tmp, -32); \ 308285612Sdelphij if (M_isneg) { \ 309285612Sdelphij d_tmp = -d_tmp; \ 310285612Sdelphij } \ 311285612Sdelphij (d) = d_tmp; \ 312285612Sdelphij } while (FALSE) 313285612Sdelphij 314285612Sdelphij#else /* use only 32 bit unsigned values */ 315285612Sdelphij 316285612Sdelphij#define M_DTOLFP(d, r_ui, r_uf) /* double to l_fp */ \ 31754359Sroberto do { \ 318285612Sdelphij double d_tmp; \ 319285612Sdelphij if ((d_tmp = (d)) < 0) { \ 320285612Sdelphij (r_ui) = (u_int32)(-d_tmp); \ 321285612Sdelphij (r_uf) = (u_int32)(-(d_tmp + (double)(r_ui)) * FRAC); \ 322285612Sdelphij M_NEG((r_ui), (r_uf)); \ 32354359Sroberto } else { \ 324285612Sdelphij (r_ui) = (u_int32)d_tmp; \ 325285612Sdelphij (r_uf) = (u_int32)((d_tmp - (double)(r_ui)) * FRAC); \ 32654359Sroberto } \ 32754359Sroberto } while (0) 328285612Sdelphij#define M_LFPTOD(r_ui, r_uf, d) /* l_fp to double */ \ 32954359Sroberto do { \ 330285612Sdelphij u_int32 l_thi, l_tlo; \ 331285612Sdelphij l_thi = (r_ui); l_tlo = (r_uf); \ 332285612Sdelphij if (M_ISNEG(l_thi)) { \ 333285612Sdelphij M_NEG(l_thi, l_tlo); \ 334285612Sdelphij (d) = -((double)l_thi + (double)l_tlo / FRAC); \ 33554359Sroberto } else { \ 336285612Sdelphij (d) = (double)l_thi + (double)l_tlo / FRAC; \ 33754359Sroberto } \ 33854359Sroberto } while (0) 339285612Sdelphij#endif 340285612Sdelphij 34154359Sroberto#define DTOLFP(d, v) M_DTOLFP((d), (v)->l_ui, (v)->l_uf) 34254359Sroberto#define LFPTOD(v, d) M_LFPTOD((v)->l_ui, (v)->l_uf, (d)) 34354359Sroberto 34454359Sroberto/* 34554359Sroberto * Prototypes 34654359Sroberto */ 347285612Sdelphijextern char * dofptoa (u_fp, int, short, int); 348285612Sdelphijextern char * dolfptoa (u_int32, u_int32, int, short, int); 34954359Sroberto 350285612Sdelphijextern int atolfp (const char *, l_fp *); 351285612Sdelphijextern int buftvtots (const char *, l_fp *); 352285612Sdelphijextern char * fptoa (s_fp, short); 353285612Sdelphijextern char * fptoms (s_fp, short); 354285612Sdelphijextern int hextolfp (const char *, l_fp *); 355316722Sdelphijextern void gpstolfp (u_int, u_int, unsigned long, l_fp *); 356285612Sdelphijextern int mstolfp (const char *, l_fp *); 357285612Sdelphijextern char * prettydate (l_fp *); 358285612Sdelphijextern char * gmprettydate (l_fp *); 359285612Sdelphijextern char * uglydate (l_fp *); 360285612Sdelphijextern void mfp_mul (int32 *, u_int32 *, int32, u_int32, int32, u_int32); 36154359Sroberto 362285612Sdelphijextern void set_sys_fuzz (double); 363285612Sdelphijextern void init_systime (void); 364285612Sdelphijextern void get_systime (l_fp *); 365285612Sdelphijextern int step_systime (double); 366285612Sdelphijextern int adj_systime (double); 367330567Sgordonextern int clamp_systime (void); 36854359Sroberto 369285612Sdelphijextern struct tm * ntp2unix_tm (u_int32 ntp, int local); 370182007Sroberto 371285612Sdelphij#define lfptoa(fpv, ndec) mfptoa((fpv)->l_ui, (fpv)->l_uf, (ndec)) 372285612Sdelphij#define lfptoms(fpv, ndec) mfptoms((fpv)->l_ui, (fpv)->l_uf, (ndec)) 37354359Sroberto 374285612Sdelphij#define stoa(addr) socktoa(addr) 375285612Sdelphij#define ntoa(addr) stoa(addr) 376285612Sdelphij#define sptoa(addr) sockporttoa(addr) 377285612Sdelphij#define stohost(addr) socktohost(addr) 37854359Sroberto 379285612Sdelphij#define ufptoa(fpv, ndec) dofptoa((fpv), 0, (ndec), 0) 380285612Sdelphij#define ufptoms(fpv, ndec) dofptoa((fpv), 0, (ndec), 1) 381285612Sdelphij#define ulfptoa(fpv, ndec) dolfptoa((fpv)->l_ui, (fpv)->l_uf, 0, (ndec), 0) 382285612Sdelphij#define ulfptoms(fpv, ndec) dolfptoa((fpv)->l_ui, (fpv)->l_uf, 0, (ndec), 1) 383285612Sdelphij#define umfptoa(fpi, fpf, ndec) dolfptoa((fpi), (fpf), 0, (ndec), 0) 384132451Sroberto 385285612Sdelphij/* 386285612Sdelphij * Optional callback from libntp step_systime() to ntpd. Optional 387285612Sdelphij* because other libntp clients like ntpdate don't use it. 388285612Sdelphij */ 389285612Sdelphijtypedef void (*time_stepped_callback)(void); 390285612Sdelphijextern time_stepped_callback step_callback; 39154359Sroberto 392285612Sdelphij/* 393285612Sdelphij * Multi-thread locking for get_systime() 394285612Sdelphij * 395285612Sdelphij * On most systems, get_systime() is used solely by the main ntpd 396285612Sdelphij * thread, but on Windows it's also used by the dedicated I/O thread. 397285612Sdelphij * The [Bug 2037] changes to get_systime() have it keep state between 398285612Sdelphij * calls to ensure time moves in only one direction, which means its 399285612Sdelphij * use on Windows needs to be protected against simultaneous execution 400285612Sdelphij * to avoid falsely detecting Lamport violations by ensuring only one 401285612Sdelphij * thread at a time is in get_systime(). 402285612Sdelphij */ 403285612Sdelphij#ifdef SYS_WINNT 404285612Sdelphijextern CRITICAL_SECTION get_systime_cs; 405285612Sdelphij# define INIT_GET_SYSTIME_CRITSEC() \ 406285612Sdelphij InitializeCriticalSection(&get_systime_cs) 407285612Sdelphij# define ENTER_GET_SYSTIME_CRITSEC() \ 408285612Sdelphij EnterCriticalSection(&get_systime_cs) 409285612Sdelphij# define LEAVE_GET_SYSTIME_CRITSEC() \ 410285612Sdelphij LeaveCriticalSection(&get_systime_cs) 411285612Sdelphij# define INIT_WIN_PRECISE_TIME() \ 412285612Sdelphij init_win_precise_time() 413285612Sdelphij#else /* !SYS_WINNT follows */ 414285612Sdelphij# define INIT_GET_SYSTIME_CRITSEC() \ 415285612Sdelphij do {} while (FALSE) 416285612Sdelphij# define ENTER_GET_SYSTIME_CRITSEC() \ 417285612Sdelphij do {} while (FALSE) 418285612Sdelphij# define LEAVE_GET_SYSTIME_CRITSEC() \ 419285612Sdelphij do {} while (FALSE) 420285612Sdelphij# define INIT_WIN_PRECISE_TIME() \ 421285612Sdelphij do {} while (FALSE) 422285612Sdelphij#endif 423285612Sdelphij 42454359Sroberto#endif /* NTP_FP_H */ 425