/* Call me WRSpeedTest. I use Conduant's XLR functions to write a long * (broken) sequence of TVG data, which I then read back (no check). I * note the time each of these takes. The idea is to determine how fast * SS can read and write through the PCI bus presumably as a function * of how many SS disks are installed. Please use EndM5 if you need * to interrupt. Revised: 2004 April 21, JAB */ #include "Parse5A.h" #include /* For signal() to catch ^C */ #define NUMLOOPS 10000 /* Number of write loops */ // #include /* For time() */ #include /* For ftime() */ void signalint(int k); /* To catch signal SIGINT (below) */ SSHANDLE dev; /* xlrDevice */ UINT indx = 1; /* Index */ unsigned long baseRange; /* From XLRGetBaseRange() */ unsigned long * windowAddr; /* From XLRGetWindowAddr() */ char * me; /* My name */ int msglev = 0; /* Debug message level */ int main(int argc, char * argv[]) { /* WRSpeedTest */ unsigned long rbuff[BUFFL]; /* Write and read buffer */ int i; struct timeb time1, time2; /* From ftime() */ unsigned long plapnt[2]; /* Convert to and from long long */ unsigned long long * pplapnt = (unsigned long long *) plapnt; double dt; /* *** Initialize *** */ me = (me = strrchr(argv[0], '/')) == NULL ? argv[0] : me+1; /* My name */ /* ** Fill rbuff[] with TVG pattern ** */ for (i = 0; i < BUFFL; i++) rbuff[i] = tvg(i == 0); /* ** Initialize and check XLR ** */ if (XLRDeviceFind() <= 0) { /* StreamStor cards? */ (void) fprintf(stderr, "%s ERROR: \007 XLRDeviceFind() returned none \n", me); /* Error */ (void) errors(); return(-1); /* Error */ } if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s DEBUG: XLRDeviceFind() OK \n", me); (void) errors(); if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s DEBUG: Trying to XLROpen() ... \n", me); if (XLROpen(indx, &dev) != XLR_SUCCESS) { /* Open, OK? */ (void) fprintf(stderr, "%s ERROR: \007 XLROpen() returned error \n", me); /* Nope */ (void) errors(); XLRClose(dev); /* See manual notes on XLROpen() */ return(-2); /* Error */ } if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s DEBUG: XLROpen() OK \n", me); (void) errors(); signal(SIGINT, signalint); /* Catch interrupt signal */ /* * Get info for data write (which may not be needed) * */ windowAddr = XLRGetWindowAddr(dev); /* Data-write address */ (void) errors(); baseRange = XLRGetBaseRange(dev); /* Data-write size */ (void) errors(); if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s DEBUG: BaseRange %ld (not used) \n", me, baseRange); /* * SS mode to PCI for writing and reading * */ if (XLRSetMode(dev, SS_MODE_PCI) != XLR_SUCCESS) { /* Set mode, OK? */ (void) fprintf(stderr, "%s ERROR: \007 XLRSetMode() returned error \n", me); /* Nope */ (void) errors(); XLRClose(dev); /* See manual notes on XLROpen() */ return(-3); /* Error */ } (void) errors(); /* (FPDP mode is not used) */ ///* ** Erase any data already on SS disks ** */ //if (msglev < 1) /* Debuggery? */ // (void) fprintf(stderr, "%s DEBUG: Erasing SS disks \n", me); /* Yes */ //if (XLRRecord(dev, FALSE, 1) != XLR_SUCCESS) /* Record, OK? */ // (void) fprintf(stderr, /* Nope */ // "%s Parse5A() WARNING: XLRRecord() returned error \n", me); // /* We try to go on */ //(void) errors(); if (XLRStop(dev) != XLR_SUCCESS) /* Stop, OK? */ (void) fprintf(stderr, /* Nope */ "%s Parse5A() WARNING: XLRStop() returned error \n", me); /* We try to go on */ (void) errors(); (void) fprintf(stderr, "%s: Each loop is %d cycles of %d bytes \n", me, NUMLOOPS, sizeof(rbuff)); /* *** Write loop *** */ if (XLRAppend(dev) != XLR_SUCCESS) { /* Record, OK? */ (void) fprintf(stderr, /* Nope */ "%s Parse5A() ERROR: XLRAppend() returned error \n", me); (void) errors(); return(-4); /* Give up */ } (void) fprintf(stderr, "%s: Start write loop \n", me); (void) ftime(&time1); /* What time is it? */ for (i = 0; i < NUMLOOPS; i++) { /* Each of NUMLOOPS loops */ /* Two alternatives for writing data: */ if (XLRWriteData(dev, (void *) rbuff, sizeof(rbuff)) != XLR_SUCCESS) { /* Write to SS, OK? */ (void) fprintf(stderr, /* Nope */ "%s ERROR: XLRWriteData() returned error \n", me); (void) errors(); break; /* Error */ } } /* End of for i write loop */ (void) ftime(&time2); /* What time is it now? */ if (XLRStop(dev) != XLR_SUCCESS) { /* Stop, OK? */ (void) fprintf(stderr, /* Nope */ "%s ERROR: XLRStop() returned error \n", me); (void) errors(); return(-5); /* Give up */ } (void) errors(); /* ** Show results ** */ dt = time2.time + time2.millitm/1000.0 - time1.time - time1.millitm/1000.0; (void) fprintf(stderr, "%s Write i %d, time %.1f seconds, speed %.3e baud \n", me, i, dt, 8.0*i*sizeof(rbuff)/dt); /* *** Read loop *** */ (void) fprintf(stderr, "%s Start read loop \n", me); (void) ftime(&time1); /* What time is it? */ for (i = 0; i < NUMLOOPS; i++) { /* Each of NUMLOOPS loops */ *pplapnt = i * sizeof(rbuff); /* Play "pointer" */ if (XLRReadData(dev, rbuff, plapnt[1], plapnt[0], sizeof(rbuff)) != XLR_SUCCESS) { /* Read from SS, OK? */ (void) fprintf(stderr, /* Nope */ "%s ERROR: XLRReadData() returned error \n", me); (void) errors(); break; /* Error */ } } /* End of for i read loop */ (void) ftime(&time2); /* What time is it now? */ (void) errors(); /* ** Show results ** */ dt = time2.time + time2.millitm/1000.0 - time1.time - time1.millitm/1000.0; (void) fprintf(stderr, "%s Read i %d, time %.1f seconds, speed %.3e baud \n", me, i, dt, 8.0*i*sizeof(rbuff)/dt); /* *** Done *** */ XLRClose(dev); /* See manual notes on XLROpen() */ (void) errors(); if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, "%s DEBUG: XLRClose() done \n", me); /* Yes */ return(0); /* The end */ } /* End of main = TVGmTest */ int errors() { /* XLR errors? Print XLR error code if so */ extern char * me; /* My name */ extern int msglev; /* Debug print? */ char messg[XLR_ERROR_LENGTH]; /* Error message as a string */ XLR_ERROR_CODE error; /* Return from error request */ if ((error = XLRGetLastError()) != 3) { /* Errors? */ /* Yes, get error message */ if (XLRGetErrorMessage(messg, error) != XLR_SUCCESS) { /* OK? */ if (msglev < 2) /* Nope. Debuggery? */ (void) fprintf(stderr, "%s errors() ERROR: XLR error %ld, " "but XLRGetErrorMessage() failed \n", me, error); } else /* Error message, messg[], OK */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s ERROR: XLR error %ld %s \n", me, error, messg); return(TRUE); /* Yes, XLR error */ } return(FALSE); /* Else no error */ } /* End of errors() */ unsigned long tvg(int init) { /* Calculate the test-vector-generator (TVG) pattern. * Reference: VSI-H Specification, Rev 1.0, 7 August 2000, available * at http://web.haystack.mit.edu/vsi/. See especially Figure 6, * page 29 and Table 13, page 20. Referring to Figure 6, q (below) * represents the Q outputs of the flip-flops, r the upper inputs of * the exors, and u the lower 16 bits of the answer (output). * Revised: 2001 December 18, JAB */ static unsigned short q; unsigned short r, u; if (init) /* Initialize? */ q = 0xffff; /* Yes */ /* Set r to a copy of q right shifted by 1 bit */ r = q >> 1; /* And set r bit 15 to a copy of q bit 2 */ if (q & 4) /* Bit 2 set? */ r |= 0x8000; /* Yes */ /* We need to overwrite r bit 14 with a copy of u bit 0, * so we need to do q exor r temporarily to get this bit */ if ((q ^ r) & 1) /* Bit 0 set? */ r |= 0x4000; /* Yes */ else /* Not set */ r &= 0xbfff; /* Now set u to q exor r */ u = q ^ r; /* Lower 16 bits of the answer */ /* For next time, set q to a copy of u right shifted by 1 bit */ q = u >> 1; /* And set q bit 15 (invisible) to a copy of q bit 0 */ if (q & 1) /* Bit 0 set? */ q |= 0x8000; /* Yes */ /* u has the lower 16 bits of the answer; the upper 16 bits * are the lower 16 bits inverted and shifted up there */ return(((unsigned long) ~u << 16) + u); } /* End of tvg() */ void signalint(int k) { /* To catch interrupt signal SIGINT */ /* (k is not used) */ extern SSHANDLE dev; /* xlrDevice */ extern char * me; /* My name */ extern int msglev; /* Debug message level */ if (msglev < 2) /* Debuggery? */ (void) fprintf(stderr, "%s INTERRUPT \n", me); /* Yes */ /* An XLRReset() here allows swapping disks after XLRClose() below */ if (XLRReset(dev) != XLR_SUCCESS) { /* OK? */ if (msglev < 2) /* No. Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s WARNING: XLRReset() returned error \n", me); (void) errors(); } else if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, "%s DEBUG: XLRReset() OK \n", me); XLRClose(dev); /* See manual notes on XLROpen() */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, "%s DEBUG: XLRClose() done \n", me); /* Yes */ if (msglev < 2) /* Debuggery? */ (void) printf("%s: The End \n", me); exit(0); /* Bye */ } /* End of signalint() */