arith.c 1.27 KB
Newer Older
1
/*
2 3
 * Copyright (C) 2011 CERN (www.cern.ch)
 * Author: Aurelio Colosimo
4
 * Based on PTPd project v. 2.1.0 (see AUTHORS for details)
5 6
 *
 * Released according to the GNU LGPL, version 2.1 or any later version.
7 8
 */

9
#include <limits.h>
Alessandro Rubini's avatar
Alessandro Rubini committed
10
#include <ppsi/ppsi.h>
11

12
void normalize_pp_time(struct pp_time *t)
13
{
14 15 16
	/* no 64b division please, we'll rather loop a few times */
	#define SNS_PER_S ((1000LL * 1000 * 1000) << 16)

17 18
	int sign = (t->secs < 0 || (t->secs == 0 && t->scaled_nsecs < 0))
		? -1 : 1;
19

20 21 22
	/* turn into positive, to make code shorter (don't replicate loops) */
	t->secs *= sign;
	t->scaled_nsecs *= sign;
23

24 25 26
	while (t->scaled_nsecs < 0) {
		t->secs--;
		t->scaled_nsecs += SNS_PER_S;
27
	}
28 29 30
	while (t->scaled_nsecs > SNS_PER_S) {
		t->secs++;
		t->scaled_nsecs -= SNS_PER_S;
31
	}
32 33
	t->secs *= sign;
	t->scaled_nsecs *= sign;
34 35
}

36
void pp_time_add(struct pp_time *t1, struct pp_time *t2)
37
{
38 39 40
	t1->secs += t2->secs;
	t1->scaled_nsecs += t2->scaled_nsecs;
	normalize_pp_time(t1);
41 42
}

43
void pp_time_sub(struct pp_time *t1, struct pp_time *t2)
44
{
45 46 47
	t1->secs -= t2->secs;
	t1->scaled_nsecs -= t2->scaled_nsecs;
	normalize_pp_time(t1);
48
}
49

50
void pp_time_div2(struct pp_time *t)
51
{
52
	int sign = (t->secs < 0) ? -1 : 1;
53

54 55 56 57
	t->scaled_nsecs >>= 1;
	if (t->secs &1)
		t->scaled_nsecs += sign * SNS_PER_S / 2;
	t->secs >>= 1;
58
}