
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define SLAB_FREELIST_COUNT 9

int main(int argc, char **argv)
{
	clock_t start, end;
	double v1_time, v2_time;
	int freecount;
	int freelist_shift = 0;
	int chunksPerBlock;
	int index;
	int zerocount = 0;
	
	if (argc < 2)
	{
		printf("Syntax: %s <chunksPerBlock>\n", argv[0]);
		return -1;
	}
	
	chunksPerBlock = atoi(argv[1]);
	printf("chunksPerBlock = %d\n", chunksPerBlock);
	
	while ((chunksPerBlock >> freelist_shift) >= (SLAB_FREELIST_COUNT - 1))
		freelist_shift++;
	printf("freelist_shift = %d\n", freelist_shift);
	
	start = clock();
	
	for (freecount = 0; freecount <= chunksPerBlock; freecount++)
	{
		index = (freecount + (1 << freelist_shift) - 1) >> freelist_shift;
		
		/* try to prevent optimizing the above out */
		if (index == 0)
			zerocount++;
	}
	
	
	end = clock();
	v1_time = (double) (end - start) / CLOCKS_PER_SEC;
	printf("Test 'a' in %f seconds\n", v1_time);
	printf("zerocount = %d\n", zerocount);
	
	zerocount = 0;
	start = clock();

	for (freecount = 0; freecount <= chunksPerBlock; freecount++)
	{
		index = -(-freecount >> freelist_shift);

		/* try to prevent optimizing the above out */
		if (index == 0)
			zerocount++;
		
	}

	end = clock();
	v2_time = (double) (end - start) / CLOCKS_PER_SEC;
	printf("Test 'd' in %f seconds (%f%% faster)\n", v2_time, v1_time / v2_time * 100.0 - 100.0);
	printf("zerocount = %d\n", zerocount);
	return 0;
}