no more exit() calls

This commit is contained in:
Dave Schuyler 2003-03-15 03:40:49 +00:00
parent 210afd30a4
commit 2ae297a7c7
3 changed files with 261 additions and 235 deletions

View File

@ -1,5 +1,4 @@
#include "stdafx.h" #include "stdafx.h"
#include <iostream> #include <iostream>
@ -13,35 +12,35 @@ using namespace std;
int _tmain(int argc, _TCHAR* argv[]) { int _tmain(int argc, _TCHAR* argv[]) {
cout <<"UniqueIdAllocator Test"<<endl; cout <<"UniqueIdAllocator Test"<<endl;
UniqueIdAllocator b=UniqueIdAllocator(2, 9); UniqueIdAllocator b=UniqueIdAllocator(2, 9);
b.printTo(cout); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.free(2); b.printTo(cout); b.free(2); b.print_to(cout, true);
b.free(3); b.printTo(cout); b.free(3); b.print_to(cout, true);
b.free(4); b.printTo(cout); b.free(4); b.print_to(cout, true);
b.free(5); b.printTo(cout); b.free(5); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.free(3); b.printTo(cout); b.free(3); b.print_to(cout, true);
b.free(2); b.printTo(cout); b.free(2); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
b.free(4); b.printTo(cout); b.free(4); b.print_to(cout, true);
b.free(3); b.printTo(cout); b.free(3); b.print_to(cout, true);
b.allocate(); b.printTo(cout); b.allocate(); b.print_to(cout, true);
return 0; return 0;
} }

View File

@ -22,6 +22,31 @@
#include "uniqueIdAllocator.h" #include "uniqueIdAllocator.h"
NotifyCategoryDecl(uniqueIdAllocator, EXPCL_PANDA, EXPTP_PANDA);
NotifyCategoryDef(uniqueIdAllocator, "");
#ifndef NDEBUG //[
// Non-release build:
#define uniqueIdAllocator_debug(msg) \
if (uniqueIdAllocator_cat.is_debug()) { \
uniqueIdAllocator_cat->debug() << msg << endl; \
} else {}
#define uniqueIdAllocator_info(msg) \
uniqueIdAllocator_cat->info() << msg << endl
#define uniqueIdAllocator_warning(msg) \
uniqueIdAllocator_cat->warning() << msg << endl
#else //][
// Release build:
#define uniqueIdAllocator_debug(msg) ((void)0)
#define uniqueIdAllocator_info(msg) ((void)0)
#define uniqueIdAllocator_warning(msg) ((void)0)
#endif //]
#define audio_error(msg) \
audio_cat->error() << msg << endl
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: // Function:
// Access: // Access:
@ -30,7 +55,7 @@
UniqueIdAllocator:: UniqueIdAllocator::
UniqueIdAllocator(U32 min, U32 max) UniqueIdAllocator(U32 min, U32 max)
: _min(min), _max(max) { : _min(min), _max(max) {
//cout<<"UniqueIdAllocator::UniqueIdAllocator("<<min<<", "<<max<<")"<<endl; uniqueIdAllocator_debug("UniqueIdAllocator("<<min<<", "<<max<<")");
_size=_max-_min+1; // +1 because min and max are inclusive. _size=_max-_min+1; // +1 because min and max are inclusive.
assert(_size); // size must be > 0. assert(_size); // size must be > 0.
_table=new U32[_size]; _table=new U32[_size];
@ -51,7 +76,7 @@ UniqueIdAllocator(U32 min, U32 max)
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
UniqueIdAllocator:: UniqueIdAllocator::
~UniqueIdAllocator() { ~UniqueIdAllocator() {
//cout<<"UniqueIdAllocator::~UniqueIdAllocator()"<<endl; uniqueIdAllocator_debug("~UniqueIdAllocator()");
delete [] _table; delete [] _table;
} }
@ -60,30 +85,21 @@ UniqueIdAllocator::
// Function: // Function:
// Access: // Access:
// Description: Receive an id between _min and _max (that were passed // Description: Receive an id between _min and _max (that were passed
// to the constructor). This code will succede or call // to the constructor).
// exit(). // -1 is returned if no ids are available.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
U32 UniqueIdAllocator:: U32 UniqueIdAllocator::
allocate() { allocate() {
if (_next_free==-1) { if (_next_free==-1) {
// ...all ids allocated. // ...all ids allocated.
cerr<<"UniqueIdAllocator Error: all ids allocated."<<endl; uniqueIdAllocator_warning("allocate Error: no more free ids.");
// TODO:throw an exception rather than calling exit. return -1;
exit(1);
}
// This next block is redundant with the one above it, but I'm leaving
// the one above in place, in case anyone removes this next block.
if (_free<=(_size>>2)) {
// ...under 1/4 of the ids are free.
cerr<<"UniqueIdAllocator Error: 75% of ids allocated."<<endl;
// TODO:throw an exception rather than calling exit.
exit(1);
} }
U32 id=_min+_next_free; U32 id=_min+_next_free;
_next_free=_table[_next_free]; _next_free=_table[_next_free];
assert(_table[id-_min]=-2); // this assignment is debug only. assert(_table[id-_min]=-2); // this assignment is debug only.
--_free; --_free;
//cout<<"UniqueIdAllocator::allocate() returning "<<id<<endl; uniqueIdAllocator_debug("allocate() returning "<<id);
return id; return id;
} }
@ -96,42 +112,52 @@ allocate() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void UniqueIdAllocator:: void UniqueIdAllocator::
free(U32 index) { free(U32 index) {
//cout<<"UniqueIdAllocator::free(index)"<<endl; uniqueIdAllocator_debug("free("<<index<<")");
assert(index>=_min); // Attempt to free out-of-range id. assert(index>=_min); // Attempt to free out-of-range id.
assert(index<=_max); // Attempt to free out-of-range id. assert(index<=_max); // Attempt to free out-of-range id.
index=index-_min; index=index-_min; // Convert to _table index.
assert(_table[index]==-2); // Attempt to free non-allocated id. assert(_table[index]==-2); // Attempt to free non-allocated id.
_table[index]=-1; _table[index]=-1; // Mark this element as the end of the list.
_table[_last_free]=index; _table[_last_free]=index;
#if 0 //[
// This is only necessary if the free pool is allowed to go empty.
// Since we don't allow that, it is an optimization to comment
// this out.
if (_next_free==-1) { if (_next_free==-1) {
// ...the free list was empty.
_next_free=index; _next_free=index;
} }
#endif //]
_last_free=index; _last_free=index;
++_free; ++_free;
} }
////////////////////////////////////////////////////////////////////
// Function:
// Access:
// Description: return what percentage of the pool is used. The
// range is 0 to 1.0, so 75% would be 0.75, for example.
////////////////////////////////////////////////////////////////////
float UniqueIdAllocator::
percent_used() const {
return float(_size-_free)/_size;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: // Function:
// Access: // Access:
// Description: ...intended for debugging only. // Description: ...intended for debugging only.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void UniqueIdAllocator:: void UniqueIdAllocator::
printTo(ostream& os) const { print_to(ostream& os, bool verbose) const {
os <<"[_next_free: "<<long(_next_free) os <<"[_next_free: "<<long(_next_free)
<<"; _last_free: "<<long(_last_free) <<"; _last_free: "<<long(_last_free)
<<"; _size: "<<_size <<"; _size: "<<_size
<<"; _free: "<<_free <<"; _free: "<<_free
<<"; used: "<<_size-_free <<"; used: "<<_size-_free
<<"; %used: "<<float(_size-_free)/_size // This differs the %used code above. <<"; %used: "<<float(_size-_free)/_size;
<<";\n "; if (verbose) {
for (U32 i=0; i<_size; ++i) { os <<";\n ";
os<<long(_table[i])<<", "; for (U32 i=0; i<_size; ++i) {
os<<long(_table[i])<<", ";
}
} }
os<<"]"<<endl; os<<"]"<<endl;
} }

View File

@ -35,7 +35,8 @@ PUBLISHED:
~UniqueIdAllocator(); ~UniqueIdAllocator();
U32 allocate(); U32 allocate();
void free(U32 index); void free(U32 index);
void printTo(ostream& os) const; float percent_used() const;
void print_to(ostream& os, bool verbose=false) const;
protected: protected:
U32* _table; U32* _table;