#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stdint.h>

int main(int argc, char **argv){
	uint32_t NR_CPUS = atoi(argv[1]);
	uint32_t RCU_FANOUT = atoi(argv[2]);
	uint32_t RCU_FANOUT_LEAF = atoi(argv[3]);
	uint32_t RCU_FANOUT_1 = 0;
	uint32_t RCU_FANOUT_2 = 0;
	uint32_t RCU_FANOUT_3 = 0;
	uint32_t RCU_FANOUT_4 = 0;
	uint32_t RCU_NUM_LVLS = 0;
	uint32_t NUM_RCU_LVL_0 = 0;
	uint32_t NUM_RCU_LVL_1 = 0;
	uint32_t NUM_RCU_LVL_2 = 0;
	uint32_t NUM_RCU_LVL_3 = 0;
	uint32_t NUM_RCU_NODES = 0;


	RCU_FANOUT_1 = RCU_FANOUT_LEAF;
	RCU_FANOUT_2 = RCU_FANOUT_1 * RCU_FANOUT;
	RCU_FANOUT_3 = RCU_FANOUT_2 * RCU_FANOUT;
	RCU_FANOUT_4 = RCU_FANOUT_3 * RCU_FANOUT;

	if(NR_CPUS <= RCU_FANOUT_1){
		RCU_NUM_LVLS = 1;
		NUM_RCU_LVL_0 = 1;
		NUM_RCU_NODES = NUM_RCU_LVL_0;
	}else if(NR_CPUS <= RCU_FANOUT_2){
		RCU_NUM_LVLS = 2;
		NUM_RCU_LVL_0 = 1;
		NUM_RCU_LVL_1 = (uint32_t)ceil((double)NR_CPUS/RCU_FANOUT_1);
		NUM_RCU_NODES = (NUM_RCU_LVL_0 + NUM_RCU_LVL_1);
	}else if(NR_CPUS <= RCU_FANOUT_3){
		RCU_NUM_LVLS = 3;
		NUM_RCU_LVL_0 = 1;
		NUM_RCU_LVL_1 = (uint32_t)ceil((double)NR_CPUS/RCU_FANOUT_2);
		NUM_RCU_LVL_2 = (uint32_t)ceil((double)NR_CPUS/RCU_FANOUT_1);
		NUM_RCU_NODES = (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2);
	}else if(NR_CPUS <= RCU_FANOUT_4){
		RCU_NUM_LVLS = 4;
		NUM_RCU_LVL_0 = 1;
		NUM_RCU_LVL_1 = (uint32_t)ceil((double)NR_CPUS/RCU_FANOUT_3);
		NUM_RCU_LVL_2 = (uint32_t)ceil((double)NR_CPUS/RCU_FANOUT_2);
		NUM_RCU_LVL_3 = (uint32_t)ceil((double)NR_CPUS/RCU_FANOUT_1);
		NUM_RCU_NODES = (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3);
	}else{
		printf("error: CONFIG_RCU_FANOUT insufficient for NR_CPUS\n");
	}

	printf("NR_CPUS: %u\n", NR_CPUS);
	printf("RCU_FANOUT: %u\n", RCU_FANOUT);
	printf("RCU_FANOUT_LEAF: %u\n", RCU_FANOUT_LEAF);
	printf("RCU_FANOUT_1: %u\n", RCU_FANOUT_1);
	printf("RCU_FANOUT_2: %u\n", RCU_FANOUT_2);
	printf("RCU_FANOUT_3: %u\n", RCU_FANOUT_3);
	printf("RCU_FANOUT_4: %u\n", RCU_FANOUT_4);
	printf("RCU_NUM_LVLS: %u\n", RCU_NUM_LVLS);
	printf("NUM_RCU_LVL_0: %u\n", NUM_RCU_LVL_0);
	printf("NUM_RCU_LVL_1: %u\n", NUM_RCU_LVL_1);
	printf("NUM_RCU_LVL_2: %u\n", NUM_RCU_LVL_2);
	printf("NUM_RCU_LVL_3: %u\n", NUM_RCU_LVL_3);
	printf("NUM_RCU_NODES: %u\n", NUM_RCU_NODES);

	return 0;
}
