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
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- #define INCL_DOS
- #define INCL_DOSDEVICES
- #define INCL_DOSDEVIOCTL
- #define INCL_DOSERRORS
- //#define INCL_NOPM
- #include <os2.h>
-
- #include "diskacc2.h"
-
- #define INTERVAL 10
-
- int nHandle;
- unsigned nSides, nTracks, nSectors;
- char *pBuffer;
-
- int time_over;
- double dhry_time, dhry_result;
-
- extern unsigned long Number_Of_Runs;
- extern long dhry_stone(void);
- extern void err(char* s);
-
- int bench_dhry(void);
-
- VOID APIENTRY timer_thread(ULONG nArg)
- {
- #if 1
- HEV hSem;
- HTIMER hTimer;
-
- DosCreateEventSem(0, &hSem, DC_SEM_SHARED, 0);
- DosAsyncTimer(nArg * 1000, (HSEM) hSem, &hTimer);
- DosWaitEventSem(hSem, SEM_INDEFINITE_WAIT);
- DosStopTimer(hTimer);
- DosCloseEventSem(hSem);
- #else
- DosSleep(nArg * 1000);
- #endif
-
- time_over = 1;
- Number_Of_Runs = 0;
-
- DosExit(EXIT_THREAD, 0);
- }
-
- int start_alarm(ULONG nSeconds)
- {
- TID ttid;
-
- time_over = 0;
- Number_Of_Runs = -1;
-
- if (DosCreateThread(&ttid, timer_thread, nSeconds, 0, 8192))
- {
- err("Cannot create timer thread");
- return -1;
- }
-
- return 0;
- }
-
- int start_timer(QWORD *nStart)
- {
- if (DosTmrQueryTime(nStart))
- {
- err("Timer error");
- return -1;
- }
-
- return 0;
- }
-
- int stop_timer(QWORD *nStart, int accuracy)
- {
- QWORD nStop;
- ULONG nFreq;
-
- if (DosTmrQueryTime(&nStop))
- {
- err("Timer error 2");
- return -1;
- }
- if (DosTmrQueryFreq(&nFreq))
- {
- err("Timer error 3");
- return -1;
- }
-
- nFreq = (nFreq + accuracy / 2) / accuracy;
-
- return (nStop.ulLo - nStart->ulLo) / nFreq;
- }
-
- int bench_transfer(int nTrack, int nDirection)
- {
- int nCnt, nData = 0, nTime, Dxfer;
- QWORD nLocal;
-
- //printf("Data transfer rate on track %-4d: ", nTrack);
- //fflush(stdout);
-
- if (start_alarm(INTERVAL))
- return -1;
-
- if (start_timer(&nLocal))
- return -1;
-
- for (nCnt = 0; !time_over; nCnt++)
- {
- if (DskRead(nHandle, nCnt % nSides, nTrack + (nCnt / nSides) * nDirection, 1, nSectors, pBuffer))
- {
- err("Disk read error - bench transfer.");
- return -1;
- }
-
- nData += nSectors * 512;
- }
-
- if ((nTime = stop_timer(&nLocal, 1024)) == -1)
- return -1;
-
- Dxfer = nData / nTime;
-
- return Dxfer;
- }
-
- int bench_bus(void)
- {
- int nCnt, nData = 0, nTime, Dxfer;
- QWORD nLocal;
-
- //printf("Drive cache/bus transfer rate: ");
- //fflush(stdout);
-
- if (start_alarm(INTERVAL))
- return -1;
-
- if (start_timer(&nLocal))
- return -1;
-
- for (nCnt = 0; !time_over; nCnt++)
- {
- if (DskRead(nHandle, 0, 0, 1, nSectors, pBuffer))
- {
- err("Disk read error - bus/cache.");
- return -1;
- }
-
- nData += nSectors * 512;
- }
-
- if ((nTime = stop_timer(&nLocal, 1024)) == -1)
- return -1;
-
- Dxfer = nData / nTime;
-
- return Dxfer;
- }
-
- int bench_latency(void)
- {
- int nCnt, nSector, nTime;
- QWORD nLocal;
-
- //printf("Average latency time: ");
- //fflush(stdout);
-
- srand(1);
-
- if (start_alarm(INTERVAL))
- return -1;
-
- if (start_timer(&nLocal))
- return -1;
-
- for (nCnt = 0; !time_over; nCnt++)
- {
- nSector = rand() * nSectors / RAND_MAX + 1;
-
- if (DskRead(nHandle, 0, 0, nSector, 1, pBuffer))
- {
- err("Disk read error - bench latency.");
- return -1;
- }
- }
-
- if ((nTime = stop_timer(&nLocal, 1000)) == -1)
- return -1;
-
- nTime = nTime * 10 / nCnt;
-
- //printf("%d.%d ms\n", nTime / 10, nTime % 10);
-
- return nTime;
- }
-
- int bench_seek(void)
- {
- int nCnt, nTrack, nTime;
- QWORD nLocal;
-
- //printf("Average data access time: ");
- //fflush(stdout);
-
- srand(1);
-
- if (start_alarm(INTERVAL))
- return -1;
-
- if (start_timer(&nLocal))
- return -1;
-
- for (nCnt = 0; !time_over; nCnt++)
- {
- nTrack = rand() * nTracks / RAND_MAX;
-
- if (DskRead(nHandle, 0, nTrack, 1, 1, pBuffer))
- {
- err("Disk read error - bench seek.");
- return -1;
- }
- }
-
- if ((nTime = stop_timer(&nLocal, 1000)) == -1)
- return -1;
-
- nTime = nTime * 10 / nCnt;
-
- //printf("%d.%d ms\n", nTime / 10, nTime % 10);
-
- return nTime;
- }
-
- VOID APIENTRY dhry_thread(ULONG nArg)
- {
- APIRET rc;
-
- rc = DosSetPriority(PRTYS_THREAD, PRTYC_IDLETIME, PRTYD_MAXIMUM, 0);
-
- dhry_time = dhry_stone();
-
- DosExit(EXIT_THREAD, 0);
- }
-
-
- double bench_concurrent(void)
- {
- int nCnt, nData = 0, nTime;
- double percent;
- QWORD nLocal;
- TID dtid;
- APIRET rc;
-
- if (start_alarm(INTERVAL))
- return -1;
-
- if (DosCreateThread(&dtid, dhry_thread, 0, 0, 8192))
- return -1;
-
- if (start_timer(&nLocal))
- return -1;
-
- for (nCnt = 0; !time_over; nCnt++)
- {
- if (DskRead(nHandle, 0, 0, 1, nSectors, pBuffer))
- {
- err("Disk read error - concurrency test.");
- return -1;
- }
-
- nData += nSectors * 512;
- }
-
- if ((nTime = stop_timer(&nLocal, 1024)) == -1)
- return -1;
-
- if ((rc = DosWaitThread(&dtid, DCWW_WAIT)) && rc != ERROR_INVALID_THREADID)
- return -1; /* it may have already terminated */
-
- dhry_time = (dhry_time + 500) / 1000;
-
- percent = ((dhry_result-(Number_Of_Runs / dhry_time)) * 100 / dhry_result);
-
- return percent;
- }
-
- int bench_disk(int nDisk)
- {
- char szName[8];
-
- sprintf(szName, "$%d:", nDisk);
-
- if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0)
- {
- err("Cannot access disk");
- return -1;
- }
-
- // printf("\nDisk %d: %d sides, %d cylinders, %d sectors per track = %d MB\n", nDisk, nSides, nTracks, nSectors, nSides * nTracks * nSectors / 2048);
-
- if ((pBuffer = malloc(nSectors * 512)) == NULL)
- {
- err("Not enough memory - bench disk.");
- return -1;
- }
-
- bench_bus();
- bench_transfer(0, 1);
- bench_transfer(nTracks - 1, -1);
- // bench_concurrent();
- bench_latency();
- bench_seek();
-
- free(pBuffer);
- DskClose(nHandle);
-
- return 0;
- }
-
- static double bench_disk_avseek(int nDisk)
- {
- char szName[8];
- double r;
-
- sprintf(szName, "$%d:", nDisk);
-
- if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0) {
- err("Disk IO test error : Cannot access disk - avseek.");
- exit(1);
- }
-
- if ((pBuffer = malloc(nSectors * 512)) == NULL) {
- err("Disk IO test error : malloc() failed.");
- exit(1);
- }
-
- r = bench_seek();
-
- 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, 0, &nSides, &nTracks, &nSectors)) < 0) {
- err("Disk IO test error : Cannot access disk - bench disk xfer.");
- exit(1);
- }
-
- if ((pBuffer = malloc(nSectors * 512)) == NULL) {
- err("Disk IO test error : malloc() failed.");
- exit(1);
- }
-
- r = (bench_transfer(nTracks-1, -1)+bench_transfer(0, 1)+bench_transfer(nTracks/2, 1))/3;
-
- 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_buscache_xfer(int disknr)
- {
- double r;
- char szName[8];
-
- disknr++;
-
- sprintf(szName, "$%d:", disknr);
-
- if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0)
- {
- err("Cannot access disk");
- return -1;
- }
-
- if ((pBuffer = malloc(nSectors * 512)) == NULL)
- {
- err("Not enough memory - bus cache test.");
- return -1;
- }
-
- r = bench_bus();
-
- free(pBuffer);
- DskClose(nHandle);
- return r;
- }
-
- double pmb_diskio_transfer(int disknr)
- {
- double r;
-
- disknr++;
- r = bench_disk_transfer(disknr);
-
- return r;
- }
-
- double pmb_diskio_cpupct(int disknr)
- {
- double r;
- char szName[8];
- APIRET rc;
-
- disknr++;
-
- sprintf(szName, "$%d:", disknr);
-
- if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0)
- {
- err("Cannot access disk - cpu percent");
- return -1;
- }
-
- if ((pBuffer = malloc(nSectors * 512)) == NULL)
- {
- err("Not enough memory - cpu percent test.");
- return -1;
- }
-
- rc = DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0);
-
- r = bench_dhry(); /* get base value for CPU when we're running at hi priority */
-
- rc = DosSetPriority(PRTYS_THREAD, PRTYC_REGULAR, 0, 0);
-
- r = bench_concurrent();
-
- free(pBuffer);
- DskClose(nHandle);
- return r;
- }
-
- int bench_dhry(void)
- {
- int nTime;
- QWORD nLocal;
- TID dtid;
- APIRET rc;
-
- if (start_alarm(INTERVAL))
- return -1;
-
- /* if (DosCreateThread(&dtid, dhry_thread, 0, 0, 8192))
- return -1; */
-
- if (start_timer(&nLocal))
- return -1;
-
- dhry_time = dhry_stone();
-
- if ((nTime = stop_timer(&nLocal, 1024)) == -1)
- return -1;
-
- /* if ((rc = DosWaitThread(&dtid, DCWW_WAIT)) && rc != ERROR_INVALID_THREADID)
- return -1; /* it may have already terminated */
-
- dhry_time = (dhry_time + 500) / 1000;
-
- dhry_result = Number_Of_Runs / dhry_time;
-
- return 0;
- }
-
-
-
- // return number of bytes on disk nDisk
- double pmb_diskio_disksize(int nDisk) {
- char szName[8];
-
- nDisk++;
-
- sprintf(szName, "$%d:", nDisk);
-
- if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0) {
- err("Disk IO test error : Cannot access disk.");
- exit(1);
- }
-
- DskClose(nHandle);
- return (nSides * nTracks * nSectors) / 2; /* divide by 2 to get Kb on disk */
- }
-
- int pmb_diskio_nrdisks(void) {
- USHORT nDisks;
- int nCount;
-
- if (DosPhysicalDisk(INFO_COUNT_PARTITIONABLE_DISKS, &nDisks, sizeof(nDisks), 0, 0)) {
- err("Disk IO test error : Cannot determine number of disks.");
- exit(1);
- }
- return nDisks;
- }