#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#define  __USE_GNU 
#include "whet.h"
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/wait.h>

/* Intervalo, em segundos, entre cada execução do benchmark */
#define RENEW_BENCH 2592000

int main(int argc, char *argv[]) {
    int i;
    int result;
    int myPid;
    float processResult;
    float processTime = 0;
    int status;
    int *pfd;
    char buf[1024];
    int nread;
    FILE *f;
    struct stat fileAttr;
    time_t actualTime;
    time_t fileTime;
    int resStat;
    int execBench;
    struct utsname unameBuf;

    uname(&unameBuf);

    execBench = 0;
    resStat = stat(argv[1], &fileAttr);
    if(resStat == -1) {
        if(errno == ENOENT)
            execBench = 1;
    }
    else {
        fileTime = fileAttr.st_mtime;
        time(&actualTime);  

        if(difftime(actualTime, fileTime) > RENEW_BENCH)
            execBench = 1;
    }

    if(execBench == 1) 
    {
        #ifdef IRIX
            #define numberOfProcessors sysconf(_SC_NPROC_CONF)
        #else
            #ifdef IRIX64
                #define numberOfProcessors sysconf(_SC_NPROC_CONF)
            #else
                #define numberOfProcessors sysconf(_SC_NPROCESSORS_CONF)
            #endif
        #endif

        pfd = malloc(numberOfProcessors * sizeof(int));

        status = pipe(pfd);
        if(status != -1) 
        {
            i = 0;
    	    while(i < numberOfProcessors) {
		        myPid = fork();
    	        if(myPid == 0) // Child process
          	    {
         		    processResult = DoWhet(10000);

    	    		close(pfd[0]);
	    		    sprintf(buf, "%f", processResult);
    	    		write(pfd[1], buf, strlen(buf)+1);
	    	    	close(pfd[1]);
                    exit(0);
	 	        }
	 	        else
	 	        {
                    ++i;
                }
            }
        }
    
        if(myPid != 0) 
    	{
	    	close(pfd[1]);
		    for(i = 0; i < numberOfProcessors; i++)
		    {   
			    wait(&status);
    			if((nread = read(pfd[0], buf, 1024)) != -1)
	    		{
		    		processTime += atof(buf);
			    }
    		}

	    	close(pfd[0]);

		    processTime /= numberOfProcessors;

    		result =
            		numberOfProcessors * 10000 * 100 / processTime;

            printf("%d", result);
            f = fopen(argv[1], "w");
            fprintf(f, "%d", result);
            fclose(f);
        }

        // Desaloca memória
        free(pfd);
    }

    return 0;
}
