#include <signal.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <asm/unistd.h>

#ifdef __i386__
#define __NR_fairsched_mknod    500     /* FairScheduler syscalls */
#define __NR_fairsched_rmnod    501
#define __NR_fairsched_chwt     502
#define __NR_fairsched_mvpr     503
#define __NR_fairsched_rate     504
#define __NR_fairsched_vcpus    505
#else
#error "syscalls not defined"
#endif

//long sys_fairsched_mknod(unsigned int parent, unsigned int weight,
//                                    unsigned int desired);
static _syscall3(long, fairsched_mknod, 
		unsigned int, parent, unsigned int, weight, 
		unsigned int, desired);
// long sys_fairsched_rmnod(unsigned int id);
static _syscall1(long, fairsched_rmnod, unsigned int, id);
// long sys_fairsched_chwt(unsigned int id, unsigned int wght);
static _syscall2(long, fairsched_chwt, unsigned int, id, unsigned int, wght);
// long sys_fairsched_mvpr(pid_t pid, unsigned int newid);
static _syscall2(long, fairsched_mvpr, pid_t, pid, unsigned int, newid);

void usage(char *name)
{
	fprintf(stderr, "%s commands\n"
			"\tmknod parent weight [desired]\n"
			"\trmnod id\n"
			"\tchwt id weight\n"
			"\tmvpr id pid\n", name);

}

int main(int argc, char **argv)
{
	pid_t pid;
	unsigned int id;
	unsigned int weight;
	unsigned int desired;
	long ret;
	char *endptr;
 
	if (argc <3) {
		usage(argv[0]);
		exit(1);
	}
	id = strtol(argv[2], &endptr, 0);
	if (*endptr != '\0') {
		usage(argv[0]);
		exit(1);
	}
	if (strstr(argv[1], "mknod") == argv[1]) {
		if (argc < 4) {
			usage(argv[0]);
			exit(1);
		}
		weight = strtol(argv[3], &endptr, 0);
		if (*endptr != '\0') {
			usage(argv[0]);
			exit(1);
		}
		desired = 0;
		if (argc > 4) {
			desired = strtol(argv[4], &endptr, 0);
			if (*endptr != '\0') {
				usage(argv[0]);
				exit(1);
			}
		}
		ret = fairsched_mknod(id, weight, desired);
		if (ret < 0) {
			perror("fairsched_mknod:");
			exit(1);
		}
		printf("node %u created\n", desired == 0 ? ret : desired);
	} else if (strstr(argv[1], "rmnod") == argv[1]) {
		ret = fairsched_rmnod(id);
		if (ret < 0) {
			perror("fairsched_rmnod:");
			exit(1);
		}
		printf("node %u removed\n", id);
	} else if (strstr(argv[1], "chwt") == argv[1]) {
		if (argc < 4) {
			usage(argv[0]);
			exit(1);
		}
		weight = strtol(argv[3], &endptr, 0);
		if (*endptr != '\0') {
			usage(argv[0]);
			exit(1);
		}
		ret = fairsched_chwt(id, weight);
		if (ret < 0) {
			perror("fairsched_chwt:");
			exit(1);
		}
		printf("node %u weight changed\n", id);
	} else if (strstr(argv[1], "mvpr") == argv[1]) {
		if (argc < 4) {
			usage(argv[0]);
			exit(1);
		}
		pid = strtol(argv[3], &endptr, 0);
		if (*endptr != '\0') {
			usage(argv[0]);
			exit(1);
		}
		ret = fairsched_mvpr(pid, id);
		if (ret < 0) {
			perror("fairsched_mvpr:");
			exit(1);
		}
		printf("pid %u moved to %d\n", pid, id);
	}
}