File: clb_memory.h

package info (click to toggle)
eprover 2.6%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 21,288 kB
  • sloc: ansic: 331,111; csh: 12,026; python: 10,178; awk: 5,825; makefile: 461; sh: 389
file content (242 lines) | stat: -rw-r--r-- 7,288 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/*-----------------------------------------------------------------------

  File  : clb_memory.h

  Author: Stephan Schulz

  This module implements simple general purpose memory management
  routines that is efficient for problems with a very regular memory
  access pattern (like most theorem provers). In addition to the
  groundwork it also implements secure versions of standard functions
  making use of memory allocation.

  Copyright 1998-2017 by the author.
  This code is released under the GNU General Public Licence and
  the GNU Lesser General Public License.
  See the file COPYING in the main E directory for details..
  Run "eprover -h" for contact information.

  Changes

  Created: Wed Aug 13 21:56:20 MET DST 1997

  -----------------------------------------------------------------------*/

#ifndef CLB_MEMORY

#define CLB_MEMORY

#ifdef USE_NEWMEM
#include "clb_newmem.h"
#else

#include "clb_verbose.h"
#include "clb_os_wrapper.h"

/*---------------------------------------------------------------------*/
/*                    Data type declarations                           */
/*---------------------------------------------------------------------*/

/* Administrate deallocated memory blocks */

typedef struct memcell
{
   struct memcell* next;
#ifndef NDEBUG
   unsigned long   test;
#endif
}MemCell, *Mem_p;

/*---------------------------------------------------------------------*/
/*                Exported Functions and Variables                     */
/*---------------------------------------------------------------------*/

#define MEM_ARR_SIZE 8192
#define MEM_ARR_MIN_INDEX sizeof(MemCell)
#define MEM_FREE_PATTERN 0xFAFBFAFA
#define MEM_RSET_PATTERN 0x00000000

extern bool MemIsLow;
extern Mem_p free_mem_list[]; /* Exported for use by inline
                               * functions/Macros */

static inline void* SizeMallocReal(size_t size);
static inline void  SizeFreeReal(void* junk, size_t size);


/* For estimating the real memory consumption of a data type - the
   default may be way off for some memory managers, but should be
   reasonably ok for many situations. If CONSTANT_MEM_ESTIMATE is on,
   a very rough but machine-independent estimate is used. */

#ifdef CONSTANT_MEM_ESTIMATE
#define MEMSIZE(type) "There is a bug in the code! Everything has to work with constants."
#else
#define MEMSIZE(type) (sizeof(type)+sizeof(void*))
#endif

#ifdef USE_SYSTEM_MEM

#ifndef NDEBUG
#define SizeFree(junk, size) free(junk); junk=NULL
#define SizeMalloc(size)     malloc(size)
#define ENSURE_NULL(junk)    junk=NULL
#else
#define SizeFree(junk, size) free(junk)
#define SizeMalloc(size)     malloc(size)
#define ENSURE_NULL(junk) /* Only defined in debug mode */
#endif

#else

#ifndef NDEBUG
#define SizeFree(junk, size) SizeFreeReal(junk, size); junk=NULL
#define SizeMalloc(size)     SizeMallocReal(size)
#define ENSURE_NULL(junk)    junk=NULL
#else
#define SizeFree(junk, size) SizeFreeReal(junk, size);
#define SizeMalloc(size)     SizeMallocReal(size)
#define ENSURE_NULL(junk) /* Only defined in debug mode */
#endif

#endif

void  MemFlushFreeList(void);
void* SecureMalloc(size_t size);
void* SecureRealloc(void *ptr, size_t size);
char* SecureStrdup(const char* source);
char* SecureStrndup(const char* source, size_t n);
#define FREE(junk) assert(junk);free(junk); junk=NULL

long* IntArrayAlloc(int size);
#define IntArrayFree(array, size) SizeFree(array, size*sizeof(long))

#ifdef CLB_MEMORY_DEBUG
void MemDebugPrintStats(FILE* out);
extern long size_malloc_mem;
extern long size_malloc_count;
extern long size_free_mem;
extern long size_free_count;
extern long clb_free_count;
extern long secure_malloc_count;
extern long secure_malloc_mem;
extern long secure_realloc_count;
extern long secure_realloc_m_count;
extern long secure_realloc_f_count;
void MemFreeListPrint(FILE* out);
#undef FREE
#define FREE(junk) assert(junk); clb_free_count++; free(junk); junk=NULL
#endif

#ifdef CLB_MEMORY_DEBUG2
#undef FREE
#define FREE(junk) assert(junk); clb_free_count++; printf("\nBlock %p F:\n", junk); \
   free(junk); junk=NULL
#endif

/*-------------------------------------------------------------------------
  If you want to have a special Allocator and Deallocator for a
  datatype just copy the following templates to your .h-file and fill
  them in... The allocated structures will not be initialized - you
  need to write a function built on top of the macros if you want more
  functionality in you Allocator.

  #define DataCellAlloc() (DataCell*)SizeMalloc(sizeof(DataCell))
  #define DataCellFree(junk)         SizeFree(junk, sizeof(DataCell))

  -------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------
//
// Function: SizeMallocReal()
//
//   Returns a block of memory sized size using the internal
//   free-list. This block is freeable with free(), and in all
//   respects behaves like a normal malloc'ed block.
//
// Global Variables: free_mem_list[]
//
// Side Effects    : Memory operations
//
/----------------------------------------------------------------------*/

static inline void* SizeMallocReal(size_t size)
{
   Mem_p handle;

   if(size>=MEM_ARR_MIN_INDEX && size<MEM_ARR_SIZE && free_mem_list[size])
   {
      assert(free_mem_list[size]->test == MEM_FREE_PATTERN);
      assert((free_mem_list[size]->test = MEM_RSET_PATTERN, true));
      handle = free_mem_list[size];
      free_mem_list[size] = free_mem_list[size]->next;
   }
   else
   {
      handle = SecureMalloc(size);
#ifndef NDEBUG
      if(size>=MEM_ARR_MIN_INDEX && size<MEM_ARR_SIZE)
      {
         assert((handle->test = MEM_RSET_PATTERN, true));
      }
#endif
   }
#ifdef CLB_MEMORY_DEBUG
   size_malloc_mem+=size;
   size_malloc_count++;
#endif
#ifdef CLB_MEMORY_DEBUG2
   printf("\nBlock %p A: size %zd\n", handle, size);
#endif
   return handle;
}


/*-----------------------------------------------------------------------
//
// Function: SizeFreeReal()
//
//  Returns a block sized size. Note: size has to be exact - you
//  should only give blocks to SizeFree() that have been allocated
//  with malloc(size) or SizeMalloc(size). Giving blocks that are to
//  big wastes memory, blocks that are to small will result in more
//  serious trouble (segmentation faults).
//
// Global Variables: free_mem_list[]
//
// Side Effects    : Memory operations
//
/----------------------------------------------------------------------*/

static inline void SizeFreeReal(void* junk, size_t size)
{
   assert(junk!=NULL);

#ifdef CLB_MEMORY_DEBUG2
   printf("\nBlock %p D: size %zd\n", junk, size);
#endif

   if(size>=MEM_ARR_MIN_INDEX && size<MEM_ARR_SIZE)
   {
      ((Mem_p)junk)->next = free_mem_list[size];
      free_mem_list[size] = (Mem_p)junk;
      assert(free_mem_list[size]->test != MEM_FREE_PATTERN);
      assert((free_mem_list[size]->test = MEM_FREE_PATTERN));
   }
   else
   {
      FREE(junk);
   }

#ifdef CLB_MEMORY_DEBUG
   size_free_mem+=size;
   size_free_count++;
#endif
}

#endif
#endif

/*---------------------------------------------------------------------*/
/*                        End of File                                  */
/*---------------------------------------------------------------------*/