code: mafs

ref: c947228f7cf50bbbeb3f1e1b1808280e9ae9247f
dir: /tests/sizes.c/

View raw version
#include <u.h>
#include <libc.h>
#include "../dat.h"

static uvlong
adduvlongov(uvlong a, uvlong b)
{
	uvlong r = a + b;

	if (r < a || r < b)
		return 0;
	return r;
}

static uvlong
muluvlongov(uvlong a, uvlong b)
{
	uvlong r = a * b;

	if (a != 0 && r/a != b || r < a || r < b)
		return 0;
	return r;
}

static uvlong
maxsize1(void)
{
	int i;
	uvlong max = Ndspanid, ind = 1;

	for (i = 0; i < Niblock; i++) {
		ind = muluvlongov(ind, Nindperblock);	/* power of Nindperblock */
		if (ind == 0)
			return 0;
		max = adduvlongov(max, ind);
		print("maxsize %d %llud max %llud\n", i, ind, max);
		if (max == 0)
			return 0;
	}
	return muluvlongov(max, Blocksize);
}

/* could use muluvlongov() here but it does not add any value for us
	raise base to n-th power; n >= 0
 */
u64
power( u64 base, int n)
{
	int i;
	u64 v;

	v = 1;
	for(i = 1; i <= n; i++){
		v = v*base;
	}
	return v;
}

/* Each u64 address in this indirect block links to n Tdata/Tdentry blocks */
u64
nperindunit(u16 tag)
{
	if(tag < Tind0 || tag > Tmaxind+1)
		return 0;

	if(tag == Tind0)
		return 1;
	return Nspanidperblock*power(Blocksize/sizeof(u64), tag-Tind1);
}

/* extern double pow(double x, double y); *//* return x ^ y (exponentiation) */
/* Each u64 address in the indirect block links to n Tdata/Tdentry blocks */
u64
nperiblock(u16 tag)
{
	return nperindunit(tag+1);
}

static uvlong
maxsize(void)
{
	int i;
	uvlong max = Ndspanid, ind;

	print("maxsize direct spans max %llud\n", max);
	for (i = 0; i < Niblock; i++) {
		ind = nperiblock(Tind0+i);
		max += ind;
		print("maxsize %s %llud max %llud\n", tagnames[Tind0+i], ind, max);
	}
	return max;
}

void
main(int, void**)
{
	int i;
	u64 spans, max;

	print("Namelen %d Ndspanid %d Niblock %d\n", Namelen, Ndspanid, Niblock);
	print("Blocksize %d Nspanidperblock %d Nindperblock %d\n",
			Blocksize, Nspanidperblock, Nindperblock);
	print("Maxspanlen %llud Maxspansize %llud\n",
			Maxspanlen, Maxspansize);

	spans = nperindunit(Tind0);
	print("A %s unit points to %lld data spans (%llud bytes)\n",
			 tagnames[Tind0], spans, spans*Maxspansize);
	print("	block points to %lld data spans\n", nperiblock(Tind0));
	for (i = Tind1; i < Maxtind; i++) {
		spans = nperindunit(i);
		print("A %s unit points to %lld data spans (%llud bytes)\n",
			 tagnames[i], spans, spans*Maxspansize);
		print("	block points to %lld data spans\n", nperiblock(i));
	}
	print("sizeof(Dentry1) %d Namelen %d\n",
			sizeof(Dentry1), Namelen);
	max = maxsize();
	print("maximum possible spans %llud\n", max);
	print("	(%llud*Maxspansize = %llud bytes)\n", max, max*Maxspansize);
	print("	(%llud*Maxspansize = %llud bytes = %llud TiB)\n",
			max, max*Maxspansize, (max*Maxspansize)/(MiB*MiB));
	exits(0);
}