Esempio n. 1
0
void ComputeParams(sParams* PB, item* memList, int32 value, int32 nbVal ) {
	
	static 	int32 	startAddress = 0;
	static int32 	shift = 0;
	int32 			size;
	int32 			size1;
	int32 			size2;
	bool 			isRead;
	bool 			isSeq;
	
	
	printf("Generates %d.%d with param %d\n", PB->microBenchID, PB->expID,  value);
	
	if (strcasecmp(PB->base, "SR") == 0) {
		PB->ignoreIO = PB->ignoreIOSR;
		PB->IOCount = PB->IOCountSR;
		isSeq = TRUE;
		isRead = TRUE;
	}
	if (strcasecmp(PB->base, "SW") == 0) {
		PB->ignoreIO = PB->ignoreIORR;
		PB->IOCount = PB->IOCountRR;
		isSeq = TRUE;
		isRead = FALSE;
	}
	if (strcasecmp(PB->base, "RR") == 0) {
		PB->ignoreIO = PB->ignoreIOSW;
		PB->IOCount = PB->IOCountSW;
		isSeq = FALSE;
		isRead = TRUE;
	}
	if (strcasecmp(PB->base, "RW") == 0) {
		PB->ignoreIO = PB->ignoreIORW;
		PB->IOCount = PB->IOCountRW;
		isSeq = FALSE;
		isRead = FALSE;
	}
	
	PB->targetSize = PB->deviceSize; // Default value for target size
	if (PB->microBenchID == GRA) PB->IOSize = value;
	if (PB->microBenchID == ALI) PB->IOShift = value;
	if (PB->microBenchID == LOC) PB->targetSize = value * PB->IOSize ;
	if (PB->microBenchID == PAT) PB->nbPartition = value;
	if (PB->microBenchID == ORD) PB->order = value;
	if (PB->microBenchID == PAR) PB->parDeg = value;
	if (PB->microBenchID == MIX) PB->ratio = value;
	if (PB->microBenchID == PIO) PB->pauseIO = value;
	if (PB->microBenchID == PBU) PB->burstIO = value;

	// Number of sectors potentially touched by the experiment 
	size = PB->IOSize * PB->IOCount;
	if (PB->IOShift != 0) size += PB->IOSize; 
		
	if (PB->microBenchID == LOC) size = PB->targetSize;
	if (PB->microBenchID == ORD) size = PB->IOSize * abs(PB->order)* PB->IOCount;
	
	// 1-GRANULARITY , 2-ALIGNMENT, 8-PAUSE, 9-BURST
	if ((PB->microBenchID == GRA) || (PB->microBenchID == ALI)|| 
		(PB->microBenchID == PIO)|| (PB->microBenchID == PBU)) {
		
		if (isSeq == FALSE) 
			PB->targetOffset = 0;
		else if (isRead == TRUE) {
			PB->targetOffset = rg.IRandom(0,(int32)((PB->targetSize - size)/BLOCK))*BLOCK;
			PB->targetSize = size;
		}
		else {
			PB->targetOffset = MemSearch(memList, size);
			PB->targetSize = size;
		}
	}
	// 3-LOCALITY
	else if (PB->microBenchID == LOC) {
		if ((isRead == TRUE) || (value > 1024)) 
			PB->targetOffset = rg.IRandom(0,(int32)((PB->deviceSize - size)/BLOCK))*BLOCK;
		else {
			PB->targetOffset = MemSearch(memList, size);
			//printf("==>%d  %d\n",size, PB->targetOffset );
		}
	}
	// 07-MIX 
	else if (PB->microBenchID == MIX) {
		int32 I1, I2, C1, C2;
		
		I1 = PB->ignoreIO;
		C1 = PB->IOCount;
		if (strcasecmp(PB->base2, "SR") == 0) {
			I2 = PB->ignoreIOSR;
			C2 = PB->IOCountSR;
		}
		
		if (strcasecmp(PB->base2, "SW") == 0) {
			I2 = PB->ignoreIOSW;
			C2 = PB->IOCountSW;
		}
				
		if (strcasecmp(PB->base2, "RR") == 0) {
			I2 = PB->ignoreIORR;
			C2 = PB->IOCountRR;
		}

		if (strcasecmp(PB->base2, "RW") == 0) {
			I2 = PB->ignoreIORW;
			C2 = PB->IOCountRW;
		}

		if (PB->ratio < 0) {
			PB->ignoreIO = max(I1 + (I1-1)*(-PB->ratio) + 1, I2 * (-PB->ratio + 1)/(-PB->ratio) + 1);
			PB->IOCount = max(C1-I1, C2-I2) + PB->ignoreIO;
			size1 = PB->IOSize * (1+ (int32)(PB->IOCount/(-PB->ratio + 1)));
			size2 = PB->IOSize * (1+ (int32)((PB->IOCount/(-PB->ratio + 1)) * (-PB->ratio)));
		}
		else if (PB->ratio > 0) {
			PB->ignoreIO = max(I2 + (I2-1) * PB->ratio + 1, (I1 * (PB->ratio + 1)/PB->ratio) + 1);
			PB->IOCount = max(C1-I1, C2-I2) + PB->ignoreIO;
			size1 = PB->IOSize * (1+ (int32)(PB->IOCount/(PB->ratio + 1)));
			size2 = PB->IOSize * (1+ (int32)((PB->IOCount/(PB->ratio + 1)) * (PB->ratio)));
		}
		else {
			PB->ignoreIO = I2;
			PB->IOCount = C2;
			size1 = 0;
			size2 = PB->IOSize * PB->IOCount;
		}
		
		if (((strcasecmp(PB->base, "SR") == 0) &&  (strcasecmp(PB->base2, "RR") == 0)) ||
			((strcasecmp(PB->base, "SR") == 0) &&  (strcasecmp(PB->base2, "RW") == 0))) {
			PB->targetSize = size1;
			PB->targetOffset = rg.IRandom(0,(int32)((PB->deviceSize - size1)/BLOCK))*BLOCK;
			PB->targetOffset2 = 0;
			PB->targetSize2 = PB->deviceSize;
		}
		if ((strcasecmp(PB->base, "RR") == 0) &&  (strcasecmp(PB->base2, "RW") == 0)) {
			PB->targetSize = PB->deviceSize;
			PB->targetOffset = 0;
			PB->targetOffset2 = 0;
			PB->targetSize2 = PB->deviceSize;
		}
		if ((strcasecmp(PB->base, "RR") == 0) &&  (strcasecmp(PB->base2, "SW") == 0)) {
			PB->targetOffset2 = MemSearch(memList, size2);
			PB->targetSize2 = size2;
			PB->targetOffset = MemMinAddress(memList);
			PB->targetSize = PB->deviceSize - PB->targetOffset;
		}
		if ((strcasecmp(PB->base, "SW") == 0) &&  (strcasecmp(PB->base2, "RW") == 0)) {
			PB->targetOffset = MemSearch(memList, size1);
			PB->targetSize = size1;
			PB->targetOffset2 = MemMinAddress(memList);
			PB->targetSize2 = PB->deviceSize - PB->targetOffset2;
		}
		if ((strcasecmp(PB->base, "SR") == 0) &&  (strcasecmp(PB->base2, "SW") == 0)) {
			PB->targetOffset2 = MemSearch(memList, size2);
			PB->targetSize2 = size2;
			PB->targetOffset = rg.IRandom((int32)((PB->deviceSize - MemMinAddress(memList))/2)/BLOCK,(int32)((PB->deviceSize - size1)/BLOCK))*BLOCK;
			PB->targetSize = size1;
		}
	}
	// 6-PARALLELISM
	else if (PB->microBenchID == PAR) {
		PB->targetSize = ((int32)((PB->deviceSize / PB->parDeg)/BLOCK))*BLOCK;
		if (isSeq == FALSE) 
			PB->targetOffset =  PB->processID * PB->targetSize;
		else if (isRead == TRUE) {
			PB->targetOffset =  rg.IRandom((PB->processID * PB->targetSize)/BLOCK, 
									 		 ((PB->processID + 1) * PB->targetSize - size)/BLOCK) * BLOCK;
			PB->targetSize = size;
		}
		else { // SEQUENTIAL WRITE..... // CAUTION : PARALLEL EXPERIMENT MUST BE AFTER PARTITIONING
			PB->targetSize = (PB->deviceSize - startAddress) / PB->parDeg;
			if (PB->targetSize < size) HandleError("ComputeParam", "device too small", 0, ERR_ABORT);
			PB->targetOffset =  MemAllocNearestAfterA(memList, (PB->processID) * PB->targetSize + startAddress, size);
			PB->targetSize = size;
		}
	}
	// 4-PARTITIONING
	else if (PB->microBenchID == PAT) {
		if ((isRead == TRUE) || (PB->nbPartition > 16)) {
			PB->targetOffset =  0;
			PB->targetSize = ((int32) (PB->deviceSize/(MAX_PARTITIONS * BLOCK))) * MAX_PARTITIONS * BLOCK;
		}
		else { // SEQUENTIAL WRITE..... // CAUTION : PARTITIONNING EXPERIMENT MUST BE THE FIRST ...
			if (startAddress == 0)
				startAddress = MemMinAddress(memList);
			if ((size % (16*BLOCK)) != 0)
				size = ((int32) (size / (16*BLOCK)) + 1 ) * (16 * BLOCK);
			PB->targetSize = PB->deviceSize - startAddress - size * nbVal * PB->nbRun;
			PB->targetSize = (int32) (PB->targetSize/ (16 * BLOCK)) * (16 * BLOCK); 
			if (PB->targetSize < size) HandleError("ComputeParam", "device too small", 0, ERR_ABORT);
			PB->targetOffset = startAddress + shift;
			for (int32 k = 0; k < PB->nbPartition; ++k) {
				long temp;
				temp = MemAlloc(memList, PB->targetOffset + k * PB->targetSize/PB->nbPartition,  
						PB->targetOffset + k * PB->targetSize/PB->nbPartition + size/PB->nbPartition);
			}	
			shift = shift + size/PB->nbPartition;
		}
		
	}
	// 5-ORDER
	else if (PB->microBenchID == ORD) {
		size = PB->IOSize * PB->IOCount * PB->order;
		if (size == 0)  size = BLOCK;
		PB->targetSize = abs(size);
		if (isRead == TRUE) {
			PB->targetOffset =  rg.IRandom(0,(int32)((PB->deviceSize - PB->targetSize)/BLOCK))*BLOCK;
			if (size < 0)
				PB->targetOffset =  PB->deviceSize - PB->targetOffset;
		}
		else {
			PB->targetOffset =  MemSearch(memList, abs(size));
			if (PB->targetOffset == INT32_MAX) {
				PB->targetOffset = rg.IRandom(0,(int32)((PB->deviceSize - abs(size))/BLOCK))*BLOCK;
				PB->warning = DEVICE_TOO_SMALL;
				OutputString(OUT_LOG, "DEVICE TOO SMALL \n");
			}	
			if (size <0)
				PB->targetOffset =  PB->targetOffset - size;
		}
	}

	if (PB->targetOffset == INT32_MAX) HandleError("ComputeParam", "device too small", 0, ERR_ABORT);
		
	if ((PB->order >= 0) && (PB->targetOffset + PB->targetSize > PB->deviceSize)) {
		char st[MAX_STR];
		
		sprintf(st, "Adjusting TargetSize (TO = %d, TS = %d DS = %d\n", PB->targetOffset, PB->targetSize, PB->deviceSize);
		PB->targetSize = PB->deviceSize - PB->targetOffset;
		PB->warning = PB->warning | TEST_EXCEED_DEVICE;
		OutputString(OUT_LOG, st);
	}
	if ((PB->order < 0) && (PB->targetOffset - PB->targetSize < 0)) {
		char st[MAX_STR];

		sprintf(st, "Adjusting TargetSize Reverse Order (TO = %d, TS = %d DS = %d\n", PB->targetOffset, PB->targetSize, PB->deviceSize);		PB->targetSize = PB->targetOffset;
		PB->warning = PB->warning | TEST_EXCEED_DEVICE;
		OutputString(OUT_LOG, st);
	}
}
Esempio n. 2
0
/**
 * @brief Computes Params
 *
 * The difficulty here is to acomodate all the benchmark runs into the memory available
 * on the device without having to "reformat" it.\n
 * Allocation is based on the assumption that benchmark runs are done in a given order:
 * -# read only benchmark (do not modify the "state" of the flash (Exp. 1 to 15)
 * -# random writes (on the whole device) ==> modify slightly, but randomly the state (Exp. 16-22)
 * -# Sequential writes  on focused areas ==> modify the state, but the focus moves\n
 *     ==> the memory is "consumed" sequentially. If no more memory is available warning
 *       DEVICE_TOO_SMALL is set and the offset is chosen randomly (thus the test is not ok)
 * -# Mix patterns SR/SW, RR/SW, SW/RW
 * -# parallelism and partitionned patterns (Exp. 32 & 33)==> Memory is allocated in the
 *     remaining part of the device. Tuning of IOCount and experiments should be done to fit
 *     in the device.
 * -# Ordered patterns (Exp. 34): when the experiment is "focused" (small gaps), we do as
 *     with sequential up to the point where there is no place. Then, it is random.
 *
 * Memory allocation is done thanks to the blocAlloc module.
 *
 * @param PB a pointer to a structure containing benchmark parameters for this session
 * @param memList a pointer to a list of free areas on the device
 * @param value the value of the parameter used for the generation
 * @param nbVal number of values
 */
static void
ComputeParams (UflipParams *PB,
               item        *memList,
               int32_t      value,
               int32_t      nbVal)
{
  static int32_t startAddress = 0;
  static int32_t shift        = 0;
  int32_t        size;
  bool           isRead       = false;
  bool           isSeq        = false;

  printf ("Generates %d.%d with param %d\n", PB->microBenchID, PB->expID,  value);

  if (strcasecmp (PB->base, "SR") == 0)
    {
      PB->ignoreIO = PB->ignoreIOSR;
      PB->IOCount  = PB->IOCountSR;
      isSeq        = true;
      isRead       = true;
    }
  else if (strcasecmp (PB->base, "SW") == 0)
    {
      PB->ignoreIO = PB->ignoreIORR;
      PB->IOCount  = PB->IOCountRR;
      isSeq        = true;
      isRead       = false;
    }
  else if (strcasecmp (PB->base, "RR") == 0)
    {
      PB->ignoreIO = PB->ignoreIOSW;
      PB->IOCount  = PB->IOCountSW;
      isSeq        = false;
      isRead       = true;
    }
  else if (strcasecmp (PB->base, "RW") == 0)
    {
      PB->ignoreIO = PB->ignoreIORW;
      PB->IOCount  = PB->IOCountRW;
      isSeq        = false;
      isRead       = false;
    }

  PB->targetSize = PB->deviceSize; /* Default value for target size */

  switch (PB->microBenchID)
    {
      case GRA:
        PB->IOSize = value;
        break;
       case ALI:
        PB->IOShift = value;
        break;
      case LOC:
        PB->targetSize = value * PB->IOSize;
        break;
      case PAT:
        PB->nbPartition = value;
        break;
      case ORD:
        PB->order = value;
        break;
      case PAR:
        PB->parDeg = value;
        break;
      case MIX:
        PB->ratio = value;
        break;
      case PIO:
        PB->pauseIO = value;
        break;
      case PBU:
        PB->burstIO = value;
        break;
      default:
        /* nothing to do */
        break;
    }

  /* Number of sectors potentially touched by the experiment */
  size = PB->IOSize * PB->IOCount;

  if (PB->IOShift != 0)
    size += PB->IOSize;

  switch (PB->microBenchID)
    {
      case LOC:
        /* 3-LOCALITY */
        size = PB->targetSize;
        if ((isRead == true) || (value > 1024))
          {
            PB->targetOffset = uflip_random_get_int (rg, 0, (int32_t) ((PB->deviceSize - size) / BLOCK)) * BLOCK;
          }
        else
          {
            PB->targetOffset = MemSearch (memList, size);
            /*printf ("==>%d  %d\n",size, PB->targetOffset);*/
          }
        break;
      case ORD:
        /* 5-ORDER */
        size = PB->IOSize * abs (PB->order) * PB->IOCount; /*XXX: wtf? */
        size = PB->IOSize * PB->IOCount * PB->order;
        if (size == 0)
          size = BLOCK;

        PB->targetSize = abs (size);
        if (isRead == true)
          {
            PB->targetOffset =  uflip_random_get_int (rg, 0, (int32_t) ((PB->deviceSize - PB->targetSize) / BLOCK)) * BLOCK;
            if (size < 0)
              PB->targetOffset =  PB->deviceSize - PB->targetOffset;
          }
        else
          {
            PB->targetOffset = MemSearch (memList, abs(size));
            if (PB->targetOffset == INT32_MAX)
              {
                PB->targetOffset = uflip_random_get_int (rg, 0, (int32_t) ((PB->deviceSize - abs (size))/BLOCK)) * BLOCK;
                PB->warning = DEVICE_TOO_SMALL;
                OutputString (OUT_LOG, "DEVICE TOO SMALL \n");
              }
            if (size < 0)
              PB->targetOffset =  PB->targetOffset - size;
          }
        break;
      case GRA:
      case ALI:
      case PIO:
      case PBU:
        /* 1-GRANULARITY , 2-ALIGNMENT, 8-PAUSE, 9-BURST */
        if (isSeq == false)
          {
            PB->targetOffset = 0;
          }
        else if (isRead == true)
          {
            PB->targetOffset = uflip_random_get_int (rg, 0, (int32_t) ((PB->targetSize - size) / BLOCK)) * BLOCK;
            PB->targetSize   = size;
          }
        else
          {
            PB->targetOffset = MemSearch (memList, size);
            PB->targetSize   = size;
          }
        break;
      case MIX:
        /* 07-MIX */
        {
          int32_t I1 = PB->ignoreIO;
          int32_t I2 = 0;
          int32_t C1 = PB->IOCount;
          int32_t C2 = 0;
          int32_t size1;
          int32_t size2;

          if (strcasecmp (PB->base2, "SR") == 0)
            {
              I2 = PB->ignoreIOSR;
              C2 = PB->IOCountSR;
            }
          else if (strcasecmp (PB->base2, "SW") == 0)
            {
              I2 = PB->ignoreIOSW;
              C2 = PB->IOCountSW;
            }
          else if (strcasecmp (PB->base2, "RR") == 0)
            {
              I2 = PB->ignoreIORR;
              C2 = PB->IOCountRR;
            }
          else if (strcasecmp (PB->base2, "RW") == 0)
            {
              I2 = PB->ignoreIORW;
              C2 = PB->IOCountRW;
            }

          if (PB->ratio < 0)
            {
              PB->ignoreIO = max (I1 + (I1 - 1) * (-PB->ratio) + 1, I2 * (-PB->ratio + 1) / (-PB->ratio) + 1);
              PB->IOCount  = max (C1 - I1, C2 - I2) + PB->ignoreIO;
              size1        = PB->IOSize * (1 + (int32_t) (PB->IOCount / (-PB->ratio + 1)));
              size2        = PB->IOSize * (1 + (int32_t) ((PB->IOCount / (-PB->ratio + 1)) * (-PB->ratio)));
            }
          else if (PB->ratio > 0)
            {
              PB->ignoreIO = max (I2 + (I2 - 1) * PB->ratio + 1, (I1 * (PB->ratio + 1) / PB->ratio) + 1);
              PB->IOCount  = max (C1 - I1, C2 - I2) + PB->ignoreIO;
              size1        = PB->IOSize * (1 + (int32_t)(PB->IOCount / (PB->ratio + 1)));
              size2        = PB->IOSize * (1 + (int32_t)((PB->IOCount / (PB->ratio + 1)) * (PB->ratio)));
            }
          else
            {
              PB->ignoreIO = I2;
              PB->IOCount = C2;
              size1 = 0;
              size2 = PB->IOSize * PB->IOCount;
            }

          if (((strcasecmp (PB->base, "SR") == 0) && (strcasecmp (PB->base2, "RR") == 0)) ||
              ((strcasecmp (PB->base, "SR") == 0) && (strcasecmp (PB->base2, "RW") == 0)))
            {
              PB->targetSize    = size1;
              PB->targetOffset  = uflip_random_get_int (rg, 0, (int32_t) ((PB->deviceSize - size1) / BLOCK)) * BLOCK;
              PB->targetOffset2 = 0;
              PB->targetSize2   = PB->deviceSize;
            }
          else if ((strcasecmp (PB->base, "RR") == 0) && (strcasecmp (PB->base2, "RW") == 0))
            {
              PB->targetSize    = PB->deviceSize;
              PB->targetOffset  = 0;
              PB->targetOffset2 = 0;
              PB->targetSize2   = PB->deviceSize;
            }
          else if ((strcasecmp (PB->base, "RR") == 0) && (strcasecmp (PB->base2, "SW") == 0))
            {
              PB->targetOffset2 = MemSearch (memList, size2);
              PB->targetSize2   = size2;
              PB->targetOffset  = MemMinAddress (memList);
              PB->targetSize    = PB->deviceSize - PB->targetOffset;
            }
          else if ((strcasecmp (PB->base, "SW") == 0) &&  (strcasecmp (PB->base2, "RW") == 0))
            {
              PB->targetOffset  = MemSearch (memList, size1);
              PB->targetSize    = size1;
              PB->targetOffset2 = MemMinAddress (memList);
              PB->targetSize2   = PB->deviceSize - PB->targetOffset2;
            }
          else if ((strcasecmp (PB->base, "SR") == 0) && (strcasecmp (PB->base2, "SW") == 0))
            {
              PB->targetOffset2 = MemSearch (memList, size2);
              PB->targetSize2 = size2;
              PB->targetOffset = uflip_random_get_int (rg, (int32_t) ((PB->deviceSize - MemMinAddress (memList)) / 2) / BLOCK, (int32_t) ((PB->deviceSize - size1) / BLOCK)) * BLOCK;
              PB->targetSize = size1;
            }
          }
        break;
      case PAR:
        /* 6-PARALLELISM */
        PB->targetSize = ((int32_t) ((PB->deviceSize / PB->parDeg) / BLOCK)) * BLOCK;
        if (isSeq == false)
          {
            PB->targetOffset =  PB->processID * PB->targetSize;
          }
        else if (isRead == true)
          {
            PB->targetOffset =  uflip_random_get_int(rg, (PB->processID * PB->targetSize)/BLOCK,
                                                     ((PB->processID + 1) * PB->targetSize - size)/BLOCK) * BLOCK;
            PB->targetSize = size;
          }
        else
          {
            /* SEQUENTIAL WRITE..... CAUTION : PARALLEL EXPERIMENT MUST BE AFTER PARTITIONING */
            PB->targetSize = (PB->deviceSize - startAddress) / PB->parDeg;

            if (PB->targetSize < size)
              HandleError (__func__, "device too small", 0, ERR_ABORT);

            PB->targetOffset = MemAllocNearestAfterA (memList, (PB->processID) * PB->targetSize + startAddress, size);
            if (PB->targetOffset == -1)
              HandleError (__func__, "Allocation problem!", 0, ERR_ABORT);

            PB->targetSize = size;
          }
        break;
      case PAT:
        /* 4-PARTITIONING */
        if ((isRead == true) || (PB->nbPartition > 16))
          {
            PB->targetOffset =  0;
            PB->targetSize = ((int32_t) (PB->deviceSize / (MAX_PARTITIONS * BLOCK))) * MAX_PARTITIONS * BLOCK;
          }
        else
          {
            /* SEQUENTIAL WRITE..... CAUTION : PARTITIONNING EXPERIMENT MUST BE THE FIRST ... */
            if (startAddress == 0)
              startAddress = MemMinAddress(memList);

            if ((size % (16 * BLOCK)) != 0)
              size = ((int32_t) (size / (16 * BLOCK)) + 1 ) * (16 * BLOCK);

            PB->targetSize = PB->deviceSize - startAddress - size * nbVal * PB->nbRun;
            PB->targetSize = (int32_t) (PB->targetSize / (16 * BLOCK)) * (16 * BLOCK);
            if (PB->targetSize < size)
              HandleError (__func__, "device too small", 0, ERR_ABORT);

            PB->targetOffset = startAddress + shift;
            for (int32_t k = 0; k < PB->nbPartition; ++k)
              {
                long temp;
                temp = MemAlloc(memList, PB->targetOffset + k * PB->targetSize / PB->nbPartition,
                                PB->targetOffset + k * PB->targetSize / PB->nbPartition + size / PB->nbPartition);
                if (temp == -1)
                  HandleError (__func__, "Allocation problem!", 0, ERR_ABORT);

              }
            shift = shift + size / PB->nbPartition;
          }
        break;
      default:
        /* nothing to do */
        break;
    }

  if (PB->targetOffset == INT32_MAX)
    HandleError (__func__, "device too small", 0, ERR_ABORT);

  if ((PB->order >= 0) && (PB->targetOffset + PB->targetSize > PB->deviceSize))
    {
      char st [MAX_STR];

      sprintf (st, "Adjusting TargetSize (TO = %d, TS = %d DS = %d\n", PB->targetOffset, PB->targetSize, PB->deviceSize);
      PB->targetSize = PB->deviceSize - PB->targetOffset;
      PB->warning = PB->warning | TEST_EXCEED_DEVICE;
      OutputString (OUT_LOG, st);
    }

  if ((PB->order < 0) && (PB->targetOffset - PB->targetSize < 0))
    {
      char st [MAX_STR];

      sprintf (st, "Adjusting TargetSize Reverse Order (TO = %d, TS = %d DS = %d\n", PB->targetOffset, PB->targetSize, PB->deviceSize);
      PB->targetSize = PB->targetOffset;
      PB->warning = PB->warning | TEST_EXCEED_DEVICE;
      OutputString (OUT_LOG, st);
    }
}