developer's diary

最近はc#のエントリが多いです

C初心者がmemcached-1.4.5を追いかける。(24)

C初心者がmemcached-1.4.5を追いかける。(23)の続き
ソースはコチラにてDLしました。

getoptで受け取ったパラメータによって処理を行っている部分を追いかける。

memcached.c(4411行目あたり)

        case 'L' :
            if (enable_large_pages() == 0) {
                preallocate = true;
            }
            break;
          "L"   /* Large memory pages */

enable_large_pagesの戻り値が0の場合preallocate をtrueに。
preallocate はslabs.cのslabs_initで利用してるみたいです。

preallocate のデフォルトはfalse memcached.c(4257行目あたり)

int main (int argc, char **argv) {
    int c;
    bool lock_memory = false;
    bool do_daemonize = false;
    bool preallocate = false;

でこの設定をみるためのenable_large_pages関数
enable_large_pagesはmemcached.c(4214行目あたり)

/*
 * On systems that supports multiple page sizes we may reduce the
 * number of TLB-misses by using the biggest available page size
 */
static int enable_large_pages(void) {
#if defined(HAVE_GETPAGESIZES) && defined(HAVE_MEMCNTL)
    int ret = -1;
    size_t sizes[32];
    int avail = getpagesizes(sizes, 32);
    if (avail != -1) {
        size_t max = sizes[0];
        struct memcntl_mha arg = {0};
        int ii;

        for (ii = 1; ii < avail; ++ii) {
            if (max < sizes[ii]) {
                max = sizes[ii];
            }
        }

        arg.mha_flags   = 0;
        arg.mha_pagesize = max;
        arg.mha_cmd = MHA_MAPSIZE_BSSBRK;

        if (memcntl(0, 0, MC_HAT_ADVISE, (caddr_t)&arg, 0, 0) == -1) {
            fprintf(stderr, "Failed to set large pages: %s\n",
                    strerror(errno));
            fprintf(stderr, "Will use default page size\n");
        } else {
            ret = 0;
        }
    } else {
        fprintf(stderr, "Failed to get supported pagesizes: %s\n",
                strerror(errno));
        fprintf(stderr, "Will use default page size\n");
    }

    return ret;
#else
    return 0;
#endif
}

HAVE_GETPAGESIZESとHAVE_MEMCNTLが有効であればロジックが走る

HAVE_GETPAGESIZESをgrep

config.h.in(22): #undef HAVE_GETPAGESIZES
memcached.c(4215): #if defined(HAVE_GETPAGESIZES) && defined(HAVE_MEMCNTL)

HAVE_MEMCNTLをgrep

config.h.in(31): #undef HAVE_MEMCNTL
memcached.c(4215): #if defined(HAVE_GETPAGESIZES) && defined(HAVE_MEMCNTL)

config.h.inで未定義にしているみたい。

#undefとは何?
http://www.mapee.jp/cpp/ifdef_endif_undef_ifndef.html

config.h.inの拡張子、h.inって何?
http://www.bookshelf.jp/texi/autoconf-ja/autoconf-ja_4.html#SEC28


HAVE_GETPAGESIZESとHAVE_MEMCNTLはsolalisで有効になるの?

getpagesizes(3C)という関数がsolalisにはあるみたいです。memcntl(2)も。
SPARC: Multiple Page Size Support
開発ツール (Solaris 9 12/03 オペレーティング環境の概要)

memcached.c(4218行目あたり)でもgetpagesizesが使われてます。
ソースを見る限り、getpagesizesが利用できても、enable_large_pagesの戻り値は0になるみたいです。
問題があればfprintfでエラーメッセージが吐かれる感じ。


他にgetpagesizesに関連するサイトは↓くらいしか見つからなかった。
http://www.nminoru.jp/~nminoru/diary/2004/09.html
http://download.oracle.com/docs/cd/E19082-01/820-2602/gdpqc/index.html


続きは↓
C初心者がmemcached-1.4.5を追いかける。(25)(Cオプション)