#include <stdio.h>
#include <handle.h>
#include <stdlib.h>
#include <conio.h>
#include <stream.hpp>
#include <time.h>
#include <dos.h>

#define N_PTRS 16
#define MAX_EMM_BLOCK_SIZE 16372
#define ITERATION_LIMIT 16384

typedef struct mystruct
   {
   int   n;
   char  buf[1];
   } MYSTRUCT;

typedef MYSTRUCT far *        MAINPTR;
typedef MYSTRUCT __handle *   EMMPTR;

MAINPTR  mainptr[N_PTRS];
EMMPTR   emmptr[N_PTRS];
MYSTRUCT *disk_buffer;

main()
   {
   int i,j,k,outer_loop_cnt;
   clock_t start,end;
   double main_time_in_secs, emm_time_in_secs, ratio;
   int div_factor = 8;
   int blocksize;

   printf("\tBlocksize\tMain mem time\tEMM time\tRatio\n");

   for(div_factor = 8 ; div_factor > 0 ; --div_factor)
      {
      blocksize = MAX_EMM_BLOCK_SIZE / div_factor;

      for(i = 0 ; i < N_PTRS ; ++i)
         {
         mainptr[i] = farmalloc(blocksize);
         if(mainptr[i] == NULL)
            {
            printf("Unable to allocate mainptr[%d]\n",i);
            for(j = 0 ; j < i ; ++j)
               {
               farfree(mainptr[j]);
               handle_free(emmptr[j]);
               exit(0);
               }
            }

         mainptr[i]->n = i;

         emmptr[i] = handle_malloc(blocksize);
         if(emmptr[i] == NULL)
            {
            printf("Unable to allocate emmptr[%d]\n",i);
            farfree(mainptr[i]);
            for(j = 0 ; j < i ; ++j)
               {
               farfree(mainptr[j]);
               handle_free(emmptr[j]);
               exit(0);
               }
            }

         if(!handle_ishandle(emmptr[i]))
            printf("emmptr[%d] is NOT a handle\n",i);

         emmptr[i]->n = i;
         }

      for(outer_loop_cnt = 1 ; outer_loop_cnt <= 5 ; ++outer_loop_cnt)
         {
         start = clock();

         for(i = 0 ; i < ITERATION_LIMIT ; ++i)
            {
            for(j = 0 ; j < N_PTRS ; ++j)
               k = mainptr[j]->n;
            }

         end = clock();

         main_time_in_secs = ((double)(end - start)) / ((double)CLK_TCK);

         start = clock();

         for(i = 0 ; i < ITERATION_LIMIT ; ++i)
            {
            for(j = 0 ; j < N_PTRS ; ++j)
               k = emmptr[j]->n;
            }

         end = clock();

         emm_time_in_secs = ((double)(end - start)) / ((double)CLK_TCK);

         ratio = emm_time_in_secs / main_time_in_secs;

         if(outer_loop_cnt == 1)
            printf("\t%d\t\t%6.3f\t\t%6.3f\t\t%6.3f\n", blocksize,
                   main_time_in_secs, emm_time_in_secs, ratio);
         else
            printf("\t\t\t%6.3f\t\t%6.3f\t\t%6.3f\n", main_time_in_secs,
                   emm_time_in_secs, ratio);
         }

      for(i = 0 ; i < N_PTRS ; ++i)
         {
         farfree(mainptr[i]);
         handle_free(emmptr[i]);
         }
      }
   }
