せっかくMacBook Air買ったがほとんど使ってないのでちゃんと使いかた覚えよう。

とりあえずぱっと思い付くのは

  • objc
  • chud
  • pthread
  • create remote threadみたいの
  • dll injectionみたいなの

あたりか。

あ、ACアダプタ忘れた。バッテリの残り時間との戦いだなぁ…

commpage

Linuxのvdsoみたいなもんかな…commpage = カーネルとユーザ空間で共通(common)のページってことか?

誰がマップしてんだ。カーネル?dyld?

#include <unistd.h>

int main() {
    _exit(1);
}

みたいなのを動かして…あ、lazy bindのせいでデバッガで追いにくいな…gdbそんな機能なかったっけ→あ、info gdb見れない。→普通に b _exit で見れるし。

よく考えたらLinuxのvdsoも誰がマップしてか知らんな…もういいか。

objc

allocてどう書いたらいいんだ…もういいやNSObject使おう。
ところでOSXはなんで実行ファイルデフォルトがPICになってるんだろう。

昔も見た気がするが、この文章がすばらしいな。

msgSend_fixup になるのとならないのって何で決まってるんだ…
GCC の objc-act.c の nonlegacy_disaptched_selectors か?

/* Non-legacy dispatch is a performance optimization only. 
   Using the "wrong" dispatch is not a correctness problem, 
   assuming non-legacy dispatch is supported at all. 

   SnowLeopard: only the selectors below are optimized by the runtime. 
     Other selectors should use legacy dispatch to save memory.
*/

Non-legacy dispatchてどういう意味?

まあいいか。↓とりあえずどのくらい効果あるか測った。

#include <Foundation/Foundation.h>
#include <stdio.h>

static inline int
rdtsc() {
    int lo,hi;
    __asm__ __volatile__ ("rdtsc"
                          :"=a"(lo), "=d"(hi));
    return lo;
}

@interface Nanika : NSObject
-(id)self;
-(int) f;
-(int) fi : (NSInteger)v;
@end
@implementation Nanika
-(id)self
{
    return NULL;
}

-(int) f
{
    return 10;
}

-(int) fi : (NSInteger)v
{
    return v;
}
@end

int main()
{
    Nanika *n = [Nanika alloc];
    int nloop = 1000, i, b, e;

    [n self];
    [n f];
    [n fi:10];

    b = rdtsc();
    for (i=0; i<nloop; i++) {
        [n self];
    }
    e = rdtsc();
    printf("%f\n", (e-b)/(double)nloop);


    b = rdtsc();
    for (i=0; i<nloop; i++) {
        [n fi:10];
    }
    e = rdtsc();
    printf("%f\n", (e-b)/(double)nloop);

    b = rdtsc();
    for (i=0; i<nloop; i++) {
        [n f];
    }
    e = rdtsc();
    printf("%f\n", (e-b)/(double)nloop);
}

↓結果。半分にならないくらいか。

10.640000
18.004000
17.703000

あと、一回目の呼び出しとか多分全然違うんだよな。

まあいいや大体わかった。いや、あんまりわかってないが…何のソース見ればいいかわかったからいいや。

pthread

高速なスレッド間通信がしたい。

PFZてなんだ。preemption free zone->なんかこのアドレスにいるときにcontext switchしたらカーネルがebxに値を設定してくれるらしい。ん?自分がコンテキストスイッチしたかどうか、っていうのって情報として意味あるか?
あ、いや、違うか、他のスレッドがペンディングしてるかどうかを示す値がebxに入っていて、他のスレッドが待機していないあいだビジーループする、という処理か。なるほど。

WindowsのSetEvent, ResetEventみたいなのが欲しいのだが、どう書くんだ。

libdispatchはsemaphore_signal使ってんな。OSAtomicFifoEnqueueとかどう使うんだろうか。
まあいいか。多分semaphore組み合わせてなんとかするしか無いな。

#include <mach/semaphore.h>
#include <mach/mach_init.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

static inline int
rdtsc() {
    int lo,hi;
    __asm__ __volatile__ ("rdtsc"
                          :"=a"(lo), "=d"(hi));
    return lo;
}

pthread_t t;
semaphore_t s2c, c2s;

void *f(void *p)
{
    while (1) {
        semaphore_wait(s2c);
        semaphore_signal(c2s);
    }
}

int main()
{
    int i;
    semaphore_create(current_task(), &s2c, SYNC_POLICY_FIFO, 0);
    semaphore_create(current_task(), &c2s, SYNC_POLICY_FIFO, 0);

    pthread_create(&t, NULL, f, NULL);

    for (i=0; i<100; i++) {
        int b,e;

        getchar();

        b = rdtsc();
        semaphore_signal(s2c);
        semaphore_wait(c2s);
        e = rdtsc();

        printf("%d\n", e-b);
    }
}

速いときで20000くらいに見える。futexとかwin32のEventだと…今手元にデータ無いが…同じくらいだったような。

chud

あ、時間になってしまった。全然調べてないや。

woman

なんかmanが全体的にwomanで見れなくてwoman派の俺死亡。

メモ

osfmk/i386/cpu_capabilities.h -> commpageにいる関数の一覧ぽいの
runtime/Messengers.subproj/objc-msg-x86_64.s : メッセージ
objc-act.c -> 上のん

ところで「OSXBSD」って誰がどういう根拠で言い出したんだ…「デフォルトのシェルがbashだからGNUシステム」とかでもいいんではないかというぐらいの根拠の気がするが。


あとid:isshikiさんに見せてもらったYD-386Aが素晴らしかった。

まとめ

おい全然目標まで進んでないぞ。
13:30 - 17:22 で バッテリ 残り24%。この使いかただと5時間ぐらい使えるというところか。