June 2006

カーネル読書会で、シーケンスロックのスピンロックをとらない軽量版が(関数名ではseqcount_hogehoge) あるんだけど、preempt_disable()してないから使うべきではない。と発言したら

いやいや、呼び出し側でIRQ disable()してるかもしれないから、一概にそうとは言えない。

と諭されてしまった。
おっしゃるとおり。


ちなみに、以下に seqcountのwrite lock関数を引用しておく。ご参考までに

136 static inline void write_seqcount_begin(seqcount_t *s)
137 {
138 s->sequence++;
139 smp_wmb();
140 }
141
142 static inline void write_seqcount_end(seqcount_t *s)
143 {
144 smp_wmb();
145 s->sequence++;
146 }




で、おっしゃるとおり。で終わっていると寂しいので使っている場所を見てみた。

ソースは例によって lxr.linux.no の 2.6.11 カーネルね。


まず、使っている場所は一箇所のみ。
以下に示すように、inode->i_size いじってる場所。

http://lxr.linux.no/source/include/linux/fs.h#L526
523 static inline void i_size_write(struct inode *inode, loff_t i_size)
524 {
525 #if BITS_PER_LONG==32 && defined(CONFIG_SMP)
526 write_seqcount_begin(&inode->i_size_seqcount);
527 inode->i_size = i_size;
528 write_seqcount_end(&inode->i_size_seqcount);
529 #elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPT)
530 preempt_disable();
531 inode->i_size = i_size;
532 preempt_enable();
533 #else
534 inode->i_size = i_size;
535 #endif
536 }



あ、あららー
やっぱり、preempt_disable()しないとまずそうですよ。
IRQ disableしてないってのもあるが、それより何より、
シングルCPUのときは preempt_disable(); してるってのが、
いかにもわざとそうしてるんじゃないんだよー
という雰囲気をかもし出している。

いや、それ以前に、ここseqcountじゃなく、seqlock使わないとまずい場所に見えるんですが・・・(n'ω'`)


カーネル読書会に来ていなかった人のために補足すると問題点は以下

1.SMP環境においてwrite_seqcount_begin() したあとで、preemptすると、ロック保持期間が滅茶苦茶長くなる
2.seqcount()は書き手が複数いたときの排他をまったくしないので、設計上1人になることを保障しなければならないが、i_size_write()がそんな事をしているようには見えない。かつi_sizeは64bit変数なので、32bitアーキでは1命令では書けない
3.seqcount使うなら読み手もread lock取らないといけないが、そんな事をしてな場所が腐るほどある。

3は問題じゃないかもしれないけどね。i_sizeが絶対32bitで収まるfsだと単純に=演算子で代入しちゃってもうまくいくから。
そこはちゃんと見てない。

なに?
2.6.11なんて見てないでちゃんと最新をおっかけろ?
おっしゃるとおり。ごめんなさい。
ちょっと、手間隙かかるのよね。最新をウォッチし続けるのって(^^ゞ

気になっているので誰かコメントくれると嬉しいっす。




しょせんカスか
ちゃんと見切れていません! ランキング!

このエントリーをはてなブックマークに追加

はてブをウォッチしていてこんな話をみつけた。

http://qootas.org/blog/archives/2006/06/perl_regex_perf.html

来日してる US の TypePad エンジニア Garth と話をしているときにでてきた正規表現の話。

$char =~ m/\p{Han}|\p{Hiragana}|\p{Katakana}/; #NG
$char =~ m/[\p{Han}\p{Hiragana}\p{Katakana}]/; #OK

return if $char =~ m/abc|def|ghi/; #NG
return if ($char =~ m/abc/ or $char =~ m/def/ or $char =~ m/ghi/); #OK

"|"(パイプ)を使った正規表現はめちゃくちゃ遅いから使わないように、ということです。確かにベンチマークを取ると32倍速いです。



あと、こっちで、なんか続きがあるっぽい
http://d.hatena.ne.jp/fbis/20060615/1150333992
うーん|が遅くなるのってNFA特有の話ですよねぇ。
perlって常にNFAなんでしたっけ?

記憶では後方参照とかない単純なやつはDFAに落としてくれるとなっていたのだが、どこと混線したのだろう・・・
GNU grepあたり?





犯人像
おまえは何をいっているんだ? ランキング!

このエントリーをはてなブックマークに追加

いやなブログさんのsetitimer システムコールを使って簡単なプロファイラを作るという記事で解説されているプロファイラー(通称:いやなプロファイラー *1)をIA64で動かしてみた。

*1 おいらが命名


せっかくだからパッチ晒しとく。
しかし、インストラクションポインタが存在しないアーキなんて存在しないのに、機種非依存コードにする方法を思いつかないこのもどかしさ。
嗚呼・・・・

--- itimer_prof.orig    2006-06-13 14:13:21.000000000 +0900
+++ itimer_prof.c 2006-05-18 12:12:26.000000000 +0900
@@ -9,7 +9,12 @@ static FILE *prof_fp;


static void
prof_handler(int signal, siginfo_t *siginfo, void *ucontext)
{
+#ifdef __ia64__
+ struct ucontext *uc = (struct ucontext *)ucontext;
+ unsigned long long int pc = uc->uc_mcontext.sc_ip;
+#else /* assume i386*/
struct ucontext *uc = (struct ucontext *)ucontext;
unsigned long int pc = uc->uc_mcontext.eip;
+#endif


fwrite(&pc, sizeof(pc), 1, prof_fp);





ヴァルキリープロファイル
女神さまをもプロファイル! ランキング!

このエントリーをはてなブックマークに追加

404 Blog Not Found様のTBとcommentの整理という記事を読んで、うむむ、なるほど!
とばかりに、自分のサイドバーのトラックバック欄を改造してみる。


・・・



・・・・・・・・・




なぜだ?
まるで、使いやすくなった気がしない。

ちゃんと自分サイトははじいて、木構造にもしたのだが。
(よく見ると、1つ自サイトのTBをはじきそこなってる。ははは)

とりあえず、今日はもう会社にいく時間なので、明日考えよう。

とりあえず、コード晒しておく。
FC2の共有プラグインをちょっと改造してるだけなので、汚いけど

<div class="tree" id="RT"><ul>
<!--rtrackback--><li>

<!-- ここで title属性に、記事名をいれておく -->
<a href="<%rtrackback_url>" title="<%rtrackback_etitle>"
name="<%rtrackback_year>/<%rtrackback_month>/<%rtrackback_day>/<%rtrackback_hour>" >
<span>(<%rtrackback_month>/<%rtrackback_day>)</span> 
<%rtrackback_blog_name>:<%rtrackback_title></a>
</li><!--/rtrackback-->
</ul></div>

<script type="text/javascript"><!--

// Blog設定の最大トラックバック数は30(最大)にしておいて
// 実際の表示数はこちらの変数を使う
// もっといい方法はないのかな・・・・
max_count=7;

var A=document.getElementById('RT').getElementsByTagName('A');
I="<ul>"; // I: 生成テキスト
L=A.length; // L: A要素数
display_count=0;
for (i=0;i<L;i++){
E=A[i].title;
tburl=A[i].href;
if ( E!="" & tburl.indexOf("mkosaki.blog46.fc2.com")==-1 ){
display_count++;
if( display_count == max_count ){
break;
}
var C=new Array();
c=-1;
I+='<li><p>'+E+'<br />';
for (j=i;j<L;j++){
if (A[j].title==E) { // 以降に同じタイトルがあれば
c++;
C[c]=j
}
}
for (j=0;j<=c;j++){
k=C[j];
A[k].title="";
p=A[k].innerHTML.split(' ');
q=A[k].name;
if (j<c) {
I+=' ├'
} else {
I+=' └'
}
I+='<a href="'+A[k].href+'" title="'+q+'" name="'+q+'">'+p[1]+'</a><br />';
}
I+='</p></li>';
}
}
I+="</ul>";
document.getElementById('RT').innerHTML=I;
--></script>



許してだワン
犬でも反省! ランキング!

このエントリーをはてなブックマークに追加

って読んでいいのでしょうか?
このニュースは

http://www.itmedia.co.jp/news/articles/0606/12/news059.html


ところで、売り上げの40%をAmazonが徴収って高いの、安いの? >そっち方面の人
このエントリーをはてなブックマークに追加



最近、人の作ったお話に入り込めなくなってきていて、実話系の本ばかりヒットしている気がする。
今回もそんな本。

(エヴァの)庵野監督と結婚してダブルアンノになってしまった安野モヨコ*1 の新婚生活エッセイ。
はっきりいって、カントク君(庵野監督の愛称)のコドモっぷりが凄すぎる。もちろん漫画なのである程度の脚色はあるのだろうが庵野ならやりかねん。とか読者に思わせてしまうあたりサスガ・・・

*1 最初からこれを狙っていたペンネームだったら凄い


評価: ☆☆☆☆☆ (オススメっす)
このエントリーをはてなブックマークに追加

最近やったアホな話

Linuxではドライバのメジャー番号が1-4095の範囲で使える。

Linux/include/linux/kdev_t.h

4 #define MINORBITS       20 
5 #define MINORMASK ((1U << MINORBITS) - 1)
6
7 #define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
8 #define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
9 #define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))


ただし、昔は1-255だったので、その範囲の番号を使いたいなら
Documentation/devices.txt を見ながら空いてる番号を探さなければいけない。

・・・・


・・・・・・・・・・・・




そう、思っていた時期が僕にもありました。



register_chrdev()の実装の中核、__register_chrdev_region()の一部をピックアップすると以下のようになっています


29 #define MAX_PROBE_HASH 255 /* random */
30
33 static struct char_device_struct {
34 struct char_device_struct *next;
35 unsigned int major;
36 unsigned int baseminor;
37 int minorct;
38 const char *name;
39 struct file_operations *fops;
40 struct cdev *cdev; /* will die */
41 } *chrdevs[MAX_PROBE_HASH];

(中略)

80 __register_chrdev_region(unsigned int major, unsigned int baseminor,
81 int minorct, const char *name)
82 {
(中略)
94
95 /* temporary */
96 if (major == 0) {
97 for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) {
98 if (chrdevs[i] == NULL)
99 break;
100 }
101
102 if (i == 0) {
103 ret = -EBUSY;
104 goto out;
105 }
106 major = i;
107 ret = major;
108 }


つまりchar deviceのハッシュバケツを255から0に向かって検索、
バケツが空だったらインデックス値(必ず 1-255の範囲になる)をメジャー番号として確保します。

このとき、Documentation/devices.txtの紳士協定を考慮するような処理は一切ない。

つまり静的にメジャー番号を確保したいデバイスは、255以下の番号はたとえ、devices.txtで空いていようが空いていまいが、動的メジャー番号確保デバイスに取られている可能性があるので使ってはいけない。

逆に、動的メジャー番号確保デバイスは、メジャー番号決めうちなレガシーデバイスに、決めうちioctlを叩き込まれる事を覚悟しなければならない

ええ、これでバグを出しましたよorz


てゆーか、仕様、おかしくないか?



ふつーに考えると、動的アロケートはレガシーとバッティングしない256以降を優先して確保すべきだろう。



major
メジャーって難しい! ランキング!

このエントリーをはてなブックマークに追加

カーネル読書会で発表してきましたというエントリで、ファイルをFC2 webにアップロードしてダウンロードしてね。とか書いておいたら見事運営側にファイルを消されてしまった。

いや、外部からのアクセスはだめよん。というのはちゃんと書いてあったのだが、FC2 blogとFC2 webは内部かなー。と都合よく脳内置換処理が走っていた。
ははは・・・

というわけで、無料でおけるファイル置き場を募集中です。
だれか知っている人はぜひぜひ情報くださいませ
このエントリーをはてなブックマークに追加

PGotMoL annex さんの記事から

void _debug_printf(const char *);
#define _num_to_str(num) #num
#define num_to_str(num) _num_to_str(num)
#define debug_printf(msg) \
_debug_printf(msg " at " __FUNC__ ":" num_to_str(__LINE__))

のように、ダミーのマクロを通せばよい。

なぜこうなるのか、プリプロセッサの動作は想像するしかないが、文字列化の識別子の優先度は高いようだ。



とあるけど、gccのプリプロセッサのinfoにズバリ書いてあるで~

Macro Pitfalls: (マクロの落とし穴)
 Separate Expansion of Macro Arguments: の項

事前走査は、引数が文字列化されたり連結されたりする場合には行われない。すなわち、

#define str(s) #s
#define foo 4
str (foo)

は "foo" に展開される。再び、事前走査による意味のある影響は防がれる。

(中略)


もう一つ、事前走査が役に立つ場合がある。事前走査で引数を展開してからそれ文字列化することが、二段階のマクロを使うことで、可能になる。上に出てきた例に新しいマクロ xstr を追加しよう。

#define xstr(s) str(s)
#define str(s) #s
#define foo 4
xstr (foo)




ま、これを読んだところ、プリプロセッサマジックという印象はぬぐえんのじゃがのー




アフリカの民族衣装
理解できない呪術的! ランキング!

このエントリーをはてなブックマークに追加

↑このページのトップヘ