[トップ][ノート][編集履歴][一覧][最近の更新][->English]

OpenBSD/Erlang/2006/09/12/hipe

Category of OpenBSD
Category of Erlang

ErlangにはHiPE(High Performance Erlang)というしかけがあって、 beam(erlangのためのvm)からネイティブコードを呼びだすよう変換することができる(hipeに関するスライド)。

FreeBSDでもx86だとhipeを有効にしてビルドする(FreeBSD-cvs:ports/lang/erlang/)ので、 OpenBSDでも動かないとおかしいわな、というわけで、otp-R11B-1をいじってみた。

まあ結果としては動いたのだが、別の問題が発覚したのでメモ。

さて、Erlangでhipeを有効にするには./configureに--enable-hipeを追加するだけでよろしい。OpenBSD-cvs:ports/lang/erlang/Makefileを見て、

./configure --disable-jinterface --disable-odbc --enable-threads --enable-kernel-poll --enable-hipe

このような感じか。

で、そのままだと、erts/emulator/hipe/hipe_x86_signal.cでこける。 ざっとコードを見たところ、OpenBSD-man:sigaltstackをdlsymして自前のsigaltstackでラップしているらしいことがわかる。

以前のエントリ(OpenBSD/2006/07/27/dlopen)を踏まえて、 このようなパッチを書いてみた: files:openbsd/otp_src_R11B-1-patch-erts_emulator_hipe_hipe_x86_signal.c

で、上のパッチを書いているときに気が付いたのだが、hipe_x86_signal.cから切り出した部分からのテストコード、

$ cat sigstack.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>

/*
 * Set alternate signal stack for the invoking thread.
 */
static void set_sigaltstack(void *ss_sp)
{
    struct sigaltstack ss;

    ss.ss_sp = ss_sp;
    ss.ss_flags = SS_ONSTACK;
    ss.ss_size = SIGSTKSZ;
    if (sigaltstack(&ss, NULL) < 0) {
    /* might be a broken pre-2.4 Linux kernel, try harder */
    ss.ss_flags = 0;
    if (sigaltstack(&ss, NULL) < 0) {
        perror("sigaltstack");
        abort();
    }
    }
}

main()
{
        static unsigned long my_sigstack[SIGSTKSZ/sizeof(long)];

        set_sigaltstack(my_sigstack);
}

が、-pthread付きでビルドしたときと、無しのときとで挙動が異なる。

$ cc sigstack.c
$ ./a.out
$
$ cc sigstack.c -pthread
$ ./a.out
sigaltstack: Invalid argument
$

結局のところ、 OpenBSD-cvs:src/lib/libpthread/uthread/uthread_sigaltstack.c 33行目はどうみても、

        if (ss == NULL) {

の間違いです。本当にありがとうございました。 本当にコードレビューしているのか怪しいものである。

ということでlibpthreadを再構築して、Erlangをビルド。

$ erl
Erlang (BEAM) emulator version 5.5.1 [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.5.1  (abort with ^G)
1>

hipeが有効になった。 ちなみにhipe付きのbeamコードは、

$ erlc +native file

とするか、erl上で、

> c(module, [native, {hipe, ['O3']}]).

とすればよい。めでたしめでたし。

blog comments powered by Disqus