home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff329.lzh
/
DiskSpeed
/
DiskSpeed.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-02
|
18KB
|
663 lines
/*
* DiskSpeed v3.0
* by
* Michael Sinz
*
* Copyright (c) 1989 by MKSoft Development
*
* MKSoft Development
* 163 Appledore Drive
* Downingtown, PA 19335
*
* Yes, this is yet another disk speed testing program, but with a few
* differences. It was designed to give the most accurate results of the
* true disk performance in the system. For this reason many of
* DiskSpeed's results may look either lower or higher than current disk
* performance tests.
*
* This program was thrown together in a few hours because I needed more
* accurate and consistent results for disk performance as seen from the
* application's standpoint. This program has now served its purpose and
* I am now giving it to the rest of the Amiga world to play with as long
* as all of the files remain together in unmodified form. (That is, the
* files DiskSpeed, DiskSpeed.info, DiskSpeed.c, DiskSpeedWindow.c,
* DiskSpeedWindow.h, MakeBoxes.c, MakeBoxes.h, StandardGadgets.c,
* StandardGadgets.h, RenderInfo.c, RenderInfo.h, DiskSpeed.doc, and
* MakeFile)
*
* Version 2.0 of this program added a few features and cleaned up the
* user interface. I hope you like this...
*
* Version 3.0 of this program added the performance stress and cleaned up
* some parts of the older code. (Fix to RenderInfo.c)
*
******************************************************************************
* *
* Reading legal mush can turn your brain into guacamole! *
* *
* So here is some of that legal mush: *
* *
* Permission is hereby granted to distribute this program's source *
* executable, and documentation for non-commercial purposes, so long as the *
* copyright notices are not removed from the sources, executable or *
* documentation. This program may not be distributed for a profit without *
* the express written consent of the author Michael Sinz. *
* *
* This program is not in the public domain. *
* *
* Fred Fish is expressly granted permission to distribute this program's *
* source and executable as part of the "Fred Fish freely redistributable *
* Amiga software library." *
* *
* Permission is expressly granted for this program and it's source to be *
* distributed as part of the Amicus Amiga software disks, and the *
* First Amiga User Group's Hot Mix disks. *
* *
******************************************************************************
*
* Main code and testing sections...
*/
#include <EXEC/Types.h>
#include <EXEC/Memory.h>
#include <Intuition/Intuition.h>
#include <Libraries/DOS.h>
#include <Libraries/DOSextens.h>
#include <Graphics/RastPort.h>
#include <Devices/Timer.h>
#include <PROTO/All.h>
#include <string.h>
#include "RenderInfo.h"
#include "DiskSpeedWindow.h"
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
struct Library *TimerBase;
#define TIMESCALER 256L
#define SEEK_READ_SIZE 300L
#define IO_BUFFER_SIZE 262144L
/* Define the file name limits for file create/delete/open/scan */
#define FINAL 'R'
static char ErrorText1[28] ="Can't create test directory";
static char ErrorText2[16] ="Bad device name";
static char ErrorText3[24] ="Can't open results file";
static char ErrorText4[19] ="Can't open printer";
static char PrinterFile[5] ="PRT:";
static char ResultFile[18] ="DiskSpeed.Results";
static char DirectoryName[22] =" Disk Test Directory ";
static char FileNameRoot[22] =" -- DiskTest File -- ";
static char Testing_String[10] =">Testing<";
/* The Wait pointer I use... */
USHORT __chip WaitPointer[48] =
{
0x0000, 0x0000, 0x6700, 0xC700, 0xCFA0, 0xCFA0, 0xBFF0, 0x3FF0,
0x70F8, 0x7FF8, 0x7DFC, 0x7FFC, 0xFBFC, 0xFFFC, 0x70FC, 0x7FFC,
0x7FFE, 0x7FFE, 0x7F0E, 0x7FFE, 0x3FDF, 0x3FFF, 0x7FBE, 0x7FFE,
0x3F0E, 0x3FFE, 0x1FFC, 0x1FFC, 0x07F8, 0x07F8, 0x01E0, 0x01E0,
0x0780, 0x0780, 0x0FE0, 0x0FE0, 0x0740, 0x0740, 0x0000, 0x0000,
0x0070, 0x0070, 0x0078, 0x0078, 0x0030, 0x0030, 0x0000, 0x0000,
};
/*
* These two defines set up and clear the WaitPointer...
*/
#define SetWait(x) SetPointer(x,WaitPointer,22L,16L,NULL,NULL)
#define ClearWait(x) ClearPointer(x)
/*
* This does a requester on the window to tell the user something...
*/
VOID TellUser(struct MyWindow *MyWindow,char *Text)
{
register struct IntuiMessage *msg;
register SHORT flag=TRUE;
MyWindow->ReqIText.LeftEdge=(MyWindow->Req.Width>>1)-(strlen(Text)<<2);
MyWindow->ReqIText.IText=Text;
Request(&(MyWindow->Req),MyWindow->Window);
while (flag)
{
WaitPort(MyWindow->Window->UserPort);
while (msg=(struct IntuiMessage *)GetMsg(MyWindow->Window->UserPort))
{
if (msg->Class==GADGETUP)
{
if (((struct Gadget *)(msg->IAddress))->GadgetID==GADGET_REQ) flag=FALSE;
}
ReplyMsg((struct Message *)msg);
}
}
EndRequest(&(MyWindow->Req),MyWindow->Window);
}
/*
* Returns FALSE if the user clicked on the CLOSE gadget...
*/
SHORT Check_Quit(struct MyWindow *MyWindow)
{
register struct IntuiMessage *msg;
register SHORT flag=TRUE;
while(msg=(struct IntuiMessage *)GetMsg(MyWindow->Window->UserPort))
{
if (msg->Class==CLOSEWINDOW) flag=FALSE;
ReplyMsg((struct Message *)msg);
}
return(flag);
}
/*
* Clears a string entry to spaces...
*/
VOID Clear_Entry(char *String)
{
register SHORT t;
for (t=0;t<9;t++) String[t]=' ';
String[9]='\0';
}
/*
* Sets a string entry to the string >Testing< and does a
* PrintIText() to display it...
*/
VOID Set_Testing(SHORT ResultNum,struct MyWindow *MyWindow)
{
strcpy(MyWindow->MyResults[ResultNum].text,Testing_String);
PrintIText(MyWindow->Window->RPort,&(MyWindow->MyResults[ResultNum].IntuiText),NULL,NULL);
}
/*
* Sets a string entry to the value passed and does a PrintIText()
* to display it...
*/
VOID Set_Entry(SHORT ResultNum,LONG Value,struct MyWindow *MyWindow)
{
register SHORT t;
register SHORT tmp;
register char *String;
String=MyWindow->MyResults[ResultNum].text;
Clear_Entry(String);
t=9;
while (Value)
{
tmp=Value%10;
Value=Value/10;
String[--t]=(char)(tmp)+'0';
}
if (!String[t]) String[--t]='0';
PrintIText(MyWindow->Window->RPort,&(MyWindow->MyResults[ResultNum].IntuiText),NULL,NULL);
}
/*
* This gets the starting time...
*/
VOID Timer_Start(struct MyWindow *MyWindow)
{
register struct timerequest *Time_Req;
Time_Req=&(MyWindow->TimeReq);
Time_Req->tr_node.io_Command=TR_GETSYSTIME;
Time_Req->tr_node.io_Flags=IOF_QUICK;
DoIO((struct IORequest *)Time_Req);
MyWindow->StartTime=Time_Req->tr_time;
}
/*
* This gets the ending time and finds out what the per second speed is...
* It also does a RefreshGadgets() to display the text...
*/
VOID Timer_Stop(struct MyWindow *MyWindow,SHORT ResultNum,LONG Number)
{
register struct timerequest *Time_Req;
register LONG Value;
Time_Req=&(MyWindow->TimeReq);
Time_Req->tr_node.io_Command=TR_GETSYSTIME;
Time_Req->tr_node.io_Flags=IOF_QUICK;
DoIO((struct IORequest *)Time_Req);
MyWindow->StopTime=Time_Req->tr_time;
SubTime(&(MyWindow->StopTime),&(MyWindow->StartTime));
/* Now calculate Value based on Number and the time... */
Value=(Number*TIMESCALER) /
( (MyWindow->StopTime.tv_secs*TIMESCALER) +
(MyWindow->StopTime.tv_micro/(1000000L/TIMESCALER))
);
Set_Entry(ResultNum,Value,MyWindow);
}
/*
* File create test...
* This creates a bunch of files in our test directory...
* The delete test deletes these files...
*/
VOID Do_FileCreate_Test(struct MyWindow *MyWindow)
{
register char *t1;
register char *t2;
register BPTR file;
register LONG count=0;
t1=FileNameRoot+1;
t2=t1+1;
Set_Testing(RESULTS_CREATE,MyWindow);
Timer_Start(MyWindow);
for (*t1='A';*t1<FINAL;(*t1)++) for (*t2='A';*t2<FINAL;(*t2)++)
{
if (file=Open(FileNameRoot,MODE_NEWFILE)) Close(file);
count++;
}
Timer_Stop(MyWindow,RESULTS_CREATE,count);
}
/*
* File Open/Close test...
* This Opens/Closes a bunch of files in our test directory...
*/
VOID Do_OpenClose_Test(struct MyWindow *MyWindow)
{
register char *t1;
register char *t2;
register BPTR file;
register LONG count=0;
t1=FileNameRoot+1;
t2=t1+1;
Set_Testing(RESULTS_OPEN_CLOSE,MyWindow);
Timer_Start(MyWindow);
for (*t1='A';*t1<FINAL;(*t1)++) for (*t2='A';*t2<FINAL;(*t2)++)
{
if (file=Open(FileNameRoot,MODE_OLDFILE)) Close(file);
count++;
}
Timer_Stop(MyWindow,RESULTS_OPEN_CLOSE,count);
}
/*
* Directory scan test... This is done by scanning the directory we
* just created in the create test... (Three times...)
*/
VOID Do_DirScan_Test(struct MyWindow *MyWindow)
{
register struct FileInfoBlock *FIB;
register BPTR lock;
register LONG count=0;
register SHORT loop;
lock=CurrentDir(NULL); /* Get our directory lock... */
if (FIB=AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC))
{
Set_Testing(RESULTS_DIR_SCAN,MyWindow);
Timer_Start(MyWindow);
for (loop=0;loop<3;loop++)
{
Examine(lock,FIB);
while (ExNext(lock,FIB)) count++;
}
Timer_Stop(MyWindow,RESULTS_DIR_SCAN,count);
FreeMem(FIB,sizeof(struct FileInfoBlock));
}
CurrentDir(lock); /* Return the locked directory... */
}
/*
* File delete test... We delete the files created in the create test...
*/
VOID Do_FileDelete_Test(struct MyWindow *MyWindow)
{
register char *t1;
register char *t2;
register LONG count=0;
t1=FileNameRoot+1;
t2=t1+1;
Set_Testing(RESULTS_DELETE,MyWindow);
Timer_Start(MyWindow);
for (*t1='A';*t1<FINAL;(*t1)++) for (*t2='A';*t2<FINAL;(*t2)++)
{
DeleteFile(FileNameRoot);
count++;
}
Timer_Stop(MyWindow,RESULTS_DELETE,count);
}
/*
* This does the seek/read test...
*/
VOID Do_SeekRead_Test(struct MyWindow *MyWindow,char *Buffer)
{
register short t;
register LONG count=0;
register LONG pos;
register BPTR bigfile;
if (bigfile=Open(FileNameRoot,MODE_NEWFILE))
{
Set_Testing(RESULTS_SEEK_READ,MyWindow);
Write(bigfile,Buffer,IO_BUFFER_SIZE);
Timer_Start(MyWindow);
for (t=0;t<200;t++)
{
Seek(bigfile,0L,OFFSET_BEGINNING);
Read(bigfile,Buffer,SEEK_READ_SIZE);
count++;
pos=Seek(bigfile,-(2*SEEK_READ_SIZE),OFFSET_END);
Read(bigfile,Buffer,SEEK_READ_SIZE);
count++;
Seek(bigfile,-(pos>>1),OFFSET_CURRENT);
Read(bigfile,Buffer,SEEK_READ_SIZE);
count++;
}
Timer_Stop(MyWindow,RESULTS_SEEK_READ,count);
Close(bigfile);
DeleteFile(FileNameRoot);
}
}
/*
* This does the testing at a set buffer size...
*/
SHORT Do_File_Test(LONG BufSize,struct MyWindow *MyWindow,UBYTE *Buffer,SHORT ResultNum)
{
register SHORT flag=TRUE;
register SHORT t;
register SHORT loop;
register LONG count;
register LONG numblocks;
register BPTR bigfile;
if (bigfile=Open(FileNameRoot,MODE_NEWFILE))
{
numblocks=IO_BUFFER_SIZE/BufSize;
if (flag&=Check_Quit(MyWindow))
{
count=0;
Set_Testing(ResultNum,MyWindow);
Timer_Start(MyWindow);
for (t=0;t<(1<<(MyWindow->TestFlag));t++)
{
Close(bigfile);
bigfile=Open(FileNameRoot,MODE_NEWFILE);
for (loop=0;loop<numblocks;loop++) count+=Write(bigfile,Buffer,BufSize);
}
Timer_Stop(MyWindow,ResultNum++,count);
}
if (flag&=Check_Quit(MyWindow))
{
count=0;
Set_Testing(ResultNum,MyWindow);
Timer_Start(MyWindow);
for (t=0;t<(2<<(MyWindow->TestFlag));t++)
{
Seek(bigfile,NULL,OFFSET_BEGINNING);
for (loop=0;loop<numblocks;loop++) count+=Write(bigfile,Buffer,BufSize);
}
Timer_Stop(MyWindow,ResultNum++,count);
}
if (flag&=Check_Quit(MyWindow))
{
count=0;
Set_Testing(ResultNum,MyWindow);
Timer_Start(MyWindow);
for (t=0;t<(3<<(MyWindow->TestFlag));t++)
{
Seek(bigfile,NULL,OFFSET_BEGINNING);
for (loop=0;loop<numblocks;loop++) count+=Read(bigfile,Buffer,BufSize);
}
Timer_Stop(MyWindow,ResultNum++,count);
}
Close(bigfile);
DeleteFile(FileNameRoot);
}
return(flag);
}
/*
* This is the master test routine... It calles the ones above...
*/
VOID Do_Disk_Test(struct MyWindow *MyWindow)
{
register BPTR lock;
register BPTR mydir;
register SHORT flag=TRUE;
register UBYTE *Buffer;
register SHORT loop;
register struct Gadget *gad;
for (loop=0;loop<NUM_GADGETS;loop++)
{
gad=&(MyWindow->MyGadgets[loop].Gadget);
RemoveGadget(MyWindow->Window,gad);
gad->Flags|=GADGDISABLED;
AddGadget(MyWindow->Window,gad,NULL);
RefreshGList(gad,MyWindow->Window,NULL,1L);
}
if (lock=Lock(MyWindow->DeviceName,ACCESS_READ))
{
lock=CurrentDir(lock);
if (mydir=CreateDir(DirectoryName))
{
mydir=CurrentDir(mydir);
for (loop=0;loop<NUM_RESULTS;loop++)
{
Clear_Entry(MyWindow->MyResults[loop].text);
}
RefreshGList(&(MyWindow->Detail),MyWindow->Window,NULL,1L);
Stress_On(MyWindow);
if (flag&=Check_Quit(MyWindow))
{
Do_FileCreate_Test(MyWindow);
if (flag&=Check_Quit(MyWindow)) Do_OpenClose_Test(MyWindow);
if (flag&=Check_Quit(MyWindow)) Do_DirScan_Test(MyWindow);
Do_FileDelete_Test(MyWindow);
}
if (Buffer=AllocMem(IO_BUFFER_SIZE,MEMF_PUBLIC))
{
if (flag&=Check_Quit(MyWindow)) Do_SeekRead_Test(MyWindow,Buffer);
if (flag&=Check_Quit(MyWindow)) flag&=Do_File_Test(512L,MyWindow,Buffer,RESULTS_512_CREATE);
if (flag&=Check_Quit(MyWindow)) flag&=Do_File_Test(4096L,MyWindow,Buffer,RESULTS_4096_CREATE);
if (flag&=Check_Quit(MyWindow)) flag&=Do_File_Test(32768L,MyWindow,Buffer,RESULTS_32768_CREATE);
if (flag&=Check_Quit(MyWindow)) flag&=Do_File_Test(262144L,MyWindow,Buffer,RESULTS_262144_CREATE);
FreeMem(Buffer,IO_BUFFER_SIZE);
}
Stress_Off(MyWindow);
mydir=CurrentDir(mydir);
UnLock(mydir);
DeleteFile(DirectoryName);
}
else
{ /* Tell user he messed up... */
TellUser(MyWindow,ErrorText1);
}
lock=CurrentDir(lock);
UnLock(lock);
}
else
{ /* Tell user he messed up... */
TellUser(MyWindow,ErrorText2);
}
for (loop=0;loop<NUM_GADGETS;loop++)
{
gad=&(MyWindow->MyGadgets[loop].Gadget);
RemoveGadget(MyWindow->Window,gad);
gad->Flags&=~GADGDISABLED;
AddGadget(MyWindow->Window,gad,NULL);
}
RefreshGadgets(gad,MyWindow->Window,NULL);
}
/*
* This function will open the file, append to the end of it the
* test results and close it...
*/
VOID Save_To_File(struct MyWindow *MyWindow)
{
register BPTR TheFile;
TheFile=Open(ResultFile,MODE_OLDFILE);
if (!TheFile) TheFile=Open(ResultFile,MODE_NEWFILE);
if (TheFile)
{
Seek(TheFile,0L,OFFSET_END);
Write_Results(MyWindow,TheFile);
Close(TheFile);
}
else
{ /* Tell the user the file did not open... */
TellUser(MyWindow,ErrorText3);
}
}
/*
* This function will open the printer, append to the end of it the
* test results and close it...
*/
VOID Save_To_Printer(struct MyWindow *MyWindow)
{
register BPTR TheFile;
if (TheFile=Open(PrinterFile,MODE_NEWFILE))
{
Write_Results(MyWindow,TheFile);
Close(TheFile);
}
else
{ /* Tell the user the file did not open... */
TellUser(MyWindow,ErrorText4);
}
}
VOID main(VOID)
{
register struct MyWindow *MyWindow;
register struct Window *Window;
register struct IntuiMessage *msg;
register struct Gadget *gad;
register struct timerequest *Time_Req;
register SHORT QuitFlag=0;
register struct Process *pr;
register APTR Old_WindowPtr;
register SHORT loop;
register LONG oldpri;
struct RenderInfo RenderInfo;
pr=(struct Process *)FindTask(NULL);
Old_WindowPtr=pr->pr_WindowPtr;
pr->pr_WindowPtr=(APTR)(-1);
oldpri=SetTaskPri((struct Task *)pr,1L);
if (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",33L))
{
if (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",33L))
{
FillIn_RenderInfo(&RenderInfo);
if (MyWindow=OpenMyWindow(&RenderInfo))
{
Window=MyWindow->Window;
Time_Req=&(MyWindow->TimeReq);
if (!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)Time_Req,NULL))
{
Time_Req->tr_node.io_Message.mn_ReplyPort=Window->UserPort;
TimerBase=(struct Library *)Time_Req->tr_node.io_Device;
while (!QuitFlag)
{
WaitPort(Window->UserPort);
if (msg=(struct IntuiMessage *)GetMsg(Window->UserPort))
{
if (msg->Class==CLOSEWINDOW) QuitFlag=TRUE;
else if (msg->Class==ACTIVEWINDOW) ActivateGadget(&(MyWindow->DeviceGadget),Window,NULL);
else if (msg->Class==GADGETDOWN)
{
gad=(struct Gadget *)msg->IAddress;
if (gad->Flags & SELECTED)
{
MyWindow->TestFlag=gad->GadgetID;
for (loop=0;loop<3;loop++)
{
gad=&(MyWindow->MyGadgets[loop].Gadget);
if (MyWindow->TestFlag!=gad->GadgetID)
{
if (gad->Flags & SELECTED)
{
RemoveGadget(Window,gad);
gad->Flags&=~SELECTED;
AddGadget(Window,gad,NULL);
RefreshGList(gad,Window,NULL,1L);
}
}
}
}
else
{
RemoveGadget(Window,gad);
gad->Flags|=SELECTED;
AddGadget(Window,gad,NULL);
RefreshGList(gad,Window,NULL,1L);
}
}
else if (msg->Class==GADGETUP)
{
SetWait(Window);
gad=(struct Gadget *)msg->IAddress;
switch (gad->GadgetID)
{
case GADGET_STRING: ActivateGadget((struct Gadget *)gad->UserData,Window,NULL);
break;
case GADGET_START: Do_Disk_Test(MyWindow);
break;
case GADGET_SAVE: Save_To_File(MyWindow);
break;
case GADGET_PRINT: Save_To_Printer(MyWindow);
break;
}
ClearWait(Window);
}
ReplyMsg((struct Message *)msg);
}
}
CloseDevice((struct IORequest *)Time_Req);
}
CloseMyWindow(MyWindow);
}
CloseLibrary((struct Library *)GfxBase);
}
CloseLibrary((struct Library *)IntuitionBase);
}
oldpri=SetTaskPri((struct Task *)pr,oldpri);
pr->pr_WindowPtr=Old_WindowPtr;
}