Metropoli BBS
VIEWER: rand.c MODE: TEXT (ASCII)
/*
 * RANDOM
 */

 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <time.h>
 #include <mem.h>
 #include "global.h"
 #include "script.h"
 #include "aspi_rw.h"
 #include "kbd.h"
 #include "dmem.h"
 #include "buf.h"
 #include "print.h"

 #define BLK_SIZE 512
 #define MAX_BLKS 120

 static FLAG auto_init = FALSE;

/***************************************************************************
 *
 * rand_aspi(...)
 *
 ***************************************************************************/

 FLAG rand_aspi(

  char		       *cmd,
  struct SCRIPT_OBJ    *script,
  unsigned long	 	num_req,
  unsigned int   	scsi_id_first,
  unsigned int   	scsi_id_last,
  unsigned int   	num_blks_min,
  unsigned int   	num_blks_max,
  unsigned long  	blk_num_first,
  unsigned long	 	blk_num_last,
  U16			tag,
  unsigned int   	pattern)
 {
  char		*aspi_cmd;
  unsigned int   scsi_id;
  unsigned long  blk_num;
  int		 rand_num;
  int		 i = 0;
  FILE		*file_log;
  FLAG		 read_only = FALSE;
  time_t	 t;
  FLAG		 ret_val = TRUE;
  unsigned int   num_blks;
  long		 ltemp;
  time_t	 time_st,time_end;
  static long	 time_total = 0;
  static U32	 num_blks_total = 0;

  //
  //
  //

  printf("ASPI Random Request Generator\n");
  printf("\tNumber of requests to be generated: %ld\n",num_req);
  printf("\tSCSI ID range: %u to %u\n",scsi_id_first,scsi_id_last);
  printf("\tBlock Number range: %lu to %lu\n",blk_num_first,blk_num_last);
  printf("\tNumber of Blocks Range per Request: %u to %u\n",num_blks_min,
	 num_blks_max);

  if ((blk_num_first - blk_num_last + 1) < num_blks_max)
    {
     error("Max number of Blocks can cause overflow of last Block");
     return (FALSE);
     }

  if (!script->loop
      &&
      (auto_init
       ||
       kbd_get_yn("Initialize blocks for speced range of SCSI IDs and Block Numbers")
       )
      )
    {
     aspi_cmd = "W";				/* Spec write		   */

     printf("%sInitializing...\n",auto_init?"Automatically ":"");

     ltemp = ((dmem_size()/BLK_SIZE) - 5) / (script->aspi_allow_reqs + 1);
     if (ltemp > MAX_BLKS)
	ltemp = MAX_BLKS;
     if (ltemp < 0)
	ltemp = 1;

     ltemp = 10;/* */

     for (scsi_id = scsi_id_first; scsi_id <= scsi_id_last; scsi_id++)
       {
	num_blks = ltemp;
	if ((blk_num_last - blk_num_first + 1) < num_blks)
	   num_blks = blk_num_last - blk_num_first + 1;

	for (blk_num = blk_num_first; ; blk_num += num_blks)
	  {
	   if ((blk_num + num_blks - 1) > blk_num_last)
	      num_blks = (blk_num + num_blks) - blk_num_last - 1;

	   if (!aspi_rw(aspi_cmd,scsi_id,blk_num,num_blks,tag,pattern))
	      return (FALSE);

	   if (i > 100)				// Modulo 100
	     {
	      printf(	"SCSI ID: %d, up to block %ld%c",
			scsi_id,
			(long)(blk_num + num_blks - 1),0x0D);
	      i = 0;
	      }
	   else
	      i += num_blks;

	   if ((blk_num + num_blks) >= blk_num_last)
	      break;
	   }
	printf("\nSCSI ID: %d initialized.\n",scsi_id);
	}

     aspi_flush();
     aspi_stats('c');				/* Clear stats		   */
     diag_msg("Done initializing...\n");
     }

  diag_msg("Generating requests...\n");

  //
  // Log file
  //

  if (diag_here(DIAG_LOG_FILE))
    {
     file_log = fopen("AE.LOG","w");
     t = time(NULL);
     fprintf(	file_log,
		"*VER_COMPAT %d\n*ECHO File produced by Random Request Log, %s\n"
		"*REQ_OUTSTANDING %d\n",
		MIN_VC_NUM,ctime(&t),script->aspi_allow_reqs);
     }

  //
  // Request loop
  //

  if (cmd[1] && (toupper(cmd[1]) == 'R'))	// Read-only, i.e. all cache
    {
     read_only = TRUE;				// Spec read-only
     aspi_cmd = "R";				// Spec read
     }

  //
  // Time statistics
  //

  time_st = time(NULL);

  for (i = 0; i < num_req; i++)
    {
     if (!read_only)
       {
	rand_num = random(2);
	if (!rand_num)				/* Write?		   */
	   if (toupper(cmd[2]) == 'V')		// Write verify?
	      aspi_cmd = "WV";			// Spec write verify
	   else					// Normal write?
	      aspi_cmd = "W";			// Spec normal write
	else					/*			   */
	   aspi_cmd = "R";			/* Spec read		   */
	}

     //
     // Don;t allow number of blocks to cause an overflow by going
     // beyond the last block specified.
     //

     scsi_id  = random(scsi_id_last - scsi_id_first + 1) + scsi_id_first;
     num_blks  = random(num_blks_max - num_blks_min + 1) + num_blks_min;
     blk_num  = random(blk_num_last - blk_num_first + 1) + blk_num_first;

     if ((blk_num + num_blks - 1) > blk_num_last)		// Overflow?
	num_blks = blk_num_last - blk_num + 1;			// Adjust

     if (diag_here(DIAG_VERBOSE))
	printf("Random ASPI command: %s.\n",aspi_cmd);

     if (diag_here(DIAG_LOG_FILE))
	fprintf(file_log,"*ASPI %s %u %lu %u %u %u\n",
		aspi_cmd,
		scsi_id,
		blk_num,
		num_blks,
		tag,
		pattern);

     num_blks_total += num_blks;

// Test to mask bits 4 and 5

  if (cmd[1] && (toupper(cmd[1]) == 'M'))	// Mask?
     do
       {
	if (cmd[2] && (cmd[2] == '4'))		// Bits 4-7?
	  {
	   blk_num &= 0xFFFFFF0F;
	   break;
	   }
	if (cmd[2] && (cmd[2] == '0'))		// Bits 0-3?
	  {
	   blk_num &= 0xFFFFFFF0;
	   break;
	   }
	if (cmd[2] && (cmd[2] == 'B'))		// Both bits 4 & 5 and bits 8 & 9?
	  {
	   blk_num &= 0xFFFFFF00;
	   break;
	   }
	if (cmd[2] && (cmd[2] == 'F'))		// Detect 0xFF?
	  {
	   if ((blk_num & 0x000000FF) == 0x000000FF)
	      blk_num &= 0xFFFFFF00;
	   break;
	   }
	}
	while (FALSE);


     if (!aspi_rw(aspi_cmd,scsi_id,blk_num,num_blks,tag,pattern))
	break;

     if (kbd_double_esc())
       {
	if (kbd_get_yn("ABORT Random Request Generator"))
	  {
	   diag_msg("User abort during generation of random requests.\n");
	   ret_val = FALSE;
	   break;
	   }
	}

     if (!(i & 0x0000000F))			// Modulo 16
	printf("Up to request %d%c",i,0x0D);
     }

  printf("\n");

  //
  // Time statistics
  //

  time_end = time(NULL);
  time_total += difftime(time_end,time_st);

  printf("Averages:\n");
  printf("\tTotal Kbytes: %ld\n\tTotal secs: %ld\n",
	 (num_blks_total/2),time_total);
  printf("\tTotal: %ld Kbytes/sec\n",
	 (num_blks_total/2)/time_total);

  if (diag_here(DIAG_LOG_FILE))
    {
     fprintf(file_log,"*ECHO End of Script file\n");
     fprintf(file_log,"*ABORT\n");
     fclose(file_log);
     }

  return (ret_val);
  }

/***************************************************************************
 *
 * rand_auto_init(...)
 *
 ***************************************************************************/

 void rand_auto_init(void)
 {
  auto_init = TRUE;
  }

[ RETURN TO DIRECTORY ]