/* 
 * Real-Time and Multimedia Systems Laboratory
 * Copyright (c) 2000 Carnegie Mellon University
 * All Rights Reserved.
 * 
 * Permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 * 
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 * 
 * Carnegie Mellon requests users of this software to return to
 * 
 *  Real-Time and Multimedia Systems Laboratory
 *  Attn: Prof. Raj Rajkumar
 *  Electrical and Computer Engineering, and Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 *  or via email to raj@ece.cmu.edu
 * 
 * any improvements or extensions that they make and grant Carnegie Mellon
 * the rights to redistribute these changes.
 */
/*			program developed by Luca Abeni
 *					luca@sssup.it
 *					http://hartik.sssup.it/~luca
 */
/* Modified for FS RSV demo by Saowanee Saewong */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <rk/rk.h>
#include <rk/posix_timers.h>

#define start_delay 1 /* second */
unsigned long int firstime;
struct timespec fnow;

extern int mpbody(unsigned short int id);
int ac;
char *av[10];

unsigned int times[10000];

unsigned int qos_time(void)
{
    struct timespec t;

    clock_gettime(CLOCK_REALTIME, &t);

    return t.tv_sec * 1000000 + t.tv_nsec / 1000;
}

void shutdown(rk_resource_set_t rs1)
{
    int res;

    res = rk_resource_set_destroy(rs1);
    if (res != 0) {
	printf("rk_resource_set_destroy failed destroying RS %p", rs1);
    }

    printf("Everything is finished... I am going to exit!\n");
    exit(0);
}

int main(int argc, char *argv[])
{
    int i;
    int pid1;
    rk_resource_set_t rs1;    
    rk_reserve_t cpu_rsv1;
    rk_reserve_param_data_t p;
    struct timespec c, t;
    cpu_reserve_attr_data_t attr;
    /* int pid2; */

    if (argc < 3) {
       printf("Usage : %s [title] [mpgfile] \n", argv[0]);
       exit(1);
    }    
    ac = argc-1;
    for (i = 0; i < ac; i++) {
	av[i] = argv[i+1];
    }

    /* create resource sets */
    rs1 = rk_resource_set_create(argv[1]);
    if (((int) rs1 == -1) || (rs1 == NULL)) {
	printf("Cannot create resource set 1!!!\n");
	exit(-1);
    }

    /* And now, the reserves... */
    clock_gettime(CLOCK_REALTIME, &fnow);
    firstime = fnow.tv_nsec / 1000000 + fnow.tv_sec * 1000;

    c.tv_sec = 0, c.tv_nsec = 1000000;
    t.tv_sec = 2, t.tv_nsec = 0;
    p.enf_mode = p.sch_mode = p.rep_mode = RSV_SOFT;
    //p.enf_mode = p.sch_mode = p.rep_mode = RSV_HARD;

    attr.compute_time = c;
    attr.period = t;
    attr.deadline = t;
    attr.blocking_time.tv_sec = 0;
    attr.blocking_time.tv_nsec = 0;
    memcpy(&attr.start_time, &fnow, sizeof(struct timespec));
    attr.start_time.tv_sec += start_delay;
    attr.reserve_type = p;

    printf("Going to create CPU RSV (%ld, %ld)\n", c.tv_nsec, t.tv_nsec);
    cpu_rsv1 = rk_cpu_reserve_create(rs1, &attr);
    if (cpu_rsv1 == 0) {
	printf("Cannot create CPU reserve # 1\n");
	shutdown(rs1);
    }

    /* Let's wait that the reserves are attached to their resource sets */
    while (rk_resource_set_get_cpu_rsv(rs1) == 0);


    pid1 = fork();
    if (pid1 < 0) {
    	perror("Cannot fork task1");
	exit(-1);
    }
    if (pid1 == 0) {
    	mpbody(0);
	exit(0);
    }
    /*
    pid2 = fork();
    if (pid2 < 0) {
    	perror("Cannot fork task1");
	exit(-1);
    }
    if (pid2 == 0) {
    	mpbody(1);
	exit(0);
    }
    */
    //pause();
    wait(NULL);

    shutdown(rs1);
    exit(0);
}
