Fiber について今頃気付いたのですけど、

GNU Pth で良くね?

Lua とか Io とか組み込みたい、って考えたのは要するに二点。 C++コンパイル遅いよう、 Fiber が欲しいよう。

前者は D 使えば解決。んじゃ Fiber があればそれで終わり。んじゃ setjmp, longjmp で…っていう yuu さんのネタをひっこぬいて libfiber …って既にありそうだな…と思ってぐぐったら、

http://evanjones.ca/software/threading.html

案の定あった。この文章は良い文章だと思います。 Linux の clone システムコールUnix の ucontext.h 、 C89 の setjmp,longjmp のそれぞれで Fiber を実装する方法が紹介されてます。でも libfiber 自体は Unix に依存しているようだな…とか思って、

やっと思い出したのが GNU Pth 。ナゼこれを最初に思いつかなかった。

http://www.gnu.org/software/pth/

D で使ってみた。

extern (C) {
    alias void* pth_t;
    static const int PTH_ATTR_DEFAULT = 0;
    int pth_init();
    int pth_kill();
    int pth_yield(pth_t p);
    pth_t pth_spawn(int attr, void* (*)(void*), void*);
}

extern(C) void* spawn1(void* arg) {
    printf("1\n");
    pth_yield(null);
    printf("4\n");
    return null;
}

extern(C) void* spawn2(void* arg) {
    printf("2\n");
    pth_yield(null);
    printf("5\n");
    return null;
}

int main() {
    pth_t id1, id2;

    /* please check return value */
    pth_init();

    id1 = pth_spawn(PTH_ATTR_DEFAULT, &spawn1, null);
    id2 = pth_spawn(PTH_ATTR_DEFAULT, &spawn2, null);

    pth_yield(null);
    printf("3\n");
    pth_yield(null);

    return pth_kill();
}

何の問題もない。 GC というものについて相変わらずサッパリわかっとらんのですけど、大丈夫なんだろうか。まあとりあえず使ってみます。

追記: 今作ってるものに組み込んでみたけどやはし問題無いです。すばらしいです。一体いままで何を悩んでいたんだか。

extern (C) {
    alias void* pth_t;
    static const int PTH_ATTR_DEFAULT = 0;
    int pth_init();
    int pth_kill();
    int pth_cancel(pth_t);
    int pth_abort(pth_t);
    int pth_yield(pth_t p);
    pth_t pth_spawn(int attr, void* (*)(void*), void*);
}

この程度があれば何でもできるみたいです。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h