mcxt.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:12k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * mcxt.c
  4.  *   POSTGRES memory context code.
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.14.2.1 1999/08/02 05:25:16 scrappy Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. #include "postgres.h"
  15. #include "nodes/memnodes.h"
  16. #include "utils/excid.h"
  17. #include "utils/module.h"
  18. #undef MemoryContextAlloc
  19. #undef MemoryContextFree
  20. #undef malloc
  21. #undef free
  22. /*
  23.  * Global State
  24.  */
  25. static int MemoryContextEnableCount = 0;
  26. #define MemoryContextEnabled (MemoryContextEnableCount > 0)
  27. static OrderedSetData ActiveGlobalMemorySetData; /* uninitialized */
  28. #define ActiveGlobalMemorySet (&ActiveGlobalMemorySetData)
  29. /*
  30.  * description of allocated memory representation goes here
  31.  */
  32. #define PSIZE(PTR) (*((int32 *)(PTR) - 1))
  33. #define PSIZEALL(PTR) (*((int32 *)(PTR) - 1) + sizeof (int32))
  34. #define PSIZESKIP(PTR) ((char *)((int32 *)(PTR) + 1))
  35. #define PSIZEFIND(PTR) ((char *)((int32 *)(PTR) - 1))
  36. #define PSIZESPACE(LEN) ((LEN) + sizeof (int32))
  37. /*
  38.  * AllocSizeIsValid
  39.  * True iff 0 < size and size <= MaxAllocSize.
  40.  */
  41. #define AllocSizeIsValid(size) (0 < (size) && (size) <= MaxAllocSize)
  42. /*****************************************************************************
  43.  *   GLOBAL MEMORY  *
  44.  *****************************************************************************/
  45. /*
  46.  * CurrentMemoryContext
  47.  * Memory context for general global allocations.
  48.  */
  49. DLLIMPORT MemoryContext CurrentMemoryContext = NULL;
  50. /*****************************************************************************
  51.  *   PRIVATE DEFINITIONS  *
  52.  *****************************************************************************/
  53. static Pointer GlobalMemoryAlloc(GlobalMemory this, Size size);
  54. static void GlobalMemoryFree(GlobalMemory this, Pointer pointer);
  55. static Pointer GlobalMemoryRealloc(GlobalMemory this, Pointer pointer,
  56. Size size);
  57. static char *GlobalMemoryGetName(GlobalMemory this);
  58. static void GlobalMemoryDump(GlobalMemory this);
  59. #ifdef NOT_USED
  60. static void DumpGlobalMemories(void);
  61. #endif
  62. /*
  63.  * Global Memory Methods
  64.  */
  65. static struct MemoryContextMethodsData GlobalContextMethodsData = {
  66. GlobalMemoryAlloc, /* Pointer (*)(this, uint32)  palloc */
  67. GlobalMemoryFree, /* void (*)(this, Pointer)   pfree */
  68. GlobalMemoryRealloc, /* Pointer (*)(this, Pointer) repalloc */
  69. GlobalMemoryGetName, /* char* (*)(this)   getName */
  70. GlobalMemoryDump /* void (*)(this)   dump */
  71. };
  72. /*
  73.  * Note:
  74.  * TopGlobalMemory is handled specially because of bootstrapping.
  75.  */
  76. /* extern bool EqualGlobalMemory(); */
  77. static struct GlobalMemoryData TopGlobalMemoryData = {
  78. T_GlobalMemory, /* NodeTag tag   */
  79. &GlobalContextMethodsData, /* ContextMethods method   */
  80. {NULL, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}},
  81. /* free AllocSet   */
  82. "TopGlobal", /* char* name    */
  83. {0} /* uninitialized OrderedElemData elemD */
  84. };
  85. /*
  86.  * TopMemoryContext
  87.  * Memory context for general global allocations.
  88.  *
  89.  * Note:
  90.  * Don't use this memory context for random allocations.  If you
  91.  * allocate something here, you are expected to clean it up when
  92.  * appropriate.
  93.  */
  94. MemoryContext TopMemoryContext = (MemoryContext) &TopGlobalMemoryData;
  95. /*
  96.  * Module State
  97.  */
  98. /*
  99.  * EnableMemoryContext
  100.  * Enables/disables memory management and global contexts.
  101.  *
  102.  * Note:
  103.  * This must be called before creating contexts or allocating memory.
  104.  * This must be called before other contexts are created.
  105.  *
  106.  * Exceptions:
  107.  * BadArg if on is invalid.
  108.  * BadState if on is false when disabled.
  109.  */
  110. void
  111. EnableMemoryContext(bool on)
  112. {
  113. static bool processing = false;
  114. AssertState(!processing);
  115. AssertArg(BoolIsValid(on));
  116. if (BypassEnable(&MemoryContextEnableCount, on))
  117. return;
  118. processing = true;
  119. if (on)
  120. { /* initialize */
  121. /* initialize TopGlobalMemoryData.setData */
  122. AllocSetInit(&TopGlobalMemoryData.setData, DynamicAllocMode,
  123.  (Size) 0);
  124. /* make TopGlobalMemoryData member of ActiveGlobalMemorySet */
  125. OrderedSetInit(ActiveGlobalMemorySet,
  126.    offsetof(struct GlobalMemoryData, elemData));
  127. OrderedElemPushInto(&TopGlobalMemoryData.elemData,
  128. ActiveGlobalMemorySet);
  129. /* initialize CurrentMemoryContext */
  130. CurrentMemoryContext = TopMemoryContext;
  131. }
  132. else
  133. { /* cleanup */
  134. GlobalMemory context;
  135. /* walk the list of allocations */
  136. while (PointerIsValid(context = (GlobalMemory)
  137.   OrderedSetGetHead(ActiveGlobalMemorySet)))
  138. {
  139. if (context == &TopGlobalMemoryData)
  140. {
  141. /* don't free it and clean it last */
  142. OrderedElemPop(&TopGlobalMemoryData.elemData);
  143. }
  144. else
  145. GlobalMemoryDestroy(context);
  146. /* what is needed for the top? */
  147. }
  148. /*
  149.  * Freeing memory here should be safe as this is called only after
  150.  * all modules which allocate in TopMemoryContext have been
  151.  * disabled.
  152.  */
  153. /* step through remaining allocations and log */
  154. /* AllocSetStep(...); */
  155. /* deallocate whatever is left */
  156. AllocSetReset(&TopGlobalMemoryData.setData);
  157. }
  158. processing = false;
  159. }
  160. /*
  161.  * MemoryContextAlloc
  162.  * Returns pointer to aligned allocated memory in the given context.
  163.  *
  164.  * Note:
  165.  * none
  166.  *
  167.  * Exceptions:
  168.  * BadState if called before InitMemoryManager.
  169.  * BadArg if context is invalid or if size is 0.
  170.  * BadAllocSize if size is larger than MaxAllocSize.
  171.  */
  172. Pointer
  173. MemoryContextAlloc(MemoryContext context, Size size)
  174. {
  175. AssertState(MemoryContextEnabled);
  176. AssertArg(MemoryContextIsValid(context));
  177. LogTrap(!AllocSizeIsValid(size), BadAllocSize,
  178. ("size=%d [0x%x]", size, size));
  179. return context->method->alloc(context, size);
  180. }
  181. /*
  182.  * MemoryContextFree
  183.  * Frees allocated memory referenced by pointer in the given context.
  184.  *
  185.  * Note:
  186.  * none
  187.  *
  188.  * Exceptions:
  189.  * ???
  190.  * BadArgumentsErr if firstTime is true for subsequent calls.
  191.  */
  192. void
  193. MemoryContextFree(MemoryContext context, Pointer pointer)
  194. {
  195. AssertState(MemoryContextEnabled);
  196. AssertArg(MemoryContextIsValid(context));
  197. AssertArg(PointerIsValid(pointer));
  198. context->method->free_p(context, pointer);
  199. }
  200. /*
  201.  * MemoryContextRelloc
  202.  * Returns pointer to aligned allocated memory in the given context.
  203.  *
  204.  * Note:
  205.  * none
  206.  *
  207.  * Exceptions:
  208.  * ???
  209.  * BadArgumentsErr if firstTime is true for subsequent calls.
  210.  */
  211. Pointer
  212. MemoryContextRealloc(MemoryContext context,
  213.  Pointer pointer,
  214.  Size size)
  215. {
  216. AssertState(MemoryContextEnabled);
  217. AssertArg(MemoryContextIsValid(context));
  218. AssertArg(PointerIsValid(pointer));
  219. LogTrap(!AllocSizeIsValid(size), BadAllocSize,
  220. ("size=%d [0x%x]", size, size));
  221. return context->method->realloc(context, pointer, size);
  222. }
  223. /*
  224.  * MemoryContextGetName
  225.  * Returns pointer to aligned allocated memory in the given context.
  226.  *
  227.  * Note:
  228.  * none
  229.  *
  230.  * Exceptions:
  231.  * ???
  232.  * BadArgumentsErr if firstTime is true for subsequent calls.
  233.  */
  234. #ifdef NOT_USED
  235. char *
  236. MemoryContextGetName(MemoryContext context)
  237. {
  238. AssertState(MemoryContextEnabled);
  239. AssertArg(MemoryContextIsValid(context));
  240. return context->method->getName(context);
  241. }
  242. #endif
  243. /*
  244.  * PointerGetAllocSize
  245.  * Returns size of aligned allocated memory given pointer to it.
  246.  *
  247.  * Note:
  248.  * none
  249.  *
  250.  * Exceptions:
  251.  * ???
  252.  * BadArgumentsErr if firstTime is true for subsequent calls.
  253.  */
  254. #ifdef NOT_USED
  255. Size
  256. PointerGetAllocSize(Pointer pointer)
  257. {
  258. AssertState(MemoryContextEnabled);
  259. AssertArg(PointerIsValid(pointer));
  260. return PSIZE(pointer);
  261. }
  262. #endif
  263. /*
  264.  * MemoryContextSwitchTo
  265.  * Returns the current context; installs the given context.
  266.  *
  267.  * Note:
  268.  * none
  269.  *
  270.  * Exceptions:
  271.  * BadState if called when disabled.
  272.  * BadArg if context is invalid.
  273.  */
  274. MemoryContext
  275. MemoryContextSwitchTo(MemoryContext context)
  276. {
  277. MemoryContext old;
  278. AssertState(MemoryContextEnabled);
  279. AssertArg(MemoryContextIsValid(context));
  280. old = CurrentMemoryContext;
  281. CurrentMemoryContext = context;
  282. return old;
  283. }
  284. /*
  285.  * External Functions
  286.  */
  287. /*
  288.  * CreateGlobalMemory
  289.  * Returns new global memory context.
  290.  *
  291.  * Note:
  292.  * Assumes name is static.
  293.  *
  294.  * Exceptions:
  295.  * BadState if called when disabled.
  296.  * BadState if called outside TopMemoryContext (TopGlobalMemory).
  297.  * BadArg if name is invalid.
  298.  */
  299. GlobalMemory
  300. CreateGlobalMemory(char *name) /* XXX MemoryContextName */
  301. {
  302. GlobalMemory context;
  303. MemoryContext savecxt;
  304. AssertState(MemoryContextEnabled);
  305. savecxt = MemoryContextSwitchTo(TopMemoryContext);
  306. context = (GlobalMemory) newNode(sizeof(struct GlobalMemoryData), T_GlobalMemory);
  307. context->method = &GlobalContextMethodsData;
  308. context->name = name; /* assumes name is static */
  309. AllocSetInit(&context->setData, DynamicAllocMode, (Size) 0);
  310. /* link the context */
  311. OrderedElemPushInto(&context->elemData, ActiveGlobalMemorySet);
  312. MemoryContextSwitchTo(savecxt);
  313. return context;
  314. }
  315. /*
  316.  * GlobalMemoryDestroy
  317.  * Destroys given global memory context.
  318.  *
  319.  * Exceptions:
  320.  * BadState if called when disabled.
  321.  * BadState if called outside TopMemoryContext (TopGlobalMemory).
  322.  * BadArg if context is invalid GlobalMemory.
  323.  * BadArg if context is TopMemoryContext (TopGlobalMemory).
  324.  */
  325. void
  326. GlobalMemoryDestroy(GlobalMemory context)
  327. {
  328. AssertState(MemoryContextEnabled);
  329. AssertArg(IsA(context, GlobalMemory));
  330. AssertArg(context != &TopGlobalMemoryData);
  331. AllocSetReset(&context->setData);
  332. /* unlink and delete the context */
  333. OrderedElemPop(&context->elemData);
  334. MemoryContextFree(TopMemoryContext, (Pointer) context);
  335. }
  336. /*****************************************************************************
  337.  *   PRIVATE  *
  338.  *****************************************************************************/
  339. /*
  340.  * GlobalMemoryAlloc
  341.  * Returns pointer to aligned space in the global context.
  342.  *
  343.  * Exceptions:
  344.  * ExhaustedMemory if allocation fails.
  345.  */
  346. static Pointer
  347. GlobalMemoryAlloc(GlobalMemory this, Size size)
  348. {
  349. return AllocSetAlloc(&this->setData, size);
  350. }
  351. /*
  352.  * GlobalMemoryFree
  353.  * Frees allocated memory in the global context.
  354.  *
  355.  * Exceptions:
  356.  * BadContextErr if current context is not the global context.
  357.  * BadArgumentsErr if pointer is invalid.
  358.  */
  359. static void
  360. GlobalMemoryFree(GlobalMemory this,
  361.  Pointer pointer)
  362. {
  363. AllocSetFree(&this->setData, pointer);
  364. }
  365. /*
  366.  * GlobalMemoryRealloc
  367.  * Returns pointer to aligned space in the global context.
  368.  *
  369.  * Note:
  370.  * Memory associated with the pointer is freed before return.
  371.  *
  372.  * Exceptions:
  373.  * BadContextErr if current context is not the global context.
  374.  * BadArgumentsErr if pointer is invalid.
  375.  * NoMoreMemoryErr if allocation fails.
  376.  */
  377. static Pointer
  378. GlobalMemoryRealloc(GlobalMemory this,
  379. Pointer pointer,
  380. Size size)
  381. {
  382. return AllocSetRealloc(&this->setData, pointer, size);
  383. }
  384. /*
  385.  * GlobalMemoryGetName
  386.  * Returns name string for context.
  387.  *
  388.  * Exceptions:
  389.  * ???
  390.  */
  391. static char *
  392. GlobalMemoryGetName(GlobalMemory this)
  393. {
  394. return this->name;
  395. }
  396. /*
  397.  * GlobalMemoryDump
  398.  * Dumps global memory context for debugging.
  399.  *
  400.  * Exceptions:
  401.  * ???
  402.  */
  403. static void
  404. GlobalMemoryDump(GlobalMemory this)
  405. {
  406. GlobalMemory context;
  407. printf("--n%s:n", GlobalMemoryGetName(this));
  408. context = (GlobalMemory) OrderedElemGetPredecessor(&this->elemData);
  409. if (PointerIsValid(context))
  410. printf("tpredecessor=%sn", GlobalMemoryGetName(context));
  411. context = (GlobalMemory) OrderedElemGetSuccessor(&this->elemData);
  412. if (PointerIsValid(context))
  413. printf("tsucessor=%sn", GlobalMemoryGetName(context));
  414. AllocSetDump(&this->setData); /* XXX is this right interface */
  415. }
  416. /*
  417.  * DumpGlobalMemories
  418.  * Dumps all global memory contexts for debugging.
  419.  *
  420.  * Exceptions:
  421.  * ???
  422.  */
  423. #ifdef NOT_USED
  424. static void
  425. DumpGlobalMemories()
  426. {
  427. GlobalMemory context;
  428. context = (GlobalMemory) OrderedSetGetHead(&ActiveGlobalMemorySetData);
  429. while (PointerIsValid(context))
  430. {
  431. GlobalMemoryDump(context);
  432. context = (GlobalMemory) OrderedElemGetSuccessor(
  433.  &context->elemData);
  434. }
  435. }
  436. #endif