PostgreSQL/開発

概要

定義

マクロ

MaxAllocSize, MaxAllocHugeSize

マクロ名説明
MaxAllocSizeアロケーションの最大サイズ(1G-1)。
pallocでは,このサイズがリミットである。
(Size) 0x3fffffff
MaxAllocHugeSizeアロケーションの最大サイズ(SIZE_MAX/2)。
XXXHogeやXXX_huge系の関数ではこのリミットとなる。
(Size) -1 >> 1

このマクロ定数を直接使うシーンはあまりない。AllocHugeSizeIsValidやAllocSizeIsValidなどのチェックマクロがMemoryAllocXXXX関数で使われている。

AllocSizeIsValid, AllocHugeSizeIsValid

STANDARDCHUNKHEADERSIZE

MemoryContextResetAndDeleteChildren

ALLOCSET_DEFAULT_XXXX

定数説明
ALLOCSET_DEFAULT_MINSIZE0
ALLOCSET_DEFAULT_INITSIZE(8 * 1024)
ALLOCSET_DEFAULT_MAXSIZE(8 * 1024 * 1024)

ALLOCSET_SMALL_XXXX

定数説明
ALLOCSET_SMALL_MINSIZE0
ALLOCSET_SMALL_INITSIZE(1 * 1024)
ALLOCSET_SMALL_MAXSIZE(8 * 1024)

ALLOCSET_SEPARATE_THRESHOLD

列挙型

構造体

Struct

番号データ型フィールド説明

関数

MemoryContextInit

#define AllocSizeIsValid(size)	((Size) (size) <= MaxAllocSize)
#define AllocHugeSizeIsValid(size)	((Size) (size) <= MaxAllocHugeSize)

 参考  MemoryContextInit() - on doxygen.postgresql.org

MemoryContextReset

#define STANDARDCHUNKHEADERSIZE  MAXALIGN(sizeof(StandardChunkHeader))

 参考 

MemoryContextDelete

#define MemoryContextResetAndDeleteChildren(ctx) MemoryContextReset(ctx)

 参考  MemoryContextDelete() - on doxygen.postgresql.org

MemoryContextResetOnly

MemoryContext context = AllocSetContextCreate(CurrentMemoryContext,
                                              "my context",
                                              ALLOCSET_DEFAULT_MINSIZE,
                                              ALLOCSET_DEFAULT_INITSIZE,
                                              ALLOCSET_DEFAULT_MAXSIZE);

MemoryContextResetChildren

#define ALLOCSET_SEPARATE_THRESHOLD  8192

MemoryContextDeleteChildren

extern void MemoryContextInit(void);

 サンプル 

// 引数1:対象のメモリコンテキスト
extern void MemoryContextReset(MemoryContext context);

MemoryContextSetParent

// 引数1:対象のメモリコンテキスト
extern void MemoryContextDelete(MemoryContext context);

 参考  MemoryContextSetParent() - on doxygen.postgresql.org

GetMemoryChunkSpace

// 引数1:対象のメモリコンテキスト
extern void MemoryContextResetOnly(MemoryContext context);

 サンプル 

// 引数1:対象のメモリコンテキスト
extern void MemoryContextResetChildren(MemoryContext context);

GetMemoryChunkContext

// 引数1:対象のメモリコンテキスト
extern void MemoryContextDeleteChildren(MemoryContext context);

 サンプル 

#define BLOCK_SIZE 1024 * 8

void reset_callback(void *arg)
{
    MemoryContext context = (MemoryContext)arg;
    elog(NOTICE, "%s will be deleted.", context->name);
}

void sample()
{
    MemoryContext oldcontext = NULL;
    MemoryContextCallback callback;
    MemoryContextCallback callback2;

    // init parent context
    MemoryContext parent_context = AllocSetContextCreate(CurrentMemoryContext,
                                                  "parent context",
                                                  0,
                                                  BLOCK_SIZE,
                                                  BLOCK_SIZE);

    callback.func = reset_callback;
    callback.arg = parent_context;
    MemoryContextRegisterResetCallback(parent_context, &callback);

    oldcontext = MemoryContextSwitchTo(parent_context);

    // parent context from here
    StringInfo strinfo = makeStringInfo();
    appendStringInfo(strinfo, "Hello %s", "Duke");
    elog(NOTICE, "%s", strinfo->data);

    // init child context
    MemoryContext child_context = AllocSetContextCreate(parent_context,
                                                  "child context",
                                                  0,
                                                  BLOCK_SIZE,
                                                  BLOCK_SIZE);
    callback2.func = reset_callback;
    callback2.arg = child_context;
    MemoryContextRegisterResetCallback(child_context, &callback2);

    MemoryContextSwitchTo(child_context);

    // child context from here
    StringInfo strinfo2 = makeStringInfo();
    appendStringInfo(strinfo2, "Hello %s", "Togo");
    elog(NOTICE, "%s", strinfo2->data);


    // switch back to original context.
    MemoryContextSwitchTo(oldcontext);

    // delete parent_context and child_context
    //
    //  CurrentMemoryContext
    //    |- parent_context     <--- delete
    //        |- child_context  <--- delete
    MemoryContextDeleteChildren(CurrentMemoryContext);
}

MemoryContextGetParent

// 引数1:対象のメモリコンテキスト
// 引数2:新しい親となるメモリコンテキスト
extern void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent);

/* Change a context to belong a new parent.

== Before ==
new_parent             current_parent
  |- context1            |- context <-- move to (o)
  |- context2            |- next_context

== After ==
new_parent             current_parent
  |- context (o)         |- next_context
  |- context1
  |- context2            
*/

MemoryContextIsEmpty

// 引数1:メモリチャンクのポインタ
// 戻り値:メモリチャンクサイズ(ヘッダ含む)
extern Size GetMemoryChunkSpace(void *pointer);

 参考 

MemoryContextStats

void test_chunk_space()
{
    elog(NOTICE, "STANDARDCHUNKHEADERSIZE = %d", STANDARDCHUNKHEADERSIZE);

    char *chunk1 = palloc(128); // 128 + STANDARDCHUNKHEADERSIZE
    elog(NOTICE, "%d", GetMemoryChunkSpace(chunk1)); // NOTICE:  152

    char *chunk2 = palloc(256-32); // 256 + STANDARDCHUNKHEADERSIZE
    elog(NOTICE, "%d", GetMemoryChunkSpace(chunk2)); // NOTICE:  280
}

 サンプル 

// 引数1:メモリチャンクのポインタ
// 戻り値:メモリチャンクが属するメモリコンテキスト
extern MemoryContext GetMemoryChunkContext(void *pointer);

 参考  MemoryContextStats() - on doxygen.postgresql.org

MemoryContextAllowInCriticalSection

void test_chunk()
{
    MemoryContext context = AllocSetContextCreate(CurrentMemoryContext,
                                                         "my context",
                                                         0,
                                                         1024 * 8,
                                                         1024 * 8);

    MemoryContext oldcontext = MemoryContextSwitchTo(context);
    StringInfo strinfo = makeStringInfo();
    elog(NOTICE, "%s", GetMemoryChunkContext(strinfo)->name); // NOTICE:  my contex

    MemoryContextSwitchTo(oldcontext);
    MemoryContextDelete(context);
}

 参考  palloc() - on doxygen.postgresql.org

 実験 

// 引数1:対象のメモリコンテキスト
// 戻り値:contextの親のメモリコンテスト
extern MemoryContext MemoryContextGetParent(MemoryContext context);

MemoryContextCheck

// 引数1:対象のメモリコンテキスト
// 戻り値:true:空,false:空でない
extern bool MemoryContextIsEmpty(MemoryContext context);

MemoryContextContains

// 引数1:対象のメモリコンテキスト
extern void MemoryContextStats(MemoryContext context);

 参考  MemoryContextContains() - on doxygen.postgresql.org

 サンプル 

void test_chunk()
{
    MemoryContext context = AllocSetContextCreate(CurrentMemoryContext,
                                                         "my context",
                                                         0,
                                                         1024 * 8,
                                                         1024 * 8);


    MemoryContext oldcontext = MemoryContextSwitchTo(context);
    StringInfo strinfo = makeStringInfo();
    elog(NOTICE, "%s", GetMemoryChunkContext(strinfo)->name); // NOTICE:  my contex

    MemoryContextStats(context);
    // my context: 8192 total in 1 blocks; 7056 free (0 chunks); 1136 used

    MemoryContextSwitchTo(oldcontext);
    MemoryContextDelete(context);
}

MemoryContextCreate

// 引数1:対象のメモリコンテキスト
// 引数2:クリティカルセクションのメモリアローケーションを許可するか否か
//      true:許可する,false:許可しない
extern void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow);

AllocSetContextCreate

//
// Debug, on enable assertion
//
void test_crit()
{
    MemoryContext context = AllocSetContextCreate(CurrentMemoryContext,
                                                  "my context",
                                                  0,
                                                  1024 * 8,
                                                  1024 * 8);
    MemoryContextAllowInCriticalSection(context, true); // 許可しない,trueだと下のpallocは成功する
    // context->allowInCritSection = false; // 許可しない,trueだと下のpallocは成功する
    MemoryContext oldcontext = MemoryContextSwitchTo(context);

    START_CRIT_SECTION();
    // クリティカルセクション内でのメモリアローケーションは通常許可されない
    void *chunk = palloc(128);
    // TRAP: FailedAssertion("!(CritSectionCount == 0 || (CurrentMemoryContext)->allowInCritSection)", File: "mcxt.c", Line: 818)
    END_CRIT_SECTION();

    MemoryContextSwitchTo(oldcontext);
    MemoryContextDelete(context);
}

サンプルプログラム

// 引数1:対象のメモリコンテキスト
extern void MemoryContextCheck(MemoryContext context);

参考・関連

 関連 

コメント



トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
目次
ダブルクリックで閉じるTOP | 閉じる
GO TO TOP