home *** CD-ROM | disk | FTP | other *** search
- /* diskio.c - disk benchmark
- *
- * Author: Kai Uwe Rommel <rommel@ars.muc.de>
- * Created: Fri Jul 08 1994
- */
-
- // modified 1994-08-10 by Henrik Harmsen
-
- #define INTERVAL 8
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <string.h>
-
- #define INCL_DOS
- #define INCL_DOSDEVICES
- #define INCL_DOSDEVIOCTL
- #define INCL_DOSERRORS
- #include <os2.h>
-
- static int DskOpen(char *drv, int lock,
- unsigned *sides, unsigned *tracks, unsigned *sectors);
- static int DskClose(int handle);
- static int DskRead(int handle, unsigned side, unsigned track,
- unsigned sector, unsigned nsects, void *buf);
- static int DskWrite(int handle, unsigned side, unsigned track,
- unsigned sector, unsigned nsects, void *buf);
-
-
- static int nHandle;
- static unsigned nSides, nTracks, nSectors;
- static char *pBuffer;
-
- static HEV hSemTimer;
- static HTIMER hTimer;
- static QWORD nStart, nStop;
-
- extern void err(char* s);
- extern void warn(char* s);
- extern void log(char* s);
-
- static int start_timer(void)
- {
- ULONG nPost;
- APIRET rc;
-
- if ((rc = DosResetEventSem(hSemTimer, &nPost)) && rc != ERROR_ALREADY_RESET) {
- log("Disk IO test : Semaphore error.");
- exit(1);
- }
-
- if(DosAsyncTimer(INTERVAL * 1000, (HSEM) hSemTimer, &hTimer)) {
- log("Disk IO test : Timer error.");
- exit(1);
- }
-
- if (DosTmrQueryTime(&nStart)) {
- log("Disk IO test : Timer error.");
- exit(1);
- }
-
- nPost = 0;
-
- return 0;
- }
-
- static int time_over(void)
- {
- ULONG nPost;
-
- if (DosQueryEventSem(hSemTimer, &nPost))
- err("Disk IO test:Semaphore error.\n"), 1;
-
- return nPost;
- }
-
- static int stop_timer(int accuracy)
- {
- ULONG nFreq;
-
- if (DosTmrQueryTime(&nStop))
- err("Disk IO test:Timer error.");
- if (DosTmrQueryFreq(&nFreq))
- err("Disk IO test:Timer error.");
-
- nFreq = (nFreq + accuracy / 2) / accuracy;
-
- return (nStop.ulLo - nStart.ulLo) / nFreq;
- }
-
- static int bench_transfer(void)
- {
- int nCnt, nData = 0, nTime;
-
- DosSleep(500);
-
- if (start_timer())
- err("disk io error: start timer error");
-
- for (nCnt = 0; !time_over(); nCnt++)
- {
- if (DskRead(nHandle, nCnt % nSides, nCnt / nSides, 1, nSectors, pBuffer))
- err("disk IO test error: Disk read error.");
-
- nData += nSectors * 512;
- }
-
- if ((nTime = stop_timer(1000)) == -1)
- err("disk io error: stop timer error");
-
- // printf("%d k/sec\n", nData / nTime);
-
- return (double)nData / ((double)nTime * 1.0e-3);
- }
-
- static double bench_latency(void)
- {
- int nCnt, nSector, nTime;
-
- srand(1);
-
- DosSleep(500);
-
- if (start_timer())
- err("disk io error: start timer error");
-
- for (nCnt = 0; !time_over(); nCnt++)
- {
- nSector = (rand() * nSectors) / RAND_MAX + 1;
-
- if (DskRead(nHandle, 0, 0, nSector, 1, pBuffer))
- err("disk IO test error: Disk read error.");
- }
-
- if ((nTime = stop_timer(1000)) == -1)
- err("disk io error: stop timer error");
-
- // nTime = nTime * 10 / nCnt;
-
- // printf("%d.%d ms\n", nTime / 10, nTime % 10);
-
- return (double)nTime/(double)nCnt*1.0e-3;
-
- }
-
- static double bench_seek(double nLatency)
- {
- int nCnt, nTrack, nTime;
-
- srand(1);
-
- DosSleep(500);
-
- if (start_timer())
- err("disk io error: start timer error");
-
- for (nCnt = 0; !time_over(); nCnt++)
- {
- nTrack = rand() * nTracks / RAND_MAX;
-
- if (DskRead(nHandle, 0, nTrack, 1, 1, pBuffer))
- err("disk IO test error: Disk read error.");
- }
-
- if ((nTime = stop_timer(1000)) == -1)
- err("disk io error: stop timer error");
-
- // nTime = nTime * 10 / nCnt;
-
- return (double)nTime/(double)nCnt*1.0e-3 - nLatency;
- }
-
- static double bench_disk_avseek(int nDisk)
- {
- char szName[8];
- double r;
-
- sprintf(szName, "$%d:", nDisk);
-
- if ((nHandle = DskOpen(szName, 0, &nSides, &nTracks, &nSectors)) < 0) {
- log("Disk IO test error : Cannot access disk.");
- exit(1);
- }
-
- if ((pBuffer = malloc(nSectors * 512)) == NULL) {
- log("Disk IO test error : malloc() failed.");
- exit(1);
- }
-
- r = bench_seek(bench_latency());
-
- free(pBuffer);
- DskClose(nHandle);
-
- return r;
- }
-
- static double bench_disk_transfer(int nDisk)
- {
- char szName[8];
- double r;
-
- sprintf(szName, "$%d:", nDisk);
-
- if ((nHandle = DskOpen(szName, 0, &nSides, &nTracks, &nSectors)) < 0) {
- log("Disk IO test error : Cannot access disk.");
- exit(1);
- }
-
- if ((pBuffer = malloc(nSectors * 512)) == NULL) {
- log("Disk IO test error : malloc() failed.");
- exit(1);
- }
-
- r = bench_transfer();
-
- free(pBuffer);
- DskClose(nHandle);
-
- return r;
- }
-
-
- double pmb_diskio_avseek(int disknr)
- {
- double r;
-
- disknr++;
-
- DosCreateEventSem(NULL, &hSemTimer, DC_SEM_SHARED, 0);
- DosSleep(500);
-
- r = bench_disk_avseek(disknr);
-
- DosCloseEventSem(hSemTimer);
- hSemTimer = 0;
- return r;
- }
-
- double pmb_diskio_transfer(int disknr)
- {
- double r;
-
- disknr++;
-
- DosCreateEventSem(NULL, &hSemTimer, DC_SEM_SHARED, 0);
- DosSleep(500);
-
- r = bench_disk_transfer(disknr);
-
- DosCloseEventSem(hSemTimer);
- hSemTimer = 0;
- return r;
- }
-
- // return number of bytes on disk nDisk
- int pmb_diskio_disksize(int nDisk) {
- char szName[8];
-
- nDisk++;
-
- sprintf(szName, "$%d:", nDisk);
-
- if ((nHandle = DskOpen(szName, 0, &nSides, &nTracks, &nSectors)) < 0) {
- log("Disk IO test error : Cannot access disk.");
- exit(1);
- }
-
- DskClose(nHandle);
- return nSides * nTracks * nSectors * 512;
- }
-
- int pmb_diskio_nrdisks(void) {
- USHORT nDisks;
- int nCount;
-
- if (DosPhysicalDisk(INFO_COUNT_PARTITIONABLE_DISKS, &nDisks, sizeof(nDisks), 0, 0)) {
- log("Disk IO test error : Cannot determine number of disks.");
- exit(1);
- }
- return nDisks;
- }
-
-
-
-
-
-
-
- #define PHYSICAL 0x1000
- #define CATEGORY(x) (((x) & PHYSICAL) ? IOCTL_PHYSICALDISK : IOCTL_DISK)
- #define HANDLE(x) ((x) & ~PHYSICAL)
-
- #pragma pack(1)
-
- typedef struct
- {
- BYTE bCommand;
- USHORT usHead;
- USHORT usCylinder;
- USHORT usFirstSector;
- USHORT cSectors;
- struct
- {
- USHORT usSectorNumber;
- USHORT usSectorSize;
- }
- TrackTable[64];
- }
- TRACK;
-
- static ULONG DosDevIOCtl32(PVOID pData, ULONG cbData, PVOID pParms, ULONG cbParms,
- ULONG usFunction, HFILE hDevice)
- {
- ULONG ulParmLengthInOut = cbParms, ulDataLengthInOut = cbData;
- return DosDevIOCtl(HANDLE(hDevice), CATEGORY(hDevice), usFunction,
- pParms, cbParms, &ulParmLengthInOut,
- pData, cbData, &ulDataLengthInOut);
- }
-
- static int test_sector(int handle, int side, int track, int sector)
- {
- char buffer[1024];
- TRACK trk;
-
- trk.bCommand = 0;
- trk.usHead = side;
- trk.usCylinder = track;
- trk.usFirstSector = 0;
- trk.cSectors = 1;
-
- trk.TrackTable[0].usSectorNumber = sector;
- trk.TrackTable[0].usSectorSize = 512;
-
- return DosDevIOCtl32(buffer, sizeof(buffer), &trk, sizeof(trk),
- DSK_READTRACK, handle) == 0;
- }
-
- static int DskOpen(char *drv, int lock,
- unsigned *sides, unsigned *tracks, unsigned *sectors)
- {
- BIOSPARAMETERBLOCK bpb;
- DEVICEPARAMETERBLOCK dpb;
- HFILE handle;
- USHORT physical;
- ULONG action;
- BYTE cmd = 0;
-
- if (isalpha(drv[0]) && drv[1] == ':' && drv[2] == 0)
- {
- if (DosOpen(drv, &handle, &action, 0L, FILE_NORMAL, FILE_OPEN,
- OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |
- OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE, 0L))
- return -1;
- }
- else if (drv[0] == '$' && isdigit(drv[1]) && drv[2] == ':' && drv[3] == 0)
- {
- if (DosPhysicalDisk(INFO_GETIOCTLHANDLE, &physical, sizeof(physical),
- drv + 1, strlen(drv + 1) + 1))
- return -1;
- handle = physical | PHYSICAL;
- }
- else
- return -1;
-
- if (handle & PHYSICAL)
- {
- if (DosDevIOCtl32(&dpb, sizeof(dpb), &cmd, sizeof(cmd),
- DSK_GETDEVICEPARAMS, handle))
- {
- DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0, &physical, sizeof(physical));
- return -1;
- }
-
- *sectors = dpb.cSectorsPerTrack;
- *tracks = dpb.cCylinders;
- *sides = dpb.cHeads;
- }
- else
- {
- if (DosDevIOCtl32(&bpb, sizeof(bpb), &cmd, sizeof(cmd),
- DSK_GETDEVICEPARAMS, handle))
- {
- DosClose(handle);
- return -1;
- }
-
- *sectors = bpb.usSectorsPerTrack;
- *tracks = bpb.cCylinders;
- *sides = bpb.cHeads;
- }
-
-
- if (lock && DosDevIOCtl32(0L, 0, &cmd, sizeof(cmd), DSK_LOCKDRIVE, handle))
- {
- if (handle & PHYSICAL)
- DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0, &physical, sizeof(physical));
- else
- DosClose(handle);
- return -1;
- }
-
- if (*sectors >= 15) /* 360k floppies ... */
- if (!test_sector(handle, 0, 0, 15))
- {
- if (*sectors == 15)
- *tracks = 40;
-
- *sectors = 9;
- }
-
- return handle;
- }
-
- static int DskClose(int handle)
- {
- BYTE cmd = 0;
- USHORT physical = handle & ~PHYSICAL;
-
- DosDevIOCtl32(0L, 0, &cmd, sizeof(cmd), DSK_UNLOCKDRIVE, handle);
-
- if (handle & PHYSICAL)
- return DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0,
- &physical, sizeof(physical));
- else
- return DosClose(handle);
- }
-
- static int DskRead(int handle, unsigned side, unsigned track,
- unsigned sector, unsigned nsects, void *buf)
- {
- TRACK trk;
- unsigned cnt;
-
- trk.bCommand = 0;
- trk.usHead = side;
- trk.usCylinder = track;
- trk.usFirstSector = 0;
- trk.cSectors = nsects;
-
- for (cnt = 0; cnt < nsects; cnt++)
- {
- trk.TrackTable[cnt].usSectorNumber = sector + cnt;
- trk.TrackTable[cnt].usSectorSize = 512;
- }
-
- return DosDevIOCtl32(buf, nsects * 512, &trk, sizeof(trk),
- DSK_READTRACK, handle);
- }
-
- static int DskWrite(int handle, unsigned side, unsigned track,
- unsigned sector, unsigned nsects, void *buf)
- {
- TRACK trk;
- unsigned cnt;
-
- trk.bCommand = 0;
- trk.usHead = side;
- trk.usCylinder = track;
- trk.usFirstSector = 0;
- trk.cSectors = nsects;
-
- for (cnt = 0; cnt < nsects; cnt++)
- {
- trk.TrackTable[cnt].usSectorNumber = sector + cnt;
- trk.TrackTable[cnt].usSectorSize = 512;
- }
-
- return DosDevIOCtl32(buf, nsects * 512, &trk, sizeof(trk),
- DSK_WRITETRACK, handle);
- }
-
-
-
-