sedna 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/{CHANGES → CHANGES.rdoc} +9 -0
  2. data/{README → README.rdoc} +23 -25
  3. data/Rakefile +32 -9
  4. data/ext/{extconf.rb → sedna/extconf.rb} +33 -21
  5. data/ext/{sedna.c → sedna/sedna.c} +48 -40
  6. data/test/sedna_test.rb +9 -9
  7. data/vendor/sedna/AUTHORS +18 -0
  8. data/vendor/sedna/COPYRIGHT +90 -0
  9. data/vendor/sedna/LICENSE +202 -0
  10. data/vendor/sedna/Makefile.include +423 -0
  11. data/vendor/sedna/Makefile.platform +31 -0
  12. data/vendor/sedna/depend.sed +48 -0
  13. data/vendor/sedna/driver/c/Makefile +98 -0
  14. data/vendor/sedna/driver/c/libsedna.c +1998 -0
  15. data/vendor/sedna/driver/c/libsedna.h +199 -0
  16. data/vendor/sedna/driver/c/sednamt.def +21 -0
  17. data/vendor/sedna/driver/c/sp_defs.h +186 -0
  18. data/vendor/sedna/kernel/common/FastXptrHash.cpp +101 -0
  19. data/vendor/sedna/kernel/common/IntHash.h +314 -0
  20. data/vendor/sedna/kernel/common/IntList.h +224 -0
  21. data/vendor/sedna/kernel/common/Makefile +30 -0
  22. data/vendor/sedna/kernel/common/SSMMsg.cpp +459 -0
  23. data/vendor/sedna/kernel/common/SSMMsg.h +142 -0
  24. data/vendor/sedna/kernel/common/XptrHash.h +435 -0
  25. data/vendor/sedna/kernel/common/argtable.c +972 -0
  26. data/vendor/sedna/kernel/common/argtable.h +896 -0
  27. data/vendor/sedna/kernel/common/base.cpp +339 -0
  28. data/vendor/sedna/kernel/common/base.h +226 -0
  29. data/vendor/sedna/kernel/common/bit_set.cpp +157 -0
  30. data/vendor/sedna/kernel/common/bit_set.h +55 -0
  31. data/vendor/sedna/kernel/common/commutil.h +67 -0
  32. data/vendor/sedna/kernel/common/config.h +62 -0
  33. data/vendor/sedna/kernel/common/counted_ptr.h +74 -0
  34. data/vendor/sedna/kernel/common/errdbg/ErrorCodes.java +1056 -0
  35. data/vendor/sedna/kernel/common/errdbg/Makefile +34 -0
  36. data/vendor/sedna/kernel/common/errdbg/assert.c +133 -0
  37. data/vendor/sedna/kernel/common/errdbg/d_printf.c +150 -0
  38. data/vendor/sedna/kernel/common/errdbg/d_printf.h +91 -0
  39. data/vendor/sedna/kernel/common/errdbg/error.codes +1743 -0
  40. data/vendor/sedna/kernel/common/errdbg/error_codes.c +531 -0
  41. data/vendor/sedna/kernel/common/errdbg/error_codes.h +549 -0
  42. data/vendor/sedna/kernel/common/errdbg/error_codes_scm.scm +527 -0
  43. data/vendor/sedna/kernel/common/errdbg/event_log.c +956 -0
  44. data/vendor/sedna/kernel/common/errdbg/event_log.h +226 -0
  45. data/vendor/sedna/kernel/common/errdbg/exceptions.cpp +155 -0
  46. data/vendor/sedna/kernel/common/errdbg/exceptions.h +559 -0
  47. data/vendor/sedna/kernel/common/errdbg/gen_error_codes +0 -0
  48. data/vendor/sedna/kernel/common/errdbg/gen_error_codes.c +345 -0
  49. data/vendor/sedna/kernel/common/gmm.cpp +192 -0
  50. data/vendor/sedna/kernel/common/gmm.h +29 -0
  51. data/vendor/sedna/kernel/common/ipc_ops.cpp +435 -0
  52. data/vendor/sedna/kernel/common/ipc_ops.h +51 -0
  53. data/vendor/sedna/kernel/common/lfsGlobals.h +12 -0
  54. data/vendor/sedna/kernel/common/lm_base.h +90 -0
  55. data/vendor/sedna/kernel/common/mmgr/Makefile +11 -0
  56. data/vendor/sedna/kernel/common/mmgr/aset.c +1185 -0
  57. data/vendor/sedna/kernel/common/mmgr/mcxt.c +741 -0
  58. data/vendor/sedna/kernel/common/mmgr/memnodes.h +70 -0
  59. data/vendor/sedna/kernel/common/mmgr/memutils.h +145 -0
  60. data/vendor/sedna/kernel/common/mmgr/se_alloc.h +321 -0
  61. data/vendor/sedna/kernel/common/mmgr/track.c +214 -0
  62. data/vendor/sedna/kernel/common/pping.cpp +672 -0
  63. data/vendor/sedna/kernel/common/pping.h +119 -0
  64. data/vendor/sedna/kernel/common/rcv_test.cpp +273 -0
  65. data/vendor/sedna/kernel/common/rcv_test.h +19 -0
  66. data/vendor/sedna/kernel/common/sedna.c +128 -0
  67. data/vendor/sedna/kernel/common/sedna.h +49 -0
  68. data/vendor/sedna/kernel/common/sedna_ef.h +52 -0
  69. data/vendor/sedna/kernel/common/sm_vmm_data.h +144 -0
  70. data/vendor/sedna/kernel/common/sp.c +93 -0
  71. data/vendor/sedna/kernel/common/sp.h +36 -0
  72. data/vendor/sedna/kernel/common/st/Makefile +20 -0
  73. data/vendor/sedna/kernel/common/st/os_linux/stacktrace.c +213 -0
  74. data/vendor/sedna/kernel/common/st/os_nt/stacktrace.c +338 -0
  75. data/vendor/sedna/kernel/common/st/os_other/stacktrace.c +39 -0
  76. data/vendor/sedna/kernel/common/st/stacktrace.h +72 -0
  77. data/vendor/sedna/kernel/common/st/stacktrfmt.c +64 -0
  78. data/vendor/sedna/kernel/common/tr_debug.cpp +112 -0
  79. data/vendor/sedna/kernel/common/tr_debug.h +22 -0
  80. data/vendor/sedna/kernel/common/u/Makefile +14 -0
  81. data/vendor/sedna/kernel/common/u/u.c +268 -0
  82. data/vendor/sedna/kernel/common/u/u.h +715 -0
  83. data/vendor/sedna/kernel/common/u/uatomic.h +12 -0
  84. data/vendor/sedna/kernel/common/u/udl.h +31 -0
  85. data/vendor/sedna/kernel/common/u/uevent.c +406 -0
  86. data/vendor/sedna/kernel/common/u/uevent.h +71 -0
  87. data/vendor/sedna/kernel/common/u/ugnames.cpp +330 -0
  88. data/vendor/sedna/kernel/common/u/ugnames.h +134 -0
  89. data/vendor/sedna/kernel/common/u/uhash_map.h +77 -0
  90. data/vendor/sedna/kernel/common/u/uhdd.c +1018 -0
  91. data/vendor/sedna/kernel/common/u/uhdd.h +206 -0
  92. data/vendor/sedna/kernel/common/u/ummap.cpp +268 -0
  93. data/vendor/sedna/kernel/common/u/ummap.h +60 -0
  94. data/vendor/sedna/kernel/common/u/umutex.c +145 -0
  95. data/vendor/sedna/kernel/common/u/umutex.h +65 -0
  96. data/vendor/sedna/kernel/common/u/upipe.cpp +244 -0
  97. data/vendor/sedna/kernel/common/u/upipe.h +74 -0
  98. data/vendor/sedna/kernel/common/u/uprocess.c +767 -0
  99. data/vendor/sedna/kernel/common/u/uprocess.h +91 -0
  100. data/vendor/sedna/kernel/common/u/usafesync.h +41 -0
  101. data/vendor/sedna/kernel/common/u/usecurity.c +150 -0
  102. data/vendor/sedna/kernel/common/u/usecurity.h +55 -0
  103. data/vendor/sedna/kernel/common/u/usem.c +891 -0
  104. data/vendor/sedna/kernel/common/u/usem.h +83 -0
  105. data/vendor/sedna/kernel/common/u/ushm.c +222 -0
  106. data/vendor/sedna/kernel/common/u/ushm.h +46 -0
  107. data/vendor/sedna/kernel/common/u/usocket.c +541 -0
  108. data/vendor/sedna/kernel/common/u/usocket.h +118 -0
  109. data/vendor/sedna/kernel/common/u/usystem.c +57 -0
  110. data/vendor/sedna/kernel/common/u/usystem.h +46 -0
  111. data/vendor/sedna/kernel/common/u/uthread.c +259 -0
  112. data/vendor/sedna/kernel/common/u/uthread.h +95 -0
  113. data/vendor/sedna/kernel/common/u/utime.c +65 -0
  114. data/vendor/sedna/kernel/common/u/utime.h +40 -0
  115. data/vendor/sedna/kernel/common/u/uutils.c +142 -0
  116. data/vendor/sedna/kernel/common/u/uutils.h +65 -0
  117. data/vendor/sedna/kernel/common/ugc.cpp +156 -0
  118. data/vendor/sedna/kernel/common/ugc.h +15 -0
  119. data/vendor/sedna/kernel/common/utils.cpp +156 -0
  120. data/vendor/sedna/kernel/common/utils.h +133 -0
  121. data/vendor/sedna/kernel/common/version.c +16 -0
  122. data/vendor/sedna/kernel/common/version.h +21 -0
  123. data/vendor/sedna/kernel/common/wustructures.h +18 -0
  124. data/vendor/sedna/kernel/common/wutypes.h +34 -0
  125. data/vendor/sedna/kernel/common/xptr.cpp +17 -0
  126. data/vendor/sedna/kernel/common/xptr.h +211 -0
  127. data/vendor/sedna/ver +1 -0
  128. metadata +142 -14
@@ -0,0 +1,741 @@
1
+ /*
2
+ * File: mcxt.c
3
+ * Memory context management code.
4
+ *
5
+ * Portions Copyright (C) 2006 The Institute for System Programming of the Russian Academy of Sciences (ISP RAS)
6
+ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7
+ * Portions Copyright (c) 1994, Regents of the University of California
8
+ *
9
+ * This module handles context management operations that are independent
10
+ * of the particular kind of context being operated on. It calls
11
+ * context-type-specific operations via the function pointers in a
12
+ * context's MemoryContextMethods struct.
13
+ *
14
+ */
15
+
16
+ #include "common/sedna.h"
17
+ #include "common/mmgr/memutils.h"
18
+
19
+ #ifdef SE_MEMORY_TRACK
20
+
21
+ #ifdef __cplusplus
22
+ extern "C" {
23
+ #endif
24
+
25
+ extern void AddTrack(void* addr, usize_t asize, const char *fname, int lnum, const char* flag);
26
+ extern void RemoveTrack(void* addr);
27
+ extern void DumpUnfreed();
28
+
29
+ #ifdef __cplusplus
30
+ }
31
+ #endif
32
+
33
+ #undef malloc
34
+ #undef free
35
+ #undef realloc
36
+ #undef calloc
37
+ #undef strdup
38
+
39
+ void *track_malloc(usize_t size, const char* file, int line, const char* flag)
40
+ {
41
+ void *ptr = (void *)malloc(size);
42
+ AddTrack(ptr, size, file, line, flag);
43
+ return ptr;
44
+ }
45
+ void track_free(void *pointer)
46
+ {
47
+ if(pointer)
48
+ {
49
+ RemoveTrack(pointer);
50
+ free(pointer);
51
+ }
52
+ }
53
+ void *track_realloc(void *pointer, usize_t size, const char* file, int line, const char* flag)
54
+ {
55
+ if(pointer)
56
+ {
57
+ void *ptr;
58
+ RemoveTrack(pointer);
59
+ ptr = (void *)realloc(pointer, size);
60
+ AddTrack(ptr, size, file, line, flag);
61
+ return ptr;
62
+ }
63
+ return NULL;
64
+ }
65
+ void *track_calloc(usize_t num, usize_t size, const char* file, int line, const char* flag)
66
+ {
67
+ void *ptr = (void *)calloc(num, size);
68
+ AddTrack(ptr, num * size, file, line, flag);
69
+ return ptr;
70
+ }
71
+ char *track_strdup(const char *source, const char* file, int line, const char* flag)
72
+ {
73
+ char *ptr = strdup(source);
74
+ AddTrack(ptr, strlen(ptr) + 1, file, line, flag);
75
+ return ptr;
76
+ }
77
+
78
+
79
+ #else
80
+
81
+ int SafeMemoryContextInit(void)
82
+ {
83
+ static int initialized = 0;
84
+ if (!initialized)
85
+ {
86
+ CurrentMemoryContext = NULL;
87
+ TopMemoryContext = NULL;
88
+ ErrorContext = NULL;
89
+
90
+ MemoryContextInit();
91
+
92
+ initialized = 1;
93
+ return 1;
94
+ }
95
+ return 0;
96
+ }
97
+
98
+
99
+ /*****************************************************************************
100
+ * GLOBAL MEMORY *
101
+ *****************************************************************************/
102
+
103
+ /*
104
+ * CurrentMemoryContext
105
+ * Default memory context for allocations.
106
+ */
107
+ MemoryContext CurrentMemoryContext = NULL;
108
+
109
+ /*
110
+ * Standard top-level contexts. For a description of the purpose of each
111
+ * of these contexts, refer to src/backend/utils/mmgr/README
112
+ */
113
+ MemoryContext TopMemoryContext = NULL;
114
+ MemoryContext ErrorContext = NULL;
115
+
116
+ MemoryContext TransactionContext = NULL;
117
+ MemoryContext UserStatementContext = NULL;
118
+ MemoryContext KernelStatementContext = NULL;
119
+ MemoryContext XQParserContext = NULL;
120
+
121
+
122
+ /*****************************************************************************
123
+ * EXPORTED ROUTINES *
124
+ *****************************************************************************/
125
+
126
+
127
+ /*
128
+ * MemoryContextInit
129
+ * Start up the memory-context subsystem.
130
+ *
131
+ * This must be called before creating contexts or allocating memory in
132
+ * contexts. TopMemoryContext and ErrorContext are initialized here;
133
+ * other contexts must be created afterwards.
134
+ *
135
+ * In normal multi-backend operation, this is called once during
136
+ * postmaster startup, and not at all by individual backend startup
137
+ * (since the backends inherit an already-initialized context subsystem
138
+ * by virtue of being forked off the postmaster).
139
+ *
140
+ * In a standalone backend this must be called during backend startup.
141
+ */
142
+ void
143
+ MemoryContextInit(void)
144
+ {
145
+ U_ASSERT(TopMemoryContext == NULL);
146
+
147
+ /*
148
+ * Initialize TopMemoryContext as an AllocSetContext with slow growth rate
149
+ * --- we don't really expect much to be allocated in it.
150
+ *
151
+ * (There is special-case code in MemoryContextCreate() for this call.)
152
+ */
153
+ TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL,
154
+ "TopMemoryContext",
155
+ 0,
156
+ 8 * 1024,
157
+ 8 * 1024);
158
+
159
+ /*
160
+ * Not having any other place to point CurrentMemoryContext, make it point
161
+ * to TopMemoryContext. Caller should change this soon!
162
+ */
163
+ CurrentMemoryContext = TopMemoryContext;
164
+
165
+ /*
166
+ * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
167
+ * we don't really expect much to be allocated in it. More to the point,
168
+ * require it to contain at least 8K at all times. This is the only case
169
+ * where retained memory in a context is *essential* --- we want to be
170
+ * sure ErrorContext still has some memory even if we've run out
171
+ * elsewhere!
172
+ */
173
+ ErrorContext = AllocSetContextCreate(TopMemoryContext,
174
+ "ErrorContext",
175
+ 8 * 1024,
176
+ 8 * 1024,
177
+ 8 * 1024);
178
+ }
179
+
180
+ /*
181
+ * MemoryContextReset
182
+ * Release all space allocated within a context and its descendants,
183
+ * but don't delete the contexts themselves.
184
+ *
185
+ * The type-specific reset routine handles the context itself, but we
186
+ * have to do the recursion for the children.
187
+ */
188
+ void
189
+ MemoryContextReset(MemoryContext context)
190
+ {
191
+ U_ASSERT(MemoryContextIsValid(context));
192
+
193
+ /* save a function call in common case where there are no children */
194
+ if (context->firstchild != NULL)
195
+ MemoryContextResetChildren(context);
196
+
197
+ (*context->methods->reset) (context);
198
+ }
199
+
200
+ /*
201
+ * MemoryContextResetChildren
202
+ * Release all space allocated within a context's descendants,
203
+ * but don't delete the contexts themselves. The named context
204
+ * itself is not touched.
205
+ */
206
+ void
207
+ MemoryContextResetChildren(MemoryContext context)
208
+ {
209
+ MemoryContext child;
210
+
211
+ U_ASSERT(MemoryContextIsValid(context));
212
+
213
+ for (child = context->firstchild; child != NULL; child = child->nextchild)
214
+ MemoryContextReset(child);
215
+ }
216
+
217
+ /*
218
+ * MemoryContextDelete
219
+ * Delete a context and its descendants, and release all space
220
+ * allocated therein.
221
+ *
222
+ * The type-specific delete routine removes all subsidiary storage
223
+ * for the context, but we have to delete the context node itself,
224
+ * as well as recurse to get the children. We must also delink the
225
+ * node from its parent, if it has one.
226
+ */
227
+ void
228
+ MemoryContextDelete(MemoryContext context)
229
+ {
230
+ U_ASSERT(MemoryContextIsValid(context));
231
+ /* We had better not be deleting TopMemoryContext ... */
232
+ U_ASSERT(context != TopMemoryContext);
233
+ /* And not CurrentMemoryContext, either */
234
+ U_ASSERT(context != CurrentMemoryContext);
235
+
236
+ MemoryContextDeleteChildren(context);
237
+
238
+ /*
239
+ * We delink the context from its parent before deleting it, so that if
240
+ * there's an error we won't have deleted/busted contexts still attached
241
+ * to the context tree. Better a leak than a crash.
242
+ */
243
+ if (context->parent)
244
+ {
245
+ MemoryContext parent = context->parent;
246
+
247
+ if (context == parent->firstchild)
248
+ parent->firstchild = context->nextchild;
249
+ else
250
+ {
251
+ MemoryContext child;
252
+
253
+ for (child = parent->firstchild; child; child = child->nextchild)
254
+ {
255
+ if (context == child->nextchild)
256
+ {
257
+ child->nextchild = context->nextchild;
258
+ break;
259
+ }
260
+ }
261
+ }
262
+ }
263
+ (*context->methods->del) (context);
264
+ se_free(context);
265
+ }
266
+
267
+ /*
268
+ * MemoryContextDeleteChildren
269
+ * Delete all the descendants of the named context and release all
270
+ * space allocated therein. The named context itself is not touched.
271
+ */
272
+ void
273
+ MemoryContextDeleteChildren(MemoryContext context)
274
+ {
275
+ U_ASSERT(MemoryContextIsValid(context));
276
+
277
+ /*
278
+ * MemoryContextDelete will delink the child from me, so just iterate as
279
+ * long as there is a child.
280
+ */
281
+ while (context->firstchild != NULL)
282
+ MemoryContextDelete(context->firstchild);
283
+ }
284
+
285
+ /*
286
+ * MemoryContextResetAndDeleteChildren
287
+ * Release all space allocated within a context and delete all
288
+ * its descendants.
289
+ *
290
+ * This is a common combination case where we want to preserve the
291
+ * specific context but get rid of absolutely everything under it.
292
+ */
293
+ void
294
+ MemoryContextResetAndDeleteChildren(MemoryContext context)
295
+ {
296
+ U_ASSERT(MemoryContextIsValid(context));
297
+
298
+ MemoryContextDeleteChildren(context);
299
+ (*context->methods->reset) (context);
300
+ }
301
+
302
+ /*
303
+ * GetMemoryChunkSpace
304
+ * Given a currently-allocated chunk, determine the total space
305
+ * it occupies (including all memory-allocation overhead).
306
+ *
307
+ * This is useful for measuring the total space occupied by a set of
308
+ * allocated chunks.
309
+ */
310
+ usize_t
311
+ GetMemoryChunkSpace(void *pointer)
312
+ {
313
+ StandardChunkHeader *header;
314
+
315
+ /*
316
+ * Try to detect bogus pointers handed to us, poorly though we can.
317
+ * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
318
+ * allocated chunk.
319
+ */
320
+ U_ASSERT(pointer != NULL);
321
+ U_ASSERT(pointer == (void *) MAXALIGN(pointer));
322
+
323
+ /*
324
+ * OK, it's probably safe to look at the chunk header.
325
+ */
326
+ header = (StandardChunkHeader *)
327
+ ((char *) pointer - STANDARDCHUNKHEADERSIZE);
328
+
329
+ U_ASSERT(MemoryContextIsValid(header->context));
330
+
331
+ return (*header->context->methods->get_chunk_space) (header->context,
332
+ pointer);
333
+ }
334
+
335
+ /*
336
+ * GetMemoryChunkContext
337
+ * Given a currently-allocated chunk, determine the context
338
+ * it belongs to.
339
+ */
340
+ MemoryContext
341
+ GetMemoryChunkContext(void *pointer)
342
+ {
343
+ StandardChunkHeader *header;
344
+
345
+ /*
346
+ * Try to detect bogus pointers handed to us, poorly though we can.
347
+ * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
348
+ * allocated chunk.
349
+ */
350
+ U_ASSERT(pointer != NULL);
351
+ U_ASSERT(pointer == (void *) MAXALIGN(pointer));
352
+
353
+ /*
354
+ * OK, it's probably safe to look at the chunk header.
355
+ */
356
+ header = (StandardChunkHeader *)
357
+ ((char *) pointer - STANDARDCHUNKHEADERSIZE);
358
+
359
+ U_ASSERT(MemoryContextIsValid(header->context));
360
+
361
+ return header->context;
362
+ }
363
+
364
+ /*
365
+ * MemoryContextIsEmpty
366
+ * Is a memory context empty of any allocated space?
367
+ */
368
+ bool
369
+ MemoryContextIsEmpty(MemoryContext context)
370
+ {
371
+ U_ASSERT(MemoryContextIsValid(context));
372
+
373
+ /*
374
+ * For now, we consider a memory context nonempty if it has any children;
375
+ * perhaps this should be changed later.
376
+ */
377
+ if (context->firstchild != NULL)
378
+ return false;
379
+ /* Otherwise use the type-specific inquiry */
380
+ return (*context->methods->is_empty) (context);
381
+ }
382
+
383
+ /*
384
+ * MemoryContextStats
385
+ * Print statistics about the named context and all its descendants.
386
+ *
387
+ * This is just a debugging utility, so it's not fancy. The statistics
388
+ * are merely sent to stderr.
389
+ */
390
+ void
391
+ MemoryContextStats(MemoryContext context)
392
+ {
393
+ MemoryContext child;
394
+
395
+ U_ASSERT(MemoryContextIsValid(context));
396
+
397
+ (*context->methods->stats) (context);
398
+ for (child = context->firstchild; child != NULL; child = child->nextchild)
399
+ MemoryContextStats(child);
400
+ }
401
+
402
+
403
+ /*
404
+ * MemoryContextCheck
405
+ * Check all chunks in the named context.
406
+ *
407
+ * This is just a debugging utility, so it's not fancy.
408
+ */
409
+ #ifdef MEMORY_CONTEXT_CHECKING
410
+ void
411
+ MemoryContextCheck(MemoryContext context)
412
+ {
413
+ MemoryContext child;
414
+
415
+ U_ASSERT(MemoryContextIsValid(context));
416
+
417
+ (*context->methods->check) (context);
418
+ for (child = context->firstchild; child != NULL; child = child->nextchild)
419
+ MemoryContextCheck(child);
420
+ }
421
+ #endif
422
+
423
+ /*
424
+ * MemoryContextContains
425
+ * Detect whether an allocated chunk of memory belongs to a given
426
+ * context or not.
427
+ *
428
+ * Caution: this test is reliable as long as 'pointer' does point to
429
+ * a chunk of memory allocated from *some* context. If 'pointer' points
430
+ * at memory obtained in some other way, there is a small chance of a
431
+ * false-positive result, since the bits right before it might look like
432
+ * a valid chunk header by chance.
433
+ */
434
+ bool
435
+ MemoryContextContains(MemoryContext context, void *pointer)
436
+ {
437
+ StandardChunkHeader *header;
438
+
439
+ /*
440
+ * Try to detect bogus pointers handed to us, poorly though we can.
441
+ * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
442
+ * allocated chunk.
443
+ */
444
+ if (pointer == NULL || pointer != (void *) MAXALIGN(pointer))
445
+ return false;
446
+
447
+ /*
448
+ * OK, it's probably safe to look at the chunk header.
449
+ */
450
+ header = (StandardChunkHeader *)
451
+ ((char *) pointer - STANDARDCHUNKHEADERSIZE);
452
+
453
+ /*
454
+ * If the context link doesn't match then we certainly have a non-member
455
+ * chunk. Also check for a reasonable-looking size as extra guard against
456
+ * being fooled by bogus pointers.
457
+ */
458
+ if (header->context == context && AllocSizeIsValid(header->size))
459
+ return true;
460
+ return false;
461
+ }
462
+
463
+ /*--------------------
464
+ * MemoryContextCreate
465
+ * Context-type-independent part of context creation.
466
+ *
467
+ * This is only intended to be called by context-type-specific
468
+ * context creation routines, not by the unwashed masses.
469
+ *
470
+ * The context creation procedure is a little bit tricky because
471
+ * we want to be sure that we don't leave the context tree invalid
472
+ * in case of failure (such as insufficient memory to allocate the
473
+ * context node itself). The procedure goes like this:
474
+ * 1. Context-type-specific routine first calls MemoryContextCreate(),
475
+ * passing the appropriate tag/size/methods values (the methods
476
+ * pointer will ordinarily point to statically allocated data).
477
+ * The parent and name parameters usually come from the caller.
478
+ * 2. MemoryContextCreate() attempts to allocate the context node,
479
+ * plus space for the name. If this fails we can ereport() with no
480
+ * damage done.
481
+ * 3. We fill in all of the type-independent MemoryContext fields.
482
+ * 4. We call the type-specific init routine (using the methods pointer).
483
+ * The init routine is required to make the node minimally valid
484
+ * with zero chance of failure --- it can't allocate more memory,
485
+ * for example.
486
+ * 5. Now we have a minimally valid node that can behave correctly
487
+ * when told to reset or delete itself. We link the node to its
488
+ * parent (if any), making the node part of the context tree.
489
+ * 6. We return to the context-type-specific routine, which finishes
490
+ * up type-specific initialization. This routine can now do things
491
+ * that might fail (like allocate more memory), so long as it's
492
+ * sure the node is left in a state that delete will handle.
493
+ *
494
+ * This protocol doesn't prevent us from leaking memory if step 6 fails
495
+ * during creation of a top-level context, since there's no parent link
496
+ * in that case. However, if you run out of memory while you're building
497
+ * a top-level context, you might as well go home anyway...
498
+ *
499
+ * Normally, the context node and the name are allocated from
500
+ * TopMemoryContext (NOT from the parent context, since the node must
501
+ * survive resets of its parent context!). However, this routine is itself
502
+ * used to create TopMemoryContext! If we see that TopMemoryContext is NULL,
503
+ * we assume we are creating TopMemoryContext and use malloc() to allocate
504
+ * the node.
505
+ *
506
+ * Note that the name field of a MemoryContext does not point to
507
+ * separately-allocated storage, so it should not be freed at context
508
+ * deletion.
509
+ *--------------------
510
+ */
511
+ MemoryContext
512
+ MemoryContextCreate(usize_t size,
513
+ MemoryContextMethods *methods,
514
+ MemoryContext parent,
515
+ const char *name)
516
+ {
517
+ MemoryContext node;
518
+ usize_t needed = size + strlen(name) + 1;
519
+
520
+ /* Get space for node and name */
521
+ if (TopMemoryContext != NULL)
522
+ {
523
+ /* Normal case: allocate the node in TopMemoryContext */
524
+ node = (MemoryContext) MemoryContextAlloc(TopMemoryContext,
525
+ needed);
526
+ }
527
+ else
528
+ {
529
+ /* Special case for startup: use good ol' malloc */
530
+ node = (MemoryContext) malloc(needed);
531
+ U_ASSERT(node != NULL);
532
+ }
533
+
534
+ /* Initialize the node as best we can */
535
+ MemSet(node, 0, size);
536
+ node->methods = methods;
537
+ node->parent = NULL; /* for the moment */
538
+ node->firstchild = NULL;
539
+ node->nextchild = NULL;
540
+ node->name = ((char *) node) + size;
541
+ strcpy(node->name, name);
542
+
543
+ /* Type-specific routine finishes any other essential initialization */
544
+ (*node->methods->init) (node);
545
+
546
+ /* OK to link node to parent (if any) */
547
+ if (parent)
548
+ {
549
+ node->parent = parent;
550
+ node->nextchild = parent->firstchild;
551
+ parent->firstchild = node;
552
+ }
553
+
554
+ /* Return to type-specific creation routine to finish up */
555
+ return node;
556
+ }
557
+
558
+ /*
559
+ * MemoryContextAlloc
560
+ * Allocate space within the specified context.
561
+ *
562
+ * This could be turned into a macro, but we'd have to import
563
+ * nodes/memnodes.h into postgres.h which seems a bad idea.
564
+ */
565
+ void *
566
+ MemoryContextAlloc(MemoryContext context, usize_t size)
567
+ {
568
+ U_ASSERT(MemoryContextIsValid(context));
569
+
570
+ if (!AllocSizeIsValid(size))
571
+ /*
572
+ elog(ERROR, "invalid memory alloc request size %lu",
573
+ (unsigned long) size)*/;
574
+
575
+ return (*context->methods->alloc) (context, size);
576
+ }
577
+
578
+ /*
579
+ * MemoryContextAllocZero
580
+ * Like MemoryContextAlloc, but clears allocated memory
581
+ *
582
+ * We could just call MemoryContextAlloc then clear the memory, but this
583
+ * is a very common combination, so we provide the combined operation.
584
+ */
585
+ void *
586
+ MemoryContextAllocZero(MemoryContext context, usize_t size)
587
+ {
588
+ void *ret;
589
+
590
+ U_ASSERT(MemoryContextIsValid(context));
591
+
592
+ if (!AllocSizeIsValid(size))
593
+ /*
594
+ elog(ERROR, "invalid memory alloc request size %lu",
595
+ (unsigned long) size)*/;
596
+
597
+ ret = (*context->methods->alloc) (context, size);
598
+
599
+ MemSetAligned(ret, 0, size);
600
+
601
+ return ret;
602
+ }
603
+
604
+ /*
605
+ * MemoryContextAllocZeroAligned
606
+ * MemoryContextAllocZero where length is suitable for MemSetLoop
607
+ *
608
+ * This might seem overly specialized, but it's not because newNode()
609
+ * is so often called with compile-time-constant sizes.
610
+ */
611
+ void *
612
+ MemoryContextAllocZeroAligned(MemoryContext context, usize_t size)
613
+ {
614
+ void *ret;
615
+
616
+ U_ASSERT(MemoryContextIsValid(context));
617
+
618
+ if (!AllocSizeIsValid(size))
619
+ /*
620
+ elog(ERROR, "invalid memory alloc request size %lu",
621
+ (unsigned long) size)*/;
622
+
623
+ ret = (*context->methods->alloc) (context, size);
624
+
625
+ MemSetLoop(ret, 0, size);
626
+
627
+ return ret;
628
+ }
629
+
630
+ /*
631
+ * se_free
632
+ * Release an allocated chunk.
633
+ */
634
+ void
635
+ se_free(void *pointer)
636
+ {
637
+ #ifdef SE_MEMORY_MNG
638
+ StandardChunkHeader *header;
639
+
640
+ /*
641
+ * Try to detect bogus pointers handed to us, poorly though we can.
642
+ * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
643
+ * allocated chunk.
644
+ */
645
+ U_ASSERT(pointer != NULL);
646
+ U_ASSERT(pointer == (void *) MAXALIGN(pointer));
647
+
648
+ /*
649
+ * OK, it's probably safe to look at the chunk header.
650
+ */
651
+ header = (StandardChunkHeader *)
652
+ ((char *) pointer - STANDARDCHUNKHEADERSIZE);
653
+
654
+ U_ASSERT(MemoryContextIsValid(header->context));
655
+
656
+ (*header->context->methods->free_p) (header->context, pointer);
657
+ #else
658
+ free(pointer);
659
+ #endif
660
+ }
661
+
662
+ /*
663
+ * se_realloc
664
+ * Adjust the size of a previously allocated chunk.
665
+ */
666
+ void *
667
+ se_realloc(void *pointer, usize_t size)
668
+ {
669
+ #ifdef SE_MEMORY_MNG
670
+ StandardChunkHeader *header;
671
+
672
+ /*
673
+ * Try to detect bogus pointers handed to us, poorly though we can.
674
+ * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
675
+ * allocated chunk.
676
+ */
677
+ U_ASSERT(pointer != NULL);
678
+ U_ASSERT(pointer == (void *) MAXALIGN(pointer));
679
+
680
+ /*
681
+ * OK, it's probably safe to look at the chunk header.
682
+ */
683
+ header = (StandardChunkHeader *)
684
+ ((char *) pointer - STANDARDCHUNKHEADERSIZE);
685
+
686
+ U_ASSERT(MemoryContextIsValid(header->context));
687
+
688
+ if (!AllocSizeIsValid(size))
689
+ /*
690
+ elog(ERROR, "invalid memory alloc request size %lu",
691
+ (unsigned long) size)*/;
692
+
693
+ return (*header->context->methods->realloc) (header->context,
694
+ pointer, size);
695
+ #else
696
+ return realloc(pointer, size);
697
+ #endif
698
+ }
699
+
700
+
701
+ /*
702
+ * MemoryContextSwitchTo
703
+ * Returns the current context; installs the given context.
704
+ *
705
+ * This is inlined when using GCC.
706
+ *
707
+ * TODO: investigate supporting inlining for some non-GCC compilers.
708
+ */
709
+ #ifndef __GNUC__
710
+
711
+ MemoryContext
712
+ MemoryContextSwitchTo(MemoryContext context)
713
+ {
714
+ MemoryContext old;
715
+
716
+ U_ASSERT(MemoryContextIsValid(context));
717
+
718
+ old = CurrentMemoryContext;
719
+ CurrentMemoryContext = context;
720
+ return old;
721
+ }
722
+ #endif /* ! __GNUC__ */
723
+
724
+ /*
725
+ * MemoryContextStrdup
726
+ * Like strdup(), but allocate from the specified context
727
+ */
728
+ char *
729
+ MemoryContextStrdup(MemoryContext context, const char *string)
730
+ {
731
+ char *nstr;
732
+ usize_t len = strlen(string) + 1;
733
+
734
+ nstr = (char *) MemoryContextAlloc(context, len);
735
+
736
+ memcpy(nstr, string, len);
737
+
738
+ return nstr;
739
+ }
740
+
741
+ #endif /* SE_MEMORY_TRACK */