// $Id: KrPool.C,v 1.1 2000/03/10 16:15:11 ben Exp $ #include #include #include #include const uint KrPool::BUFLEN; const uint KrPool::DATALEN; KrPool::Buf* KrPool::_freeList = NULL; uint KrPool::_allocSize = 65536; uint KrPool::_numBufs = 0; int KrPool::_maxBufs = -1; #define KRPOOL_MAXBUFS 10000 // 2.5Mb struct KrPool::Buf* KrPool::alloc() { Buf* b = _freeList; if (!b) { int numBufs = (_allocSize / BUFLEN); // Memory safety valve. By default, KRPOOL_MAXBUFS bufs // are allowed to be allocated. This can be overridden with // the "KRPOOL_MAXMEM" environment variable, which specifies // the maximum memory in bytes allowed. A value of zero // means "unlimited". _numBufs += numBufs; if (_maxBufs == -1) { _maxBufs = KRPOOL_MAXBUFS; // default value const char* maxMemStr = ::getenv("KRPOOL_MAXMEM"); if (maxMemStr) { int maxMem = ::strtol(maxMemStr, NULL, 0); if (maxMem >= 0 && maxMem < LONG_MAX) _maxBufs = maxMem / BUFLEN; } } //cerr << "KrPool::alloc _numBufs = " << _numBufs << endl; // $$$ turn off max pool size, may as well let this grow openendedly // if (_maxBufs && _numBufs > (unsigned) _maxBufs) // krFatalError(krFormat("exhausted KrPool limit of %dKb", // _maxBufs * BUFLEN / 1024)); // Allocate one less Buf than space would allow, so we can find // a starting address for the Bufs that is buf-aligned. // $$$ Turns out the memory-alignment feature isn't used and can be turned off // b = (Buf*)(((long int)::malloc(_allocSize) + BUFLEN - 1) // & ~(BUFLEN - 1)); b = (Buf*)::malloc(_allocSize); // Now break off the memory into Buf-sized chunks, and // add them to the freelist. while (numBufs--) { b->_next = _freeList; _freeList = b++; } b = _freeList; } _freeList = b->_next; return b; } void KrPool::free(Buf* b) { #ifdef DEBUG ::memset(b, 0, BUFLEN); #endif b->_next = _freeList; _freeList = b; } void KrPool::freeChain(Buf* b) { Buf* start = b; while (b->_next) b = b->_next; b->_next = _freeList; _freeList = start; }