home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-11-19 | 11.0 KB | 496 lines | [TEXT/MPS ] |
- /*
- File: TestStandardPool.cp
-
- Contains: Methods for TTestStandardPool
-
- Copyright: © 1992-1995 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #ifndef __GLOBALNEW__
- #include <GlobalNew.h>
- #endif
- #ifndef __TESTSTANDARDPOOL__
- #include "TestStandardPool.h"
- #endif
- #ifndef __MIXEDMODE__
- #include <MixedMode.h>
- #endif
-
- size_t StringToNum(char* str);
- size_t RandomNumber(size_t lo, size_t hi);
-
- /*******************************************************************************
- ** CLASS Declaration
- ********************************************************************************/
-
- class TMyPoolNotifier : public TPoolNotifier
- {
- public:
- TMyPoolNotifier(void* memory);
- virtual ~_CDECL TMyPoolNotifier();
-
- virtual void _CDECL Notify(EventCode, OSErrParm, void*);
-
- private:
- void* fMemory;
- };
-
- TMyPoolNotifier::TMyPoolNotifier(void* memory)
- {
- fMemory = memory;
- }
-
- TMyPoolNotifier::~TMyPoolNotifier()
- {}
-
- void TMyPoolNotifier::Notify(EventCode code, OSErrParm err, void*)
- {
- if (code == kLowPoolMemoryEvent && err == kNoError)
- {
- if (fMemory)
- {
- TMemoryPool::FreeMemory(fMemory);
- fMemory = NULL;
- }
- }
- }
- /**********************************************************************
- ** External "C" Declarations
- ***********************************************************************/
-
- extern "C"
- {
- #if GENERATINGPOWERPC
-
- struct CLI {
- short fWord[6];
- } gcli68K = {
- 0x40c0, /* move SR,D0 */
- 0x007C, 0x0700, /* ori.w #$0700,SR */
- 0x027C, 0xFEFF, /* andi.w #$FEFF,SR */
- 0x4e75
- };
-
- struct STI {
- short fWord[2];
- } gsti68K = {
- 0x46c0, /* move.w D0,SR */
- 0x4e75
- };
-
- #define pcli() CallUniversalProc((UniversalProcPtr)&gcli68K, kRegisterBased | REGISTER_RESULT_LOCATION(kRegisterD0) | RESULT_SIZE(kTwoByteCode))
- #define psti(save) CallUniversalProc((UniversalProcPtr)&gsti68K, kRegisterBased | REGISTER_ROUTINE_PARAMETER(1, kRegisterD0, kTwoByteCode), save)
-
- #else
-
- short pcli() =
- {
- 0x40c0, /* move SR,D0 */
- 0x007C, 0x0700, /* ori.w #$0700,SR */
- 0x027C, 0xFEFF /* andi.w #$FEFF,SR */
- };
- #pragma parameter psti(__D0)
- void psti(short) =
- {
- 0x46c0 /* move.w D0,SR */
- };
-
- #endif
- };
-
- /*******************************************************************************
- ** Some Constants
- ********************************************************************************/
-
- const size_t kNumPoolOps = 5;
- const size_t kNumMemory = 25;
- const size_t kMaxMemSize = 255;
-
- #define kDontTouch ((char*)-1L)
-
- /*******************************************************************************
- ** TPoolTestOperation
- ********************************************************************************/
-
- TPoolTestOperation::TPoolTestOperation(char** array, size_t size, size_t small,
- size_t large)
- {
- fArray = array;
- fArraySize = size;
- fFinished = true;
- fSmallest = small;
- fLargest = large;
- fAllocs = 0;
- fDeletes = 0;
- }
-
- TPoolTestOperation::~TPoolTestOperation()
- {}
-
- void TPoolTestOperation::Process()
- {
- size_t toAlloc = RandomNumber(0, fArraySize);
- size_t count = 0;
-
- for (count = 0; count < toAlloc; ++count)
- {
- size_t which = RandomNumber(0, fArraySize - 1);
- if (fArray[which] == NULL)
- {
- char* temp = new char[RandomNumber(fSmallest, fLargest)];
- fAllocs += 1;
- short save;
- save = pcli();
- if (fArray[which] == NULL)
- {
- fArray[which] = temp;
- psti(save);
- }
- else
- {
- psti(save);
- delete temp;
- fDeletes += 1;
- }
- }
- }
- size_t toFree = RandomNumber(0, fArraySize);
- for (count = 0; count < toFree; ++count)
- {
- size_t which = RandomNumber(0, fArraySize - 1);
- short save;
- save = pcli();
- if (fArray[which] != NULL && fArray[which] != kDontTouch)
- {
- char* temp = fArray[which];
- fArray[which] = NULL;
- psti(save);
- delete temp;
- fDeletes += 1;
- }
- else
- psti(save);
- }
- fFinished = true;
- }
-
- /*******************************************************************************
- ** PUBLIC Constructor/Destructor
- ********************************************************************************/
-
- Constructor(StandardPool)
- Destructor(StandardPool)
-
- /*******************************************************************************
- ** PUBLIC InitTest
- ********************************************************************************/
-
- void TTestStandardPool :: InitTest(BooleanParm verbose, BooleanParm, int argc, char** argv)
- {
- TStandardPool* pool = GetPool();
-
- if (pool == NULL)
- {
- Printf("### ERROR: There is no global pool\n");
- return;
- }
-
- SetLocalPool(pool);
-
- fSmallest = 1;
- fLargest = 255;
- fAllocs = 0;
- fDeletes = 0;
- fReallocs = 0;
- fIterations = 5000;
- size_t idx = 0;
- while (argc)
- {
- char* str;
-
- str = argv[idx];
- if (*str != '-')
- break;
- argc -= 1;
- idx += 1;
- switch (str[1])
- {
- case 'i':
- case 'I':
- fIterations = StringToNum(argv[idx++]);
- argc -= 1;
- break;
-
- default:
- argc = 0;
- Printf("WARNING: Option at and after '%s' not understood!\n", str);
- break;
- }
-
- }
- fSmallest = 1;
- fLargest = 255;
- if (argc)
- {
- if (argc == 1)
- Printf("WARNING: Option '%s' not understood!\n", argv[idx]);
- else
- if (argc != 2)
- Printf("WARNING: Options at and after '%s' not understood!\n",
- argv[idx]);
- else
- {
- fSmallest = StringToNum(argv[idx++]);
- fLargest = StringToNum(argv[idx++]);
- if (verbose)
- Printf("INFO: Smallest size = %u\nINFO: Largest size = %u\n",
- fSmallest, fLargest);
- }
- }
- }
-
-
- /**********************************************************************
- ** PUBLIC RunTestIteration
- ***********************************************************************/
-
- void TTestStandardPool :: RunTestIteration(BooleanParm verbose, BooleanParm)
- {
- TPoolTestOperation* ops[kNumPoolOps];
- TTimeScheduler* sched = new TTimeScheduler;
- char* memory[kNumMemory];
- size_t idx, jdx;
- TStopwatch stamp;
-
- //
- // First, we do some quick tests on the pool
- //
- {
- if (verbose)
- Printf("### INFO: Testing Pool Notifiers\n");
- TStandardPool* pool = new (2500, kCurrentZone, kNormalMemory) TStandardPool;
- if (pool)
- {
- void* memory = pool->Allocate(2000);
- if (memory == NULL)
- {
- Printf("### ERROR: Couldn't allocate 2000 bytes from a 2500 byte pool\n");
- }
- else
- {
- Boolean ok = true;
- void* mem2 = pool->Allocate(2000);
- if (mem2)
- {
- Printf("### ERROR: Allocated 4000 bytes from a 2500 byte pool\n");
- ok = false;
- pool->Free(mem2);
- }
- else
- {
- TMyPoolNotifier notifier(memory);
- pool->SetNotifier(¬ifier);
- mem2 = pool->Allocate(2000);
- if (mem2 == NULL)
- {
- ok = false;
- Printf("### ERROR: Couldn't allocate 2000 bytes using the notifier\n");
- }
- void* mem3 = pool->Allocate(2000);
- if (mem3 == NULL)
- {
- Printf("### ERROR: Pool didn't grow\n");
- ok = false;
- }
- else
- pool->Free(mem3);
- if (mem2)
- pool->Free(mem2);
- pool->SetNotifier(NULL);
- if (verbose && ok)
- Printf("### INFO: Pool notifiers seemed to work!\n");
- }
- }
- delete pool;
- }
- else
- Printf("### ERROR: Couldn't create a 2500 byte pool\n");
- }
-
- memset(memory, 0, sizeof(memory));
-
- for (idx = 0; idx < kNumPoolOps; ++idx)
- ops[idx] = new TPoolTestOperation(memory, kNumMemory, fSmallest, fLargest);
-
- (&stamp)->Reset();
-
- Printf(" 0: ");
- for (idx = 0; idx < fIterations; ++idx)
- {
- if ((idx + 1) % 100 == 0)
- Printf(".");
- if ((idx + 1) % 2500 == 0)
- Printf("\n%8u: ", idx + 1);
- //
- // Schedule any operations that are not scheduled
- //
- for (jdx = 0; jdx < kNumPoolOps; ++jdx)
- if (ops[jdx]->fFinished)
- {
- ops[jdx]->fFinished = false;
- ops[jdx]->SetTime(jdx + 1);
- sched->Schedule(ops[jdx]);
- }
-
- size_t toAlloc = RandomNumber(0, kNumMemory);
- size_t count = 0;
- for (count = 0; count < toAlloc; ++count)
- {
- size_t which = RandomNumber(0, kNumMemory - 1);
- if (memory[which] == NULL)
- {
- size_t size = RandomNumber(fSmallest, fLargest);
- char* temp = new char[size];
- fAllocs += 1;
- short save;
- save = pcli();
- if (memory[which] == NULL)
- {
- memory[which] = temp;
- psti(save);
- }
- else
- {
- psti(save);
- delete temp;
- fDeletes += 1;
- }
- }
- }
- //
- // Schedule any operations that are not scheduled
- //
- for (jdx = 0; jdx < kNumPoolOps; ++jdx)
- if (ops[jdx]->fFinished)
- {
- ops[jdx]->fFinished = false;
- ops[jdx]->SetTime(jdx + 1);
- sched->Schedule(ops[jdx]);
- }
-
- size_t toFree = RandomNumber(0, kNumMemory);
- for (count = 0; count < toFree; ++count)
- {
- size_t which = RandomNumber(0, kNumMemory - 1);
- short save;
- save = pcli();
- if (memory[which] != NULL && memory[which] != kDontTouch)
- {
- char* temp = memory[which];
- memory[which] = NULL;
- psti(save);
- delete temp;
- fDeletes += 1;
- }
- else
- psti(save);
- }
- //
- // Schedule any operations that are not scheduled
- //
- for (jdx = 0; jdx < kNumPoolOps; ++jdx)
- if (ops[jdx]->fFinished)
- {
- ops[jdx]->fFinished = false;
- ops[jdx]->SetTime(jdx + 1);
- sched->Schedule(ops[jdx]);
- }
-
- size_t toResize = RandomNumber(0, kNumMemory);
- for (count = 0; count < toResize; ++count)
- {
- size_t which = RandomNumber(0, kNumMemory - 1);
- size_t newSize = RandomNumber(fSmallest, fLargest);
- short save;
- save = pcli();
- if (memory[which] != NULL && memory[which] != kDontTouch)
- {
- char* temp = memory[which];
- memory[which] = kDontTouch;
- psti(save);
- char* temp1 = (char*)TMemoryPool::ReallocateMemory(temp, newSize);
- fReallocs += 1;
- save = pcli();
- memory[which] = temp1;
- psti(save);
- if (temp1 == NULL)
- {
- fDeletes += 1;
- delete temp;
- }
- }
- else
- psti(save);
- }
- //
- // Schedule any operations that are not scheduled
- //
- for (jdx = 0; jdx < kNumPoolOps; ++jdx)
- if (ops[jdx]->fFinished)
- {
- ops[jdx]->fFinished = false;
- ops[jdx]->SetTime(jdx + 1);
- sched->Schedule(ops[jdx]);
- }
-
- if (!GetDefaultPool()->CheckPool())
- {
- Printf("\nERROR: CheckPool() Failed ... ABORTING TEST\n");
- break;
- }
- }
- for (jdx = 0; jdx < kNumPoolOps; ++jdx)
- if (!ops[jdx]->fFinished)
- jdx = 0;
-
- unsigned long seconds = (&stamp)->ElapsedSeconds();
- unsigned long allocs, frees, reallocs;
- allocs = fAllocs;
- frees = fDeletes;
- reallocs = fReallocs;
- if (seconds == 0)
- seconds = 1;
- for (jdx = 0; jdx < kNumPoolOps; ++jdx)
- {
- allocs += ops[jdx]->fAllocs;
- frees += ops[jdx]->fDeletes;
- }
-
- delete sched;
- for (jdx = 0; jdx < kNumPoolOps; ++jdx)
- {
- TPoolTestOperation* op = ops[jdx];
- delete op;
- }
- for (jdx = 0; jdx < kNumMemory; ++jdx)
- delete memory[jdx];
-
- if (verbose)
- {
- Printf("\n\nINFO: # Allocates = %8u per second = %4u\n", allocs, allocs/seconds);
- Printf("INFO: # Deletes = %8u per second = %4u\n", frees, frees/seconds);
- Printf("INFO: # Reallocates = %8u per second = %4u\n\n", reallocs, reallocs/seconds);
- }
- }
-
- /**********************************************************************
- ** PUBLIC EndTest
- ***********************************************************************/
-
- void TTestStandardPool :: EndTest(BooleanParm verbose, BooleanParm)
- {
- if (verbose)
- Printf("INFO: End of StandardPool test\n");
- }
-