Mutexでは、deadlocksやpriority inversionsが発生するが、DragonFly BSDではSerializing toeknという仕組みを採用して、それを回避している。
簡単に言うと、「lock中のスレッドがsleepする場合、lockが解除される(他のスレッドがlockできる)」という物。
注意点は、
・sleepから起きた時に、lockしていたはずのリソースが変更されている可能性がある
メリットは、
・コードがかなりシンプルになる。
目からウロコ。すごいな、これ。
wikipediaの解説
Matt Dillionによる解説スレッド
Mutexと比較してのメリットがよくわかるメール
google-code-prettify
2007-05-14
2007-03-13
NetBSD-currentでnspluginwrapper動作せず
今までLinuxエミュレーションのfirefox-binを使っていたが、思う所があって、nativeなfirefox2+nspluginwrapperにする事にした。
ところが、pthreadまわり(_lwp_park)でSIGSEGVしてfirefoxが落ちる。
nspluginwrapperのplugin側とviewer側の間の通信は正しくできているっぽい。
newlock2のマージがあったので、まだthreadを使うアプリは正しく動作しないのだろうか。
やった事
1. nspluginwrapperのインストール
・src/npw-wrapper.cに、include <signal.h>を追加しておく
・$ ./configure
・$ gmake
・$ sudo gmake install
2. npviewerのインストール
npviewerはLinuxのバイナリを使う必要がある。
・npviewerのrpm(x86_64用)を持ってくる。
・$ rpm2cpio xxx.rpm > a.cpio
・$ cpio -i < a.cpio
展開した物は、/usr/lib/nspluginwrapper/i386/linux/に置く。
07/03/29 追記:
port-i386のメールによると、NetBSD i386 4.99.16だったり、gtk1だったりすると動作しないらしい。
うちの環境は、4.99.16でfirefox2-gtk1。ダメじゃん。
ところが、pthreadまわり(_lwp_park)でSIGSEGVしてfirefoxが落ちる。
nspluginwrapperのplugin側とviewer側の間の通信は正しくできているっぽい。
newlock2のマージがあったので、まだthreadを使うアプリは正しく動作しないのだろうか。
やった事
1. nspluginwrapperのインストール
・src/npw-wrapper.cに、include <signal.h>を追加しておく
・$ ./configure
・$ gmake
・$ sudo gmake install
2. npviewerのインストール
npviewerはLinuxのバイナリを使う必要がある。
・npviewerのrpm(x86_64用)を持ってくる。
・$ rpm2cpio xxx.rpm > a.cpio
・$ cpio -i < a.cpio
展開した物は、/usr/lib/nspluginwrapper/i386/linux/に置く。
07/03/29 追記:
port-i386のメールによると、NetBSD i386 4.99.16だったり、gtk1だったりすると動作しないらしい。
うちの環境は、4.99.16でfirefox2-gtk1。ダメじゃん。
2006-09-26
connect(2)でEADDRNOTAVAILを返している個所
connect(2)で接続先ポート番号が0の時にEADDRNOTAVAILが返るのだが、このエラーを返している個所を調べた。
connect(2)を呼ぶと、まずsys_connect()が呼ばれる。sys_connect()はsys/kern/uipc_syscalls.cにある。
sys_connect()ではgetsock()でsocketを取得。そのsocketをsoconnect()へ渡している。
soconnect()はsys/kern/uipc_socket.cにある。
で、プロトコル(so_proto)に応じたusrreq関数を呼んでいる。TCPの場合はtcp_usrreq()が呼ばれる。
tcp_usrreq()はsys/netinet/tcp_usrreq.cにあり、
と、in_pcbconnect()を呼んでいる。
netinet/in_pcb.cのin_pcbconnect()で、
とEADDRNOTAVAILを返している。
本当はgetsock()あたりで、__linkset_add_dataや__linkset_foreachなどおもしろいことが行われているのだが、それはまたいつか書こう。
ところで、uipcとpcbって何の略だろう?
この辺の略語は、どうやって調べたらよいのやら。
connect(2)を呼ぶと、まずsys_connect()が呼ばれる。sys_connect()はsys/kern/uipc_syscalls.cにある。
if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
return (error);
...
so = (struct socket *)fp->f_data;
...
error = soconnect(so, nam, l);
sys_connect()ではgetsock()でsocketを取得。そのsocketをsoconnect()へ渡している。
soconnect()はsys/kern/uipc_socket.cにある。
error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
(struct mbuf *)0, nam, (struct mbuf *)0, l);
で、プロトコル(so_proto)に応じたusrreq関数を呼んでいる。TCPの場合はtcp_usrreq()が呼ばれる。
tcp_usrreq()はsys/netinet/tcp_usrreq.cにあり、
case PRU_CONNECT:
...
error = in_pcbconnect(inp, nam, l);
と、in_pcbconnect()を呼んでいる。
netinet/in_pcb.cのin_pcbconnect()で、
if (sin->sin_port == 0)
return (EADDRNOTAVAIL);
とEADDRNOTAVAILを返している。
本当はgetsock()あたりで、__linkset_add_dataや__linkset_foreachなどおもしろいことが行われているのだが、それはまたいつか書こう。
ところで、uipcとpcbって何の略だろう?
この辺の略語は、どうやって調べたらよいのやら。
登録:
投稿 (Atom)