home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-11-19 | 6.6 KB | 174 lines | [TEXT/MPS ] |
- /*
- File: TPoolNotifierExample.cp
-
- Contains: This module shows an example use of TStandardPool and TPoolNotifier
- The Shared Library Manager provides the TPoolNotifier class to assist in
- automatically “growing” a pool when the pool comes dangerously close to
- running out of memory.
-
- Copyright: © 1993 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #include "TInitSLM.h" // the TInitSLM class and SLM include files
- #include "TPoolNotifierExample.h"
- #include <Desk.h> // for the SystemTask routine
-
- ///————————————————————————————————————————————————————————————————————————————————————
- /// CONSTANTS
- ///————————————————————————————————————————————————————————————————————————————————————
-
- const size_t kBlockSize1 = 500;
- const size_t kBlockSize2 = 750;
- const size_t kLowLimit = 2000; // low mark we want to be notified about
- const size_t kHiLimit = 2250; // high mark we want to be notified about
-
- ///————————————————————————————————————————————————————————————————————————————————————
- /// PROTOTYPES
- ///————————————————————————————————————————————————————————————————————————————————————
-
- size_t get_free_bytes( TMemoryPool* thePool );
-
-
- /*————————————————————————————————————————————————————————————————————————————————————
- main
-
- In this example we start by creating a TStandardPool and with the minimum size
- required. We have subclassed the TPoolNotifier so we can intercept the
- calls to Notify and GrowBy routines simply for the sake of displaying a message.
- This notifier is attached to the pool we create so it can be notified when
- it needs to graow.
-
- A number of different things are done to the pool to make it grow, not grow, be
- notified of low and high memory, and sometimes fail to allocate memory. The
- execution of the code is all sequential so just follow the comments as you
- read through the code so you can tell what will happen to the pool and why.
- You may want to run the tool first so you can see what the output looks like.
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- main()
- {
- TInitSLM initLibraryManager; // initialize the shared library manager
-
- if( initLibraryManager.Failed() ) // If we failed, let go home.
- return 1;
-
- // Any MPW tool that uses the SLM and calls SystemTask or WaitNextEvent
- // needs to call InitGraf
- InitGraf( (Ptr)&qd.thePort );
-
- TStandardPool *thepool = new (1,kCurrentZone) TStandardPool;
-
- if( thepool ) { // make sure we didn't fail
-
- thepool->SetNotifyMarks( kLowLimit, kHiLimit );
-
- TMyPoolNotifier *poolnotifier = new TMyPoolNotifier(0, kBlockSize2);
-
- if( poolnotifier ) { // if poolnotifier succeeded then continue
-
- // attach the notifier to our pool
- thepool->SetNotifier(poolnotifier);
-
- if( thepool->CheckPool() ) { // make sure the pool is ok
-
- thepool->TracePoolInfo();// show the PoolInfo in TraceMonitor
- cout << "Current bytes free = " << get_free_bytes(thepool) << "\n\n";
-
-
- // Make the SLM think we are executing at interrupt time so it won't
- // try to grow the pool immediately. Instead it will schedule an
- // operation to grow the pool at system task time. We're just doing
- // this for the sake of demonstrating what happens if your pool
- // runs out of memory at interrupt time. Obviously you would only
- // want to do this in a real interrupt service routine.
-
- EnterInterrupt();
-
-
- // Attempt to allocate a block of memory. Since our pool is empty
- // and the SLM thinks we are at interrupt time, it will fail. But
- // since we have a notifier attached to the pool it will schedule
- // an operation to grow the pool later.
-
- cout << "About to do allocation of kBlockSize1 for 1st time" << endl;
- if (thepool->Allocate(kBlockSize1))
- cout << "Hey, the Allocate was suppose to fail!" << endl;
- else
- cout << "The Allocate failed as expected." << endl;
- cout << "Current bytes free = " << get_free_bytes(thepool) << "\n\n";
- LeaveInterrupt(); // we're done fooling the SLM
-
-
- // Now call SystemTask so the operation that was scheduled has a
- // chance to run and grow the pool.
-
- cout << "Calling SystemTask() so pool will grow." << endl;
- SystemTask();
- cout << "Current bytes free = " << get_free_bytes(thepool) << "\n\n";
-
-
- // Now try allocating the block again. We'll disable the notifer
- // first because we want to show that it doesn't need to be called
-
- thepool->SetNotifier(NULL);
- cout << "About to do allocation of kBlockSize1 for 2nd time" << endl;
- if (thepool->Allocate(kBlockSize1))
- cout << "The Allocate succeeded as expected." << endl;
- else
- cout << "Hey, the Allocate was suppose to succeed!" << endl;
- cout << "Current bytes free = " << get_free_bytes(thepool) << "\n\n";
-
-
- // Add enough memory so our pool's free memory is just above the low limit
- // for the notifier. This will cause the notifier to be called next time
- // we allocate a block because this will put the pool just below the
- // low limit.
-
- cout << "Adding " << kLowLimit+kStandardPoolChunkOverhead;
- cout << " to the pool." << endl;
- thepool->AddMemoryToPool(kLowLimit+kStandardPoolChunkOverhead);
- cout << "Current bytes free = " << get_free_bytes(thepool) << "\n\n";
-
-
- // Now allocate a block of size kBlockSize2. First we re-enable the
- // pool notifier. It will be called to grow the pool because the
- // available memory is will fall below the low limit for the notifier
-
- thepool->SetNotifier(poolnotifier); // re-enable our notifier
- cout << "About to do allocation of kBlockSize2" << endl;
- void* theblock;
- if (theblock = thepool->Allocate(kBlockSize2))
- cout << "The Allocate succeeded as expected." << endl;
- else
- cout << "Hey, the Allocate was suppose to succeed!" << endl;
- cout << "Current bytes free = " << get_free_bytes(thepool) << "\n\n";
-
-
- // Now we'll free up the block of memory. This should cause our notifier to
- // be called because the high water mark was reached.
-
- cout << "About to free up the block." << endl;
- if (theblock)
- delete theblock;
- cout << "Current bytes free = " << get_free_bytes(thepool) << "\n\n";
- }
- }
- delete thepool; // first delete the pool
- delete poolnotifier; // then the notifier
- }
- return 0;
- }
-
- /*————————————————————————————————————————————————————————————————————————————————————
- get_free_bytes
-
- find out how many bytes are free in the pool
- ————————————————————————————————————————————————————————————————————————————————————*/
- size_t get_free_bytes( TMemoryPool* thePool )
- {
- PoolInfo info;
- thePool->GetPoolInfo(info);
- return info.fFreeBytes;
- }
-