/****Copyright (c) 2003  Alexandros V. Gerbessiotis.
 **** All rights reserved.
 ****Permission to use, copy, modify, and distribute this software,
 ****and to incorporate it, in whole or in part, into
 ****other software,is hereby granted without fee, provided that
 ****  (1) the above copyright notice and this permission
 ****      notice appear in all copies of the source code, and
 ****      the above copyright notice appear in clearly visible
 ****      form on all supporting documentation and distribution
 ****      media, and
 ****     (2) any redistribution of the software, in original
 ****         or modified form, be without fee and subject to
 ****         these same conditions.
 ****   No guarantee, whatsoever, is offered that the code works as
 ****   advertised or is absent of any, even damaging,
 ****   side-effects. Use this code at your own personal risk.
 ****/
#include	<stdio.h>
#include	<stdlib.h>
#include        <time.h>
#include        <limits.h>
#include	"bsp.h"
#include	"radixs.h"
#include         <math.h>
#define TEN 10
#define SIX 6
#define INIT   i=initialize(inp,size)
#define TIME2   t2=bsp_time(),rt2=(double)time(&timestr)-rt1
#define CALL   (*fsrt)(inp,size)
#define TIME3   t3=bsp_time(),rt3=(double)time(&timestr)-rt1
#define TIME4   t4=bsp_time(),rt4=(double)time(&timestr)-rt1
#define DEBUG1   print_seq(inp,debug,size,"Out"); 
#define CHECK1()  for(k=0;k<size-1;k++) {if (inp[k]>inp[k+1]) printf("error %s \n",labels[alg]);}

time_t time(time_t *t);

extern int CLog2();
int initialize(unsigned int *, int);

void check_if_null(void *x,char *s,char *t)
{
  if (NULL == x) {
     printf("%s::Malloc error (%s)\n",s,t);
     bsp_abort("check_if_null");
  }
}

int initialize(unsigned int *d , int length)
{
 register int i;
 srandom(21+1001*11); 
 for(i=0;i<length;i++) {
    d[i]= random() ;
 }
 return(0);
}

extern clock_t clock();

void  (*ITYPESORT)(unsigned int *,int );
void print_seq(unsigned int  *inp,int option,int size,char *s);
void print_uint(unsigned int *inp,int size,char *s,int);

int  compare(const void *left,const void *right)
{
 return(*((unsigned int *)left) - *((unsigned int *)right));
/*
 return(memcmp(left,right,TEN));
*/
}

extern double          pow(double,double);
extern double          log(double);

int main (int argc, char  **argv)
{  
time_t timestr;
struct tms buf;
int 		size,runs;
unsigned int	*inp;
double 		t1,t2,t3,t4,rt1,rt2,rt3,rt4;
int 		i,j,k;
int		debug,alg;
clock_t		d1,d2;
void (*funcrdx[6])()={qsort,int32sort,cintsort,sintsort};
char *labels[5] ={"qsort","int32sort","cintsort","sintsort"};
void (*fsrt)();

  size = 100; runs=1;  debug=0;

  if (argc == 1) {
    printf("%s size algorithm[0:qsort,1:int32,2:cint,3:sint] debug \n",argv[0]);
    exit(1);
  } 
  else 
   if (argc == 4) {
     size=atoi(argv[1]); 
     alg =atoi(argv[2]);
     debug=atoi(argv[3]); 
   }

  inp = (unsigned int *) malloc(size*sizeof(unsigned int));

  t1=bsp_time();rt1=(double) time(&timestr);
  for(i=0;i<argc;i++)
      printf("%s ",argv[i]);
  printf("  ");
  printf("\n",TEN);fflush(stdout);

  srandom(21+1001*0); 
  i=initialize(inp,size);
  print_seq(inp,debug,size,"In ");fflush(stdout);
  if (alg >0)
    fsrt=funcrdx[alg];
/*** 1: FIRST RUN :qsort*******************************************/
 TIME2;
 if (alg==0) {
   qsort((void *)inp,size,sizeof(unsigned int),compare); 
 }
 else {
   (*fsrt)(inp,size);
 }
 TIME3;
 CHECK1();
 printf("%s: %6.2f and %6.2f\n",labels[alg],(t3-t2),rt3-rt2);
 DEBUG1; fflush(stdout);

 /**********************************/
 free((void*)inp);
}

void print_seq(unsigned int *inp,int option,int size,char *s)
{
 if (option ==1) print_uint(inp, size,s,SIX);
}

void print_uint(unsigned int *inp,int size,char *s,int sIX)
{
 int i,j;
   printf("%3d %s: ",size,s);
 for(i=0;i<sIX;i++){
   printf("%d,", (unsigned int) inp[i]);
 }
   printf("...");
 for(i=size-sIX;i<size;i++){
   printf("%d,", (unsigned int) inp[i]);
 }
 printf("\n");
 
}

