2010年11月4日木曜日

Lions' Commentary (9) - 読書会#1 -

なんと、Lions' Commentary on UNIX 読書会が開かれる、という事で参加してきました。
しばらく独りで読み進めていましたが、まさか読書会に巡り会えるとは!
って、改めて読み返してみると、日記のエントリに1年近いブランクがありますね。
やばいやばい・・・時間が経つのが早過ぎる。

読書会ってのははじめてだったんですが、この会では1章ずつ読み進めます。
まずは時間が与えられて個々に内容を理解。その後、みんなで内容について議論する、と。
初回だったので進め方を決めて、さわりを・・・って感じでしたが、次回からは
月1回のペースで2章ずつ進める事になりました。途中参加もOKだと思うので
興味のある方がいたらぜひ。

1章〜4章は飛ばして実際の内容に入る5章からやりました。
pre K&RなC言語がわけわからんので、やっぱり3章も見とけば良かった・・・
みたいな話もありますが、まぁ必要になったら戻るという感じで。

5章はメモリ管理とpanic用の簡易版printfのところです。
mallocとかprintfとかいう名前だけど、libcの同名関数とは別物なので注意。
内容自体は簡単ですが、癖のある当時の文法が一番の悩みどころでした。

・型について
intとポインタはともに16bit。unsignedという考え方は存在しない。
  unsignedが必要な場合はポインタで代用する!!!
  このためstructのm_sizeの型がchar *になっている。
  ちなみにv7ではm_sizeはsigned shortだったりするけど。。。

・キャストが存在しない
  キャストがないため「*((int *)アドレス直値) = 書き込み値」みたいに書けない。
  そのかわり「->」を使うと型に関係なく構造体だと思ってメンバを探しにいく仕様で、
  構造体の名前空間も単一。これを利用して例えばintのメンバintegを持つ構造体を定義し、
  「アドレス直値->integ」と書く事で「*((int *)アドレス直値)」と等価になる。
  現代人からすると超キモイ仕様。

・大域変数にextern宣言をしない
  これは今でも通用するみたいなので、きちんとC言語の仕様をあたればそういう物かも。
  大域変数はあるソース(.c)に実体を置き、他のソースからはヘッダ(.h)にextern宣言
  された物をincludeして使う、というのが今時の描き方。
[foo.c]
 int global_variable;
 ...

[foo,h]
 extern int global_variable;
 ...

[bar.c]
 #include "foo.h"

 void bar (void) {
  global_variable = 1;
  ...
 }
  なのだが、実はexternは省略しても良い。リンク時に型や初期値の不整合がなければ
  1つにまとめてくれる。実際、coremapとswapmapはsystem.hで宣言されており、
  extern修飾もなければソース側での実体定義も存在しない。

・ldiv/lremはなぜアセンブラ?
  当時のC言語は乗除算は使えなかった? とか効率の良いコードが吐けなかった?
  とか憶測が飛び交ったけど、結局は妥当な理由が見当たらない。
  6th Cでのサポートはoracchaさんが試して通る事を確認しているし、吐かれるコードも
  悪くはない(関数にしなければinlineで展開されるのでprolog/epilogも不要なはず)。
  単純に前の版までアセンブラで書いてあったのでそのまま流用?とも思える。
  あるいはKernel書いてる頃にはコンパイラがサポートしておらず、その後ユーザランドを
  作ってるうちに面倒になってコンパイラサポートが入った、とか。
  v7ではアセンブラは廃止されてCの演算子で書かれてたりするので、この線が濃厚か。
  ちなみに、printnの最後はv6では「putchar(lrem(n, b) + '0');」という全うな書き方だが、
  v7では「putchar("0123456789ABCDEF"[(int)(n%b)]);」という微妙な書き方に。。。
  どう考えても遅いしメモリも食う書き方なので、こう書けるようになったのが嬉しくて
  つい書いてしまったコードに違いない。

・改行後のDEL
  改行がCRとLFにわかれているのと同様、歴史的な配慮?
  consoleがプリンタだった場合、描画位置を左に戻して、紙を送って・・・
  といった時間がかかるので、少し時間稼ぎ。
  プリンタがreadyを返さなければXSTのbusy loopで待つ気もするけど。

・8進数
  DECはPDP1の頃に8進数を使う文化が。。。
  詳細はこの辺とか。

・可変長引数
  stdargみたいな書き方は当然確立されていない。
  もちろん、やってる事はva_startとかva_argの中身と一緒なんだけど、
  実装を隠蔽せずに生でスタックを指すアドレスをずらして使ってる。
  なので、無理矢理ダミーの引数を並べて書いてあるけど、実は意味がない。
  引数を無駄に並べるのはv7で廃止されてるけど、実装はそのまま。

いくつか参考サイトを紹介します。
  1. 2238クラブ または 私は如何にして心配するのを止めてUNIXカーネルを愛するようになったか ... 貴重な日本語情報サイト
  2. Commentary on the Sixth Edition UNIX Operating System ... PDF版Commentaryあり
  3. Dennis Ritchie Home Page ... 6th Edition UNIXのC言語リファレンスマニュアルあり
  4. Operating System Engineering / xv6 ... x86/ANSI版
  5. xv6詳説 ... xv6のソースをひらメソッドで読む
  6. Plan9日記 2010-11-01 ... 読書会参加者のレポート
  7. やる気のないはてだ 2010-10-31 ... 同じく参加者のレポート
  8. PDP1 emulator on flash ... おまけ

近況2010!

だいぶ前に仕事が一段落したので同人を・・・みたいな事を書いたのですが。
やはりどこかにボトルネックがある限り、手が空くって事は許されないのですね。
あまりにも非生産的な毎日になってしまったので、意を決して今月転職しました。
そんなわけで、生活の根っこはだいぶ改善されたような気がします。

転職に至るまで、外の世界にも目を向けようと、前回のblogに書いたイベント参加。
あるいは最近はやりの勉強会なんてのにも顔を出すようになりました。
最近ではカーネル/VM探検隊Lions' Commentary on UNIX読書会なぞに参加して、
結構良い刺激になるとともに、ストレス解消にもなってます。

カーネル/VM探検隊向けにはHaiku OS向けのyurexドライバを書いたりしたので
次回参加時には軽く紹介したいなぁ、などと思ってます。
BeOSの系譜らしく、Pulseで貧乏揺すりの度合いを見える化できます!


Lions'本については昨年から独りで細々と読み進めており、最近になって
元会社の同僚を説き伏せて、内輪で盛り上がりつつあったところでした。
まさか大人数で集まってわいわいできるとは思っていなかったので嬉しい!

あと、ここ数年自宅サーバのマシンやHDDが壊れる壊れる。。。
という事で、だいぶカオスな状態で放置されていたサーバ群。
仮想化や冗長化をすすめ、だいぶ快適さが向上しました。

加えて買ったきりでセットアップもままならなかったmotif-rack xs。
こいつもLogicとCubaseからストレスなく使える環境が整った!
だいぶ遅れて迷惑をかけてしまってるんですが、Doll's Ingramの曲は
この環境を使って作曲作業を再開しています。

rackはYAMAHAが音色定義を配ってないので、motifの設定を流用。
あと、Logic用は面倒な手順が色々と書かれてるんだけど、裏技的な方法として、
エンバイロメントのウィンドウを開き、レイヤーとしてテンプレートファイルを開く、
とかやると便利です。
テンプレートから設定をコピペしたり、作業をテンプレートから開始したり、
とかいう煩わしさ、制約から解放されます。