Nek5000
SEM for Incompressible NS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
mem.h
Go to the documentation of this file.
1 #ifndef MEM_H
2 #define MEM_H
3 
4 /* requires:
5  <stddef.h> for size_t, offsetof
6  <stdlib.h> for malloc, calloc, realloc, free
7  <string.h> for memcpy
8  "c99.h"
9  "fail.h"
10 */
11 
12 #if !defined(C99_H) || !defined(FAIL_H)
13 #error "mem.h" requires "c99.h" and "fail.h"
14 #endif
15 
16 /*
17  All memory management goes through the wrappers defined in this
18  header. Diagnostics can be turned on with
19  -DPRINT_MALLOCS=1
20  Then all memory management operations will be printed to stdout.
21 
22  Most memory management occurs through use of the "array" type,
23  defined below, which defines a generic dynamically-sized array
24  that grows in bursts. The "buffer" type is a "char" array and
25  is often passed around by code to provide a common area for
26  scratch work.
27 */
28 
29 #ifndef PRINT_MALLOCS
30 # define PRINT_MALLOCS 0
31 #else
32 # include <stdio.h>
33 # ifndef comm_gbl_id
34 # define comm_gbl_id PREFIXED_NAME(comm_gbl_id)
35 # define comm_gbl_np PREFIXED_NAME(comm_gbl_np)
36 # include "types.h"
38 # endif
39 #endif
40 
41 /*--------------------------------------------------------------------------
42  Memory Allocation Wrappers to Catch Out-of-memory
43  --------------------------------------------------------------------------*/
44 
45 static inline void *smalloc(size_t size, const char *file, unsigned line)
46 {
47  void *restrict res = malloc(size);
48  #if PRINT_MALLOCS
49  fprintf(stdout,"MEM: proc %04d: %p = malloc(%ld) @ %s(%u)\n",
50  (int)comm_gbl_id,res,(long)size,file,line), fflush(stdout);
51  #endif
52  if(!res && size)
53  fail(1,file,line,"allocation of %ld bytes failed\n",(long)size);
54  return res;
55 }
56 
57 static inline void *scalloc(
58  size_t nmemb, size_t size, const char *file, unsigned line)
59 {
60  void *restrict res = calloc(nmemb, size);
61  #if PRINT_MALLOCS
62  fprintf(stdout,"MEM: proc %04d: %p = calloc(%ld) @ %s(%u)\n",
63  (int)comm_gbl_id,res,(long)size*nmemb,file,line), fflush(stdout);
64  #endif
65  if(!res && nmemb)
66  fail(1,file,line,"allocation of %ld bytes failed\n",
67  (long)size*nmemb);
68  return res;
69 }
70 
71 static inline void *srealloc(
72  void *restrict ptr, size_t size, const char *file, unsigned line)
73 {
74  void *restrict res = realloc(ptr, size);
75  #if PRINT_MALLOCS
76  if(res!=ptr) {
77  if(ptr)
78  fprintf(stdout,"MEM: proc %04d: %p freed by realloc @ %s(%u)\n",
79  (int)comm_gbl_id,ptr,file,line), fflush(stdout);
80  fprintf(stdout,"MEM: proc %04d: %p = realloc of %p to %lu @ %s(%u)\n",
81  (int)comm_gbl_id,res,ptr,(long)size,file,line), fflush(stdout);
82  } else
83  fprintf(stdout,"MEM: proc %04d: %p realloc'd to %lu @ %s(%u)\n",
84  (int)comm_gbl_id,res,(long)size,file,line), fflush(stdout);
85  #endif
86  if(!res && size)
87  fail(1,file,line,"allocation of %ld bytes failed\n",(long)size);
88  return res;
89 }
90 
91 #define tmalloc(type, count) \
92  ((type*) smalloc((count)*sizeof(type),__FILE__,__LINE__) )
93 #define tcalloc(type, count) \
94  ((type*) scalloc((count),sizeof(type),__FILE__,__LINE__) )
95 #define trealloc(type, ptr, count) \
96  ((type*) srealloc((ptr),(count)*sizeof(type),__FILE__,__LINE__) )
97 
98 #if PRINT_MALLOCS
99 static inline void sfree(void *restrict ptr, const char *file, unsigned line)
100 {
101  free(ptr);
102  fprintf(stdout,"MEM: proc %04d: %p freed @ %s(%u)\n",
103  (int)comm_gbl_id,ptr,file,line), fflush(stdout);
104 }
105 #define free(x) sfree(x,__FILE__,__LINE__)
106 #endif
107 
108 /*--------------------------------------------------------------------------
109  A dynamic array
110  --------------------------------------------------------------------------*/
111 struct array { void *ptr; size_t n,max; };
112 #define null_array {0,0,0}
113 static void array_init_(struct array *a, size_t max, size_t size,
114  const char *file, unsigned line)
115 {
116  a->n=0, a->max=max, a->ptr=smalloc(max*size,file,line);
117 }
118 static void array_resize_(struct array *a, size_t max, size_t size,
119  const char *file, unsigned line)
120 {
121  a->max=max, a->ptr=srealloc(a->ptr,max*size,file,line);
122 }
123 static void *array_reserve_(struct array *a, size_t min, size_t size,
124  const char *file, unsigned line)
125 {
126  size_t max = a->max;
127  if(max<min) {
128  max+=max/2+1;
129  if(max<min) max=min;
130  array_resize_(a,max,size,file,line);
131  }
132  return a->ptr;
133 }
134 
135 #define array_free(a) (free((a)->ptr))
136 #define array_init(T,a,max) array_init_(a,max,sizeof(T),__FILE__,__LINE__)
137 #define array_resize(T,a,max) array_resize_(a,max,sizeof(T),__FILE__,__LINE__)
138 #define array_reserve(T,a,min) array_reserve_(a,min,sizeof(T),__FILE__,__LINE__)
139 
140 static void array_cat_(size_t size, struct array *d, const void *s, size_t n,
141  const char *file, unsigned line)
142 {
143  char *out = array_reserve_(d,d->n+n,size, file,line);
144  memcpy(out+d->n*size, s, n*size);
145  d->n+=n;
146 }
147 
148 #define array_cat(T,d,s,n) array_cat_(sizeof(T),d,s,n,__FILE__,__LINE__)
149 
150 /*--------------------------------------------------------------------------
151  Buffer = char array
152  --------------------------------------------------------------------------*/
153 typedef struct array buffer;
154 #define null_buffer null_array
155 #define buffer_init(b,max) array_init(char,b,max)
156 #define buffer_resize(b,max) array_resize(char,b,max)
157 #define buffer_reserve(b,max) array_reserve(char,b,max)
158 #define buffer_free(b) array_free(b)
159 
160 /*--------------------------------------------------------------------------
161  Alignment routines
162  --------------------------------------------------------------------------*/
163 #define ALIGNOF(T) offsetof(struct { char c; T x; }, x)
164 static size_t align_as_(size_t a, size_t n) { return (n+a-1)/a*a; }
165 #define align_as(T,n) align_as_(ALIGNOF(T),n)
166 #define align_ptr(T,base,offset) ((T*)((char*)(base)+align_as(T,offset)))
167 #endif
168 
#define uint
Definition: types.h:70
static void * array_reserve_(struct array *a, size_t min, size_t size, const char *file, unsigned line)
Definition: mem.h:123
size_t n
Definition: mem.h:111
#define comm_gbl_id
Definition: comm.h:80
n
Definition: xxt_test.m:73
static void array_resize_(struct array *a, size_t max, size_t size, const char *file, unsigned line)
Definition: mem.h:118
static void array_init_(struct array *a, size_t max, size_t size, const char *file, unsigned line)
Definition: mem.h:113
#define comm_gbl_np
Definition: comm.h:81
Definition: mem.h:111
size_t max
Definition: mem.h:111
static size_t align_as_(size_t a, size_t n)
Definition: mem.h:164
#define restrict
Definition: c99.h:11
static void * srealloc(void *restrict ptr, size_t size, const char *file, unsigned line)
Definition: mem.h:71
static void array_cat_(size_t size, struct array *d, const void *s, size_t n, const char *file, unsigned line)
Definition: mem.h:140
void * ptr
Definition: mem.h:111
static void * scalloc(size_t nmemb, size_t size, const char *file, unsigned line)
Definition: mem.h:57
ulong out[N]
Definition: sort_test2.c:20
static void * smalloc(size_t size, const char *file, unsigned line)
Definition: mem.h:45
void fail(int status, const char *file, unsigned line, const char *fmt,...)
Definition: fail.c:47