On Tue, Feb 21, 2017 at 05:48:19PM +0100, walter harms wrote:
> > 
>       
> XSyncValueSubtract is doing as expected,
> XSyncValue is the simulation of 64bitvalues on 32bit.
> see this in hex:
>  100000001
> -000000002
>  0FFFFFFFF = 4294967295 in .lo
> 

Kind of - it errorneously returns

 1 0000 0001
-0 0000 0002
 1 ffff ffff

Test source attached.

I.e.
  XSyncValueSubtract should handle the .lo becoming <0,
  and it checks only for .lo_after_subtract < .lo,
  which would only be aplicable to uint.

E.g. there is a typo in XSyncValue.lo definition - it should be uint
instead.
Also in ServertimeBlockHandler, "timeout" is unsigned,
while it is get from signed .lo and used as signed arg to
AdjustWaitForTimeout.

Perhaps also:
  AdjustWaitForTimeout should not be used if overflow != 0
  Because something is wrong then as (pnext_time < Now) ?

Mihail
#include <stdio.h>
#include <stdint.h>

typedef int Bool;

struct xtime {
	int32_t hi;
	int32_t lo;
};

struct utime {
	int32_t hi;
	uint32_t lo; /* uint vs. int doesn't seem to matter, in XSyncValueSubtract too */
};

void print_xtime(char *comment, struct xtime *x, Bool in_hex) {
	printf("%s: { hi=%d lo=%d }\n", comment, x->hi, x->lo);
	if (in_hex) {
	  printf("%s: { hi=%x lo=%x }\n", comment, x->hi, x->lo);
	}
}

void print_utime(char *comment, struct utime *x, Bool in_hex) {
	printf("%s: { hi=%d lo=%u }\n", comment, x->hi, x->lo);
	if (in_hex) {
	  printf("%s: { hi=%x lo=%x }\n", comment, x->hi, x->lo);
	}
}

void set_xtime(struct xtime *x, int hi, int lo) {
	x->hi = hi;
	x->lo = lo;
}

void set_utime(struct utime *x, int hi, int lo) {
	x->hi = hi;
	x->lo = lo;
}

#define XSyncValueIsNegative(v) (((v).hi & 0x80000000) ? 1 : 0)

#define _XSyncValueSubtract(presult,a,b,poverflow) {\
	int t = (a).lo;\
	Bool signa = XSyncValueIsNegative(a);\
	Bool signb = XSyncValueIsNegative(b);\
	((presult)->lo = (a).lo - (b).lo);\
	((presult)->hi = (a).hi - (b).hi);\
	if (t<(presult)->lo) (presult)->hi--;\
	*poverflow = ((signa == signb) && !(signa == XSyncValueIsNegative(*presult)));\
     }

#define FixedXSyncValueSubtract(presult,a,b,poverflow) {\
	uint32_t t = (a).lo;\
	Bool signa = XSyncValueIsNegative(a);\
	Bool signb = XSyncValueIsNegative(b);\
	((presult)->lo = (a).lo - (b).lo);\
	((presult)->hi = (a).hi - (b).hi);\
	if (t<(presult)->lo || (presult)->lo < 0) (presult)->hi--;\
	*poverflow = ((signa == signb) && !(signa == XSyncValueIsNegative(*presult)));\
     }

void test_subtract(int a_hi, int a_lo, int b_hi, int b_lo) {
	int overflow;
	struct xtime d, a, b;
	struct utime ud, ua, ub;

	set_xtime(&a, a_hi, a_lo);
	set_xtime(&b, b_hi, b_lo);

	print_xtime("a", &a, 0);
	print_xtime("b", &b, 0);
	_XSyncValueSubtract(&d, a, b, &overflow);
	print_xtime("a-b", &d, 1);
	printf("a-b overflow: %c\n", (overflow ? 'y' : 'n'));

	set_utime(&ua, a_hi, a_lo);
	set_utime(&ub, b_hi, b_lo);
	
	FixedXSyncValueSubtract(&ud, ua, ub, &overflow);
	print_utime("fixed a-b", &ud, 1);
	printf("fixed a-b overflow: %c\n", (overflow ? 'y' : 'n'));

	printf("\n");
}

int main(int argc, char **argv) {
	test_subtract(2, 2, 1, 4);
	test_subtract(2, 2, 4, 0);
	test_subtract(1, 1, 0, 2);
	return 0;
}
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to