Files
geant4/source/global/management/include/G4Allocator.hh
T
2016-06-08 16:10:37 +02:00

168 lines
4.4 KiB
C++

//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4Allocator.hh,v 1.6.2.1 2001/06/28 19:10:01 gunter Exp $
// GEANT4 tag $Name: $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// History: first implementation, based on object model of
// 2nd December 1995, G.Cosmo
// ---------------- G4Allocator ----------------
// by Tim Bell, September 1995
// ------------------------------------------------------------
// SG, HPW: Protection vs double deletion of the same element, June 97.
#ifndef G4Allocator_h
#define G4Allocator_h 1
#include <stdlib.h>
#include <stddef.h>
// G4AllocatorPage
#include "G4AllocatorPage.hh"
template <class Type>
class G4Allocator
{
G4AllocatorPage<Type> *fPages;
G4AllocatorUnit<Type> *fFreeList;
private:
void AddNewPage();
Type *AddNewElement();
enum { Allocated = 0x47416C, Deleted = 0xB8BE93 };
public:
G4Allocator();
~G4Allocator();
inline Type *MallocSingle()
{
Type *anElement;
if (fFreeList != NULL)
{
fFreeList->deleted = Allocated;
anElement = &fFreeList->fElement;
fFreeList = fFreeList->fNext;
}
else
anElement = AddNewElement();
return anElement;
}
inline void FreeSingle(Type *anElement)
{
G4AllocatorUnit<Type> *fUnit;
fUnit = (G4AllocatorUnit<Type> *)
((char *) anElement -
offsetof(G4AllocatorUnit<Type>, fElement));
if (fUnit->deleted == Allocated) {
fUnit->deleted = Deleted;
fUnit->fNext = fFreeList;
fFreeList = fUnit;
}
/*
else if (fUnit->deleted == Deleted) {
// G4cerr << "G4Allocator : This object is already deleted" << G4endl;
} else {
// G4cerr << "G4Allocator: This object is allocated not by G4Allocator"<< G4endl;
}
*/
}
};
template <class Type>
G4Allocator<Type>::G4Allocator()
{
fPages = NULL;
fFreeList = NULL;
AddNewPage();
return;
}
template <class Type>
G4Allocator<Type>::~G4Allocator()
{
G4AllocatorPage<Type> *aPage;
G4AllocatorPage<Type> *aNextPage;
aPage = fPages;
while (aPage != NULL)
{
aNextPage = aPage->fNext;
free(aPage->fUnits);
delete aPage;
aPage = aNextPage;
}
fPages = NULL;
fFreeList = NULL;
return;
}
static const G4int G4AllocatorPageSize = 1024;
template <class Type>
void G4Allocator<Type>::AddNewPage()
{
G4AllocatorPage<Type> *aPage;
register G4int unit_no;
aPage = new G4AllocatorPage<Type>;
aPage->fNext = fPages;
aPage->fUnits = (G4AllocatorUnit<Type> *)
malloc(G4AllocatorPageSize);
fPages = aPage;
for (unit_no = 0;
unit_no < (G4AllocatorPageSize / G4int(sizeof(G4AllocatorUnit<Type>))-1);
++unit_no)
{
aPage->fUnits[unit_no].fNext = &aPage->fUnits[unit_no + 1];
}
aPage->fUnits[unit_no].fNext = fFreeList;
fFreeList = &aPage->fUnits[0];
}
template <class Type>
Type *G4Allocator<Type>::AddNewElement()
{
Type *anElement;
AddNewPage();
fFreeList->deleted = Allocated;
anElement = &fFreeList->fElement;
fFreeList=fFreeList->fNext;
return anElement;
}
#endif