忍者ブログ

きままなひとりごと

引っ越しました。新しいブログはnmtysh.logです。
2015/12/27

ブログを引っ越しました

ブログの引っ越しを行いました。
別サービスへの移行になるため過去記事をすべて再確認しつつ、記事の削除やリンクの差し替えなどを行っています。
現在では役に立たなくなっているtipsなどは削除していますのでご了承ください。

新しいブログはこちらです。
nmtysh.log

今後は新しいブログのほうで更新していきますのでそちらをご覧ください。
2017/01/17 (Tue) 23:58

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

2014/10/08 (Wed) 17:50

[Apache] MaxMemFree まわりのソースコード読み

最近 MaxMemFree をいじっているのですが、この値の効果を調べている時に気なるページを見つけました。
2011年の投稿なので少々古いですが、その中で
I repeated the test and did not see desired effect advertised by the documentation. Then I read in the forums the units may be Mb instead of KB as documented. VMAdmin: Apache MaxMemFree For Lean Memory Control

え、KiBじゃなくてMiBなの?と疑問に思って軽くソースコードを追ってみました。


結論から言うと KiB っぽいです。

server/core.c
AP_INIT_TAKE1("MaxMemFree", ap_mpm_set_max_mem_free, NULL, RSRC_CONF,
              "Maximum number of 1k blocks a particular childs allocator may hold."),
で、confファイルから値を読み取っています。
server/mpm_common.c
apr_uint32_t ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED;

const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy,
                                    const char *arg)
{
    long value;
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err != NULL) {
        return err;
    }

    value = strtol(arg, NULL, 0);
    if (value < 0 || errno == ERANGE)
        return apr_pstrcat(cmd->pool, "Invalid MaxMemFree value: ",
                           arg, NULL);

    ap_max_mem_free = (apr_uint32_t)value * 1024;

    return NULL;
}
実際に値をセットする際に読み取り値を1024倍してます。1124行目でデフォルト値の0を設定してます。

srclib/apr/memory/unix/apr_pools.c
APR_DECLARE(void) apr_allocator_max_free_set(apr_allocator_t *allocator,
                                             apr_size_t in_size)
{
    apr_uint32_t max_free_index;
    apr_uint32_t size = (APR_UINT32_TRUNC_CAST)in_size;

#if APR_HAS_THREADS
    apr_thread_mutex_t *mutex;

    mutex = apr_allocator_mutex_get(allocator);
    if (mutex != NULL)
        apr_thread_mutex_lock(mutex);
#endif /* APR_HAS_THREADS */

    max_free_index = APR_ALIGN(size, BOUNDARY_SIZE) >> BOUNDARY_INDEX;
    allocator->current_free_index += max_free_index;
    allocator->current_free_index -= allocator->max_free_index;
    allocator->max_free_index = max_free_index;
    if (allocator->current_free_index > max_free_index)
        allocator->current_free_index = max_free_index;

#if APR_HAS_THREADS
    if (mutex != NULL)
        apr_thread_mutex_unlock(mutex);
#endif
}

BOUNDARY_SIZE の倍数に切り上げて max_free_index とやらを設定しているようですが、
まだ、読み切れてないです……

あとは諸々の宣言部

srclib/apr/memory/unix/apr_pools.c
#define BOUNDARY_INDEX 12
#define BOUNDARY_SIZE (1 << BOUNDARY_INDEX)

srclib/apr/memory/unix/apr_pools.c
/*
 * Allocator
 *
 * @note The max_free_index and current_free_index fields are not really
 * indices, but quantities of BOUNDARY_SIZE big memory blocks.
 */

struct apr_allocator_t {
    /** largest used index into free[], always < MAX_INDEX */
    apr_uint32_t        max_index;
    /** Total size (in BOUNDARY_SIZE multiples) of unused memory before
     * blocks are given back. @see apr_allocator_max_free_set().
     * @note Initialized to APR_ALLOCATOR_MAX_FREE_UNLIMITED,
     * which means to never give back blocks.
     */
    apr_uint32_t        max_free_index;
    /**
     * Memory size (in BOUNDARY_SIZE multiples) that currently must be freed
     * before blocks are given back. Range: 0..max_free_index
     */
    apr_uint32_t        current_free_index;
#if APR_HAS_THREADS
    apr_thread_mutex_t *mutex;
#endif /* APR_HAS_THREADS */
    apr_pool_t         *owner;
    /**
     * Lists of free nodes. Slot 0 is used for oversized nodes,
     * and the slots 1..MAX_INDEX-1 contain nodes of sizes
     * (i+1) * BOUNDARY_SIZE. Example for BOUNDARY_INDEX == 12:
     * slot  0: nodes larger than 81920
     * slot  1: size  8192
     * slot  2: size 12288
     * ...
     * slot 19: size 81920
     */
    apr_memnode_t      *free[MAX_INDEX];
};

参考:
mpm_common - Apache HTTP Server Version 2.4
VMAdmin: Apache MaxMemFree For Lean Memory Control

拍手[0回]

PR