/**************************************************************************\ * * FILE: MemHandler.cpp * * This source file is part of DIME. * Copyright (C) 1998-1999 by Systems In Motion. All rights reserved. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation. DO NOT MISTAKE THIS LICENSE * FOR THE GNU LGPL LICENSE. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License (the accompanying file named COPYING) for more * details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ************************************************************************** * * If you need DIME for commercial purposes, you can contact Systems In * Motion about acquiring a commercial license. * * Systems In Motion http://www.sim.no/ * Prof. Brochs gate 6 sales@sim.no * N-7030 Trondheim Voice: +47 73540378 * NORWAY Fax: +47 73943861 * \**************************************************************************/ #include <dime/util/MemHandler.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #define MEMBLOCK_SIZE 65536 // the bigger the value, the less overhead class dimeMemNode { friend class dimeMemHandler; public: dimeMemNode(const int numbytes, dimeMemNode *next_node) : next( next_node ), currPos( 0 ), size( numbytes ) { this->block = (unsigned char*)malloc(numbytes); } ~dimeMemNode() { free((void*)this->block); } bool initOk() const { return (this->block != NULL); } void *alloc(const int numbytes, const int alignment) { unsigned int mask = alignment - 1; unsigned char *ret = NULL; if (alignment > 1) { if (this->currPos & mask) this->currPos = (this->currPos & ~mask) + alignment; } if (this->currPos + numbytes <= this->size) { ret = &this->block[currPos]; this->currPos += numbytes; } return ret; } private: dimeMemNode *next; unsigned char *block; unsigned int currPos; unsigned int size; }; // class dimeMemNode dimeMemHandler::dimeMemHandler() : bigmemnode( NULL ) { this->memnode = new dimeMemNode(MEMBLOCK_SIZE, NULL); } dimeMemHandler::~dimeMemHandler() { dimeMemNode *curr = this->memnode; dimeMemNode *next; while (curr) { next = curr->next; delete curr; curr = next; } curr = this->bigmemnode; while (curr) { next = curr->next; delete curr; curr = next; } } bool dimeMemHandler::initOk() const { return this->memnode && this->memnode->initOk(); } char * dimeMemHandler::stringAlloc(const char * const string) { int len = strlen(string)+1; char *ret = (char*)this->allocMem(len, 1); if (ret) { strcpy(ret, string); } return ret; } void * dimeMemHandler::allocMem(const int size, const int alignment) { void *ret = NULL; if (size > MEMBLOCK_SIZE/2) { // big blocks is allocated separately. this->bigmemnode = new dimeMemNode(size, this->bigmemnode); if (!this->bigmemnode || !this->bigmemnode->initOk()) return NULL; ret = (void*) this->bigmemnode->block; } else { ret = this->memnode->alloc(size, alignment); if (ret == NULL) { this->memnode = new dimeMemNode(MEMBLOCK_SIZE, this->memnode); if (!this->memnode || !this->memnode->initOk()) return NULL; ret = this->memnode->alloc(size, alignment); } } return ret; } /******************************************************************** EOF */