#include <sys/time.h>
#include <math.h>       /* for sin, exp etc.           */
#include <stdio.h>      /* standard I/O                */
#include <string.h>     /* for strcpy - 3 occurrences  */
#include <stdlib.h>     /* for exit   - 1 occurrence   */
#include <time.h>
#include <ctype.h>

/* #define enable_threading 1 */  /* uncomment for threading */
#ifdef enable_threading
#include <pthread.h>
#endif


char e2[32500]; /* ~64MB array with 1 byte char systems */
int ae1 = 32500;
double e3[4096];
int ae2 = 4096;

struct timeval starttime,endtime;
#define LOOPS 28

/* char alphabet1[26]; */

/* setup the array with the alphabet */
/* abcdefghijklmnopqrstuvwxyz */
char alphabet1[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
double te0, te1, te2, prob0, prob1;
double lsalu;
long testno;
int i;

/* Converting between lower/uppercase */
int Problem0() {
        printf("\nRunning ALU tests (2 for now):\n");
	printf("\tPreparing test #1. setting up 64MB char array...\n");	
		for(i=0; i < ae1; i++) {  
			e2[i] = alphabet1[i % 26]; 
			}
		printf("\tdone.\n");
	/*	printf("0 =: %c\n", e2[0]);
		printf("32499 =: %c\n", e2[32499]);
		printf("26 =: %c\n", e2[26]);
		e2[0]=(char)toupper((int)e2[0]);
		printf("0 =: %c\n", e2[0]);
		e2[0]=(char)tolower((int)e2[0]);
		printf("0 =: %c\n", e2[0]); */
		
		printf("\tTest running...\n\n");
		gettimeofday(&starttime, NULL);
		for(testno=0; testno<LOOPS; testno++) {
#ifdef enable_threading
#pragma omp parallel for
#endif
        		for(i=0;i<strlen(e2);i++){
        			e2[i]=(char)toupper((int)e2[i]);
        		}
#ifdef enable_threading
#pragma omp parallel for
#endif
        		for(i=0;i<strlen(e2);i++){
        			e2[i]=(char)tolower((int)e2[i]);
        		}
		}	


	gettimeofday(&endtime, NULL);
        te0=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
	te1 = LOOPS * ae1 * 2 / te0;
        printf("\tTest #1:\t ctype.h case modification: %lf/s\n\n", te1);
	prob0 = LOOPS * ae1 * 2  / te0;
return prob0;
}

/* Random number generation performance */ 
int Problem1() {
	printf("\tPreparing test #2. setting up 64MB double array...\n");
		for(i=0; i < ae2; i++) {
			e3[i] = 1;
               }
		printf("\tdone.\n");
                printf("\tTest running...\n\n");
                gettimeofday(&starttime, NULL);

                for(testno=0; testno<LOOPS; testno++) {

			srand(testno);			
#ifdef enable_threading
#pragma omp parallel for
#endif
                        for(i=0;i<ae2-1;i++){
				e3[i]=rand();
                        }
                       
		}

        gettimeofday(&endtime, NULL);
        te0=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        te2 = LOOPS * ae2 / te0;
        printf("\tTest #2:\t random number generation by stdlib.h: %lf/s\n", te2);
        prob1 = LOOPS * ae2 / te0 / 39;
return prob1;
}

int main(){
FILE *fp;
	Problem0();
	Problem1();
lsalu = (prob1 + prob0) / 80000 * 1.1;
fp=fopen("aludir/lsalu.log", "w");
fprintf(fp, "%f\n", lsalu);
fclose(fp);
printf("DONE.\n");
return (0);
}
