diff options
Diffstat (limited to 'proofs/lfsc_checker/chunking_memory_management.h')
-rw-r--r-- | proofs/lfsc_checker/chunking_memory_management.h | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/proofs/lfsc_checker/chunking_memory_management.h b/proofs/lfsc_checker/chunking_memory_management.h new file mode 100644 index 000000000..bdf938d32 --- /dev/null +++ b/proofs/lfsc_checker/chunking_memory_management.h @@ -0,0 +1,157 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// Copyright (C) 2002 by the Board of Trustees of Leland Stanford // +// Junior University. See LICENSE for details. // +// // +/////////////////////////////////////////////////////////////////////////////// +/* chunking_memory_management.h + Aaron Stump, 6/11/99 + + This file contains macros that allow you easily to add chunking + memory management for classes. + + RCS Version: $Id: chunking_memory_management.h,v 1.1 2004/11/12 16:26:19 stump Exp $ + +*/ +#ifndef _chunking_memory_management_h_ +#define _chunking_memory_management_h_ + +#include <assert.h> + +/************************************************************************ + * MACRO: ADD_CHUNKING_MEMORY_MANAGEMENT_H() + * Aaron Stump, 6/11/99 + * + * ABSTRACT: This macro should be called exactly once inside the body + * of the declaration of the class THE_CLASS to add chunking memory + * management for the class. That class should not itself declare the + * operators new and delete. The macro + * C_MACROS__ADD_CHUNKING_MEMORY_MANAGEMENT_CC should be called with + * the same value for THE_CLASS in a .cc file for that class. + * + * NOTE that the access specifier will be public after calling this + * macro. + * + * THE_FIELD is a field of the class to use for the next pointer in the + * free list data structure. It can be of any type, but must have enough + * space to hold a pointer. + ************************************************************************/ +#define C_MACROS__ADD_CHUNKING_MEMORY_MANAGEMENT_H(THE_CLASS,THE_FIELD) \ +private:\ + static unsigned C_MACROS__CHUNK_SIZE;\ + static unsigned C_MACROS__BLOCK_SIZE;\ + static void *C_MACROS__freelist;\ + static bool C_MACROS__initialized;\ + static char *C_MACROS__next_free_block;\ + static char *C_MACROS__end_of_current_chunk;\ + \ + static void C_MACROS__allocate_new_chunk();\ +\ +public:\ + static void C_MACROS__init_chunks() {\ + if (!C_MACROS__initialized) {\ + C_MACROS__allocate_new_chunk();\ + C_MACROS__initialized = true;\ + }\ + }\ +\ + static void *operator new(size_t size, void *h = NULL);\ + static void operator delete(void *ptr)\ + + +/************************************************************************ + * MACRO: ADD_CHUNKING_MEMORY_MANAGEMENT_CC() + * Aaron Stump, 6/11/99 + * + * ABSTRACT: This macro should be called exactly once in a .cc file + * for the class THE_CLASS to add chunking memory management for the + * class. This macro should be called with the same value for + * THE_CLASS as was used in calling + * C_MACROS__ADD_CHUNKING_MEMORY_MANAGEMENT_H in the body of the + * declaration of THE_CLASS. THE_CHUNK_SIZE is the number of blocks + * of memory to get at once using malloc(). A block is the portion + * of memory needed for one instance of THE_CLASS. + * + * + * IMPLEMENTATION: + ************************************************************************ + * FUNCTION: allocate_new_chunk() + * Aaron Stump, 6/8/99 + * + * ABSTRACT: This method allocates a new chunk of memory to use for + * allocating instances of THE_CLASS. + ************************************************************************ + * FUNCTION: new() + * Aaron Stump, 6/8/99 + * + * ABSTRACT: This allocator uses chunks for more efficient allocation. + ************************************************************************ + * FUNCTION: delete() + * Aaron Stump, 6/8/99 + * + * ABSTRACT: This delete() puts the chunk pointed to by ptr on the + * freelist. + ************************************************************************ + * Chunking_Memory_Management_Initializer and its static instance are used + * to call the static init_chunks() method for THE_CLASS. + ************************************************************************/ +#define C_MACROS__ADD_CHUNKING_MEMORY_MANAGEMENT_CC(THE_CLASS,THE_FIELD,THE_CHUNK_SIZE) \ +unsigned THE_CLASS::C_MACROS__CHUNK_SIZE = THE_CHUNK_SIZE;\ +\ +unsigned THE_CLASS::C_MACROS__BLOCK_SIZE = sizeof(THE_CLASS);\ +\ +void * THE_CLASS::C_MACROS__freelist = NULL;\ +char * THE_CLASS::C_MACROS__next_free_block = NULL;\ +char * THE_CLASS::C_MACROS__end_of_current_chunk = NULL;\ +bool THE_CLASS::C_MACROS__initialized = false;\ +\ +void \ +THE_CLASS::C_MACROS__allocate_new_chunk() {\ +\ + unsigned tmp = C_MACROS__CHUNK_SIZE * C_MACROS__BLOCK_SIZE;\ + char *chunk = (char *)malloc(tmp);\ + \ + assert (chunk != NULL); \ +\ + C_MACROS__next_free_block = chunk;\ + C_MACROS__end_of_current_chunk = chunk + tmp;\ +}\ +\ +void * \ +THE_CLASS::operator new(size_t size, void *h) {\ + (void)size; /* size should always be _BLOCK_SIZE */\ +\ + if (h != NULL)\ + /* we're being told what memory we should use */\ + return h;\ +\ + char *new_block;\ +\ + if (C_MACROS__freelist) {\ + /* we have a block on the freelist that we can use */\ + new_block = (char *)C_MACROS__freelist; \ + C_MACROS__freelist = (void *)((THE_CLASS *)new_block)->THE_FIELD; \ + }\ + else {\ + /* we have to get a new block from a chunk (which we may */\ + /* have to allocate*/\ + \ + if (C_MACROS__next_free_block == C_MACROS__end_of_current_chunk)\ + C_MACROS__allocate_new_chunk();\ + \ + new_block = C_MACROS__next_free_block;\ + C_MACROS__next_free_block += C_MACROS__BLOCK_SIZE;\ + }\ + \ + return new_block;\ +}\ +\ +void \ +THE_CLASS::operator delete(void *ptr) {\ + void **f = (void **)&((THE_CLASS *)ptr)->THE_FIELD; \ + *f = C_MACROS__freelist; \ + C_MACROS__freelist = ptr; \ +} + +#endif + |