<br />
<b>Warning</b>:  getimagesize(./cache/logo/6hdd.jpg) [<a href='function.getimagesize'>function.getimagesize</a>]: failed to open stream: No such file or directory in <b>/home/domain2/openhdd.com/components/Bloglounge.Data.RSSOut.php</b> on line <b>83</b><br />
<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
<channel>
<title>OpenHDD  メタブログ データ 復旧 : サーバ에 대한 분류 검색결과</title>
<link>http://www.openhdd.com</link>
<description> メタブログ データ 復旧 PC Parts モバイル HDD 情報</description>
<language>ko</language>
<pubDate>Sun, 20 May 2012 16:43:45 +0900</pubDate>
<generator>Bloglounge 0.3.1.1 flyingbucket</generator>
<image>
<title>OpenHDD  メタブログ データ 復旧</title>
<url>http://www.openhdd.com/cache/logo/6hdd.jpg</url>
<width />
<height />
<description />
</image>
<item>
<title>Fedora 16 で久々に Xen を試してみる</title>
<link>http://luna2-linux.blogspot.com/2011/12/fedora-16-xen.html</link>
<description>KVM の登場で、ほとんど触ることが無くなっていた Xen ですが、Linux 3.0 以降で Dom0 動作可能になっており、Fedora 16 なら簡単に Xen を動かせるので、試してみました。&lt;br/&gt;
&lt;br/&gt;
■準備&lt;br/&gt;
yum install xen を実行して、Xen 関連のパッケージを導入します。grub2 のメニューは、自動で追加されるので、特に何もすることはなく、導入は簡単でした。再起動して、 
&lt;pre class=&quot;console&quot;&gt;
Linux, with Xen 4.1 and Linux 3.1.2-1.fc16.x86_64
&lt;/pre&gt;
このように with Xen 4.1 がついたメニューを選択して起動すれば OK でした。&lt;br/&gt;
&lt;br/&gt;
■実験内容&lt;br/&gt;
ホストには Fedora 16 x86_64 、ゲストには CentOS 6.2 x86_64 を使い、Xen 準仮想化、Xen 完全仮想化、KVM の３つの場合で、パフォーマンスがどの程度違うものかを比較。ハードは、ThinkPad X301 (Core2 Duo U9400 1.40GHz) です。&lt;br/&gt;
個人設備の関係上、ディスク性能が貧弱なため、ベンチマークには&lt;a href=&quot;http://accc.riken.jp/HPC/HimenoBMT/&quot;&gt;姫野ベンチ&lt;/a&gt;を使いました。&lt;br/&gt;
なお、CentOS 6 では、DomU 用カーネルというのは無いので、カーネルの種類を切り替えるようなことはしなくて済みます。CentOS 5 の場合は、準仮想化で動くには xen カーネルを使う必要がありましたし、CentOS 4 では xenU カーネルを使う必要がありました。&lt;br/&gt;
&lt;br/&gt;
■実験結果&lt;br/&gt;&lt;pre&gt;
&lt;font color=&quot;darkblue&quot;&gt;&lt;b&gt;単位MFLOPS
 84.511594  Xen 完全仮想化 ゲスト (CentOS 6.2 x86_64)
 86.336558  Xen 準仮想化 ゲスト   (CentOS 6.2 x86_64)
 96.247089  Xen Dom0   (Fedora16 x86_64、ゲストとは OS 環境が異なります)
106.986019  KVM ゲスト (CentOS 6.2 x86_64)
101.272400  KVM ホスト (Fedora16 x86_64、ゲストとは OS 環境が異なります)&lt;/font&gt;
&lt;/b&gt;&lt;/pre&gt;
姫野ベンチの結果のみですが、KVM のほうがパフォーマンス (CPU, メモリ周り) が良いという結果になりました。&lt;br/&gt;
&lt;br/&gt;
■所感&lt;br/&gt;
ベンチを実行する前の段階で、体感上 Xen のほうがもっさりしていると感じました。普段、ネイティブ環境 (KVM ホスト側) で作業して、たまに仮想マシンを使うという私の利用形態だと、わざわざ性能劣化した Dom0 で通常作業はしたくないですし、Xen のメリットは全く無いという感想を持ちました。また個人的に Xen で気になる点として、Dom0 上で標準の性能ツール (sar 等) を採取しても、Xen ゲストの性能データを得られない点が挙げられます。KVM であれば、ホスト側の sar には、ゲストの値も計上されます。また、KVM ゲストは、KVM ホストからはプロセスに見えるため、top コマンドでも、KVM ゲスト毎の負荷状況を簡単にモニターできます。&lt;br/&gt;
&lt;br/&gt;
■個人的結論&lt;br/&gt;
現時点で、Xen を使うメリットは全くないと感じました。Hyper-V のハイパーバイザー部分は Xen と共有しているそうですし、Oracle VM も Xen ベースだとのこと。それらがいくらチューニングしようとも、KVM よりもレイヤーが厚い分だけ、性能面で不利なのではないかと思われます。&lt;br/&gt;
&lt;br/&gt;
&lt;font color=&quot;darkblue&quot;&gt;2012-02-19追記&lt;/font&gt;&lt;br/&gt;
古い VT（CPUの仮想化支援機能）非対応のPC（P4 3.6G）を再利用しようとして、そんな時には Xen が役立つと再認識しました。Fedora 16 で (KVM無しの) QEMU を試しましたが、実用的に使うには無理がありました。QEMU では、ゲストが起動するのに 30 分かかるのが、Xen であれば許せる時間内（数分）でゲスト起動できました。&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8780226058800981893-2835082686667343576?l=luna2-linux.blogspot.com' alt='' /&gt;&lt;/div&gt;</description>
<category>CentOS</category>
<category> KVM</category>
<category> Linux</category>
<category> Fedora</category>
<author>luna2</author>
<guid>http://luna2-linux.blogspot.com/2011/12/fedora-16-xen.html</guid>
<pubDate>Sat, 24 Dec 2011 23:05:00 +0900</pubDate>
</item>
<item>
<title>ksh で扱える整数の上限</title>
<link>http://luna2-linux.blogspot.com/2011/12/ksh.html</link>
<description>bash と tcsh について、扱える整数の上限を調べましたが、さらに ksh についても調べてみました。
&lt;pre class=&quot;source&quot;&gt;
#!/bin/ksh93

function test_int_limit {
        typeset i=2147483646
        echo -e &quot;INT_MAX-1 = &quot;$i
        let i++
        echo -e &quot;INT_MAX   = &quot;$i
        let i++
        echo -e &quot;INT_MAX+1 = &quot;$i
echo
        i=4294967294
        echo -e &quot;ULONG_MAX-1 = &quot;$i
        let i++
        echo -e &quot;ULONG_MAX   = &quot;$i
        let i++
        echo -e &quot;ULONG_MAX+1 = &quot;$i
echo
        i=999999999999999998
        echo &quot;i = &quot;$i
        let i++
        echo &quot;i+1 = &quot;$i
        let i++
        echo &quot;i+2 = &quot;$i
echo
        i=9223372036854775806
        echo -e &quot;LLONG_MAX-1 = &quot;$i
        let i++
        echo -e &quot;LLONG_MAX   = &quot;$i
        let i++
        echo -e &quot;LLONG_MAX+1 = &quot;$i
echo
}

test_int_limit
&lt;/pre&gt;
ksh について、何点か補足メモ、、、&lt;br/&gt;
&lt;br/&gt;
(1) 関数定義する場合、function キーワードを使用して、関数名の後ろに () はつけません。&lt;br/&gt;
    つけると構文エラーになります。&lt;br/&gt;
(2) ローカル変数を使うには、typeset を指定します。&lt;br/&gt;
    bash にも typeset がありますが、あちらは、Obsolute (廃止) とされています。&lt;br/&gt;
(3) 関数定義は、(1) 以外にも旧来の 関数名() { ... } という記載方法もある。&lt;br/&gt;
    しかし、その場合に typeset によるローカル変数指定が機能しません。&lt;br/&gt;
    なので、ksh の場合は (1) の書き方を使いましょう。&lt;br/&gt;
&lt;br/&gt;
テストスクリプトを実行した結果が、下記です。
&lt;pre class=&quot;console&quot;&gt;
# uname -a                                                                                                                                                                      
Linux my41 2.6.18-274.12.1.el5 #1 SMP Tue Nov 29 13:37:46 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
# ksh93 --version                                                                                                                                                               
  version         sh (AT&amp;T Research) 93t+ 2010-02-02
# ./test_int_limit.ksh93 
INT_MAX-1 = 2147483646
INT_MAX   = 2147483647
INT_MAX+1 = 2147483648

ULONG_MAX-1 = 4294967294
ULONG_MAX   = 4294967295
ULONG_MAX+1 = 4294967296
&lt;font color=&quot;lightblue&quot;&gt;
i = 999999999999999998
i+1 = 999999999999999999
i+2 = 1e+18
&lt;/font&gt;
LLONG_MAX-1 = 9223372036854775806
LLONG_MAX   = 9.22337203685477581e+18
LLONG_MAX+1 = 9.22337203685477581e+18
&lt;/pre&gt;
このように、18桁までは整数、19桁以上は浮動小数点数として扱ってくれるようです。&lt;br/&gt;
そうです。&lt;font color=&quot;blue&quot;&gt;ksh は浮動小数点数を扱えます。&lt;/font&gt;一方、bash では浮動小数点数を扱えません。&lt;br/&gt;
ごく稀に、bash でも浮動小数点数を使いたい場合があり、やむなく gawk を呼び出したりしますが、ksh ならそのようなことをしなくても済むようです。&lt;br/&gt;
なお、ksh の typeset には、-i オプション (整数型指定) がありますが、これを指定すると内部的に  int 扱いになるようで、INT_MAX までしか格納できなくなります。&lt;br/&gt;
&lt;br/&gt;
bash と tcsh の扱える整数の上限については、次の記事参照。&lt;br/&gt;
&lt;a href=&quot;http://luna2-linux.blogspot.com/2010/07/bash.html&quot;&gt;bash で扱える整数の上限&lt;/a&gt;&lt;br/&gt;
&lt;a href=&quot;http://luna2-linux.blogspot.com/2011/12/tcsh.html&quot;&gt;tcsh で扱える整数の上限&lt;/a&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8780226058800981893-1163524711554480535?l=luna2-linux.blogspot.com' alt='' /&gt;&lt;/div&gt;</description>
<category>bash</category>
<category> Linux</category>
<author>luna2</author>
<guid>http://luna2-linux.blogspot.com/2011/12/ksh.html</guid>
<pubDate>Sun, 18 Dec 2011 10:31:00 +0900</pubDate>
</item>
<item>
<title>tcsh で扱える整数の上限</title>
<link>http://luna2-linux.blogspot.com/2011/12/tcsh.html</link>
<description>以前、&lt;a href=&quot;http://luna2-linux.blogspot.com/2010/07/bash.html&quot;&gt;bash で扱える整数の上限&lt;/a&gt; という記事を書きましたが、tcsh についても調べてみました。
&lt;pre class=&quot;source&quot;&gt;
#!/bin/tcsh

@ i=2147483646
echo &quot;INT_MAX-1 = &quot;$i
@ i++
echo &quot;INT_MAX   = &quot;$i
@ i++
echo &quot;INT_MAX+1 = &quot;$i
echo &quot;&quot;
@ i=4294967294
echo &quot;ULONG_MAX-1 = &quot;$i
@ i++
echo &quot;ULONG_MAX   = &quot;$i
@ i++
echo &quot;ULONG_MAX+1 = &quot;$i
echo &quot;&quot;
@ i=9223372036854775806
echo &quot;LLONG_MAX-1 = &quot;$i
@ i++
echo &quot;LLONG_MAX   = &quot;$i
@ i++
echo &quot;LLONG_MAX+1 = &quot;$i
echo &quot;&quot;
&lt;/pre&gt;
実行結果は次の通りです。
&lt;pre class=&quot;console&quot;&gt;
# tcsh --version                                                                                                                                                                
tcsh 6.17.00 (Astron) 2009-07-10 (x86_64-unknown-linux) options wide,nls,dl,al,kan,rh,color,filec
# ./test_int_limit.tcsh                                                                                                                                                         
INT_MAX-1 = 2147483646
INT_MAX   = 2147483647
&lt;font color=&quot;yellow&quot;&gt;INT_MAX+1 = -2147483648&lt;/font&gt;

ULONG_MAX-1 = -2
ULONG_MAX   = -1
ULONG_MAX+1 = 0

LLONG_MAX-1 = -2
LLONG_MAX   = -1
LLONG_MAX+1 = 0
&lt;/pre&gt;
このように、現在の tcsh では INT_MAX までしか扱え無いようです (注：実験は、64bit環境で行ってます) 。もし、仕事で csh を指定されているなど、どうしても csh 系でスクリプトを書くという方は、お気をつけて。&lt;br/&gt;
なお、あちこちで言われているように、csh 系でスクリプトを書くのはやめたほうが良いだろうと思います。最大の難点は、関数定義できない点だと思います。&lt;br/&gt;
&lt;br/&gt;
参考URL:&lt;br/&gt;
&lt;a href=&quot;http://www.kiso.tsukuba.ac.jp/~makimura/text/node239.html&quot;&gt;有害な csh プログラミング&lt;/a&gt;&lt;pre&gt;&lt;font color=&quot;darkred&quot;&gt;&lt;b/&gt;&lt;Q&gt;結論: csh はプログラミングにはまったく向かないツールであり、
そのような目的に使うことは厳しく禁じられるべきである！&lt;br/&gt;
8. まとめ ... そもそもが欠陥品なのです。&lt;/Q&gt;&lt;/b&gt;&lt;/font&gt;&lt;/pre&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8780226058800981893-2501823679372396839?l=luna2-linux.blogspot.com' alt='' /&gt;&lt;/div&gt;</description>
<category>bash</category>
<category> Linux</category>
<author>luna2</author>
<guid>http://luna2-linux.blogspot.com/2011/12/tcsh.html</guid>
<pubDate>Sun, 18 Dec 2011 09:54:00 +0900</pubDate>
</item>
<item>
<title>bash で外部コマンドを使わずに sleep する方法</title>
<link>http://luna2-linux.blogspot.com/2011/12/bash-sleep.html</link>
<description>bash には、いくつかのビルトインコマンド (test や printf 等) があり、それらを用いた場合は、外部コマンドの起動 (fork &amp; exec) を節約できます。一般に、fork &amp; exec は重いので、できればもうちょっとビルトインを増やしてくれるといいのにと思うことがしばしばあります。もちろん肥大化しないため、最小限となっているものとは思うのですが・・・&lt;br/&gt;
&lt;br/&gt;
この記事では、外部コマンドの sleep を呼び出すことなく、bash スクリプトを秒単位でスリープさせる方法を示します。本日、ふと思いつきました。&lt;br/&gt;
&lt;br/&gt;
bash のビルトインの read には、入力待ちをタイムアウトさせるための -t オプションが備わっています。これを使えば sleep の代用にできるはずです。ただし、絶対に入力が発生しない何かを read して、かつ、ブロックさせなくてはいけません。もし、C であれば、pipe() システムコールを呼んで、作成されたパイプを read すれば良いと思いますが、bash の構文で pipe() 相当をやる方法はありません。そこで、mkfifo で名前つきファイル (FIFO) を作成することにしました。&lt;br/&gt;
&lt;br/&gt;
次が実験に使ったスクリプトです。
&lt;pre class=&quot;source&quot;&gt;
#!/bin/bash
#
# Name: test_my_builtin_sleep.bash
#

setup_my_sleep() {
        local    sleep_fifo=/tmp/.sleep_fifo.$$.$RANDOM$RANDOM
        mkfifo  $sleep_fifo
        &lt;font color=&quot;blue&quot;&gt;exec 9&lt;&gt;$sleep_fifo&lt;/font&gt;
        rm -f   $sleep_fifo
}

setup_my_sleep

my_sleep() {
        read -t $1 0&lt;&amp;9
}

time {
for ((i=0;i&lt;20;i++))
do
        sleep 1
        read &lt; /proc/uptime
        echo $REPLY
done
}

echo

time {
for ((i=0;i&lt;20;i++))
do
        my_sleep 1
        read &lt; /proc/uptime
        echo $REPLY
done
}
&lt;/pre&gt;
exec 9&lt;&gt;$sleep_fifo という書き方で、fd 9 を使って FIFO を rw モードでオープンしています。また、直後に FIFO のパスを rm していますが、オープン中なのでスクリプトが終わるまでは、FIFO を利用できます。&lt;br/&gt;
&lt;br/&gt;
次のような実行結果になりました。&lt;br/&gt;
ThinkPad X301 Core2 1.40GHz 上の CentOS 5 x86_64 で実行しています。
&lt;pre class=&quot;console&quot;&gt;
# dmidecode | grep Version                                                                                                                                                      
        Version: 6EET54WW (3.14 )
        Version: ThinkPad X301
        Version: Not Available
        Version: Not Available
        Version: Intel(R) Core(TM)2 Duo CPU     U9400  @ 1.40GHz
        SBDS Version: 03.01
# cat /etc/redhat-release                                                                                                                                                       
CentOS release 5.7 (Final)
# uname -a
Linux my41 2.6.18-274.12.1.el5xen #1 SMP Tue Nov 29 14:18:21 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
# ./test_my_builtin_sleep.bash 
4066.52 3937.55
4067.53 3938.46
4068.54 3939.47
4069.55 3940.45
4070.55 3941.45
4071.56 3942.46
4072.57 3943.47
4073.58 3944.47
4074.59 3945.47
4075.59 3946.48
4076.60 3947.48
4077.61 3948.49
4078.62 3949.49
4079.63 3950.50
4080.63 3951.50
4081.64 3952.49
4082.65 3953.50
4083.66 3954.50
4084.67 3955.51
4085.68 3956.51

real    0m20.161s
user    &lt;font color=&quot;yellow&quot;&gt;0m0.012s&lt;/font&gt;
sys     &lt;font color=&quot;yellow&quot;&gt;0m0.040s&lt;/font&gt;

4086.68 3957.52
4087.68 3958.52
4088.69 3959.53
4089.69 3960.53
4090.69 3961.53
4091.70 3962.53
4092.70 3963.54
4093.71 3964.54
4094.71 3965.55
4095.72 3966.55
4096.72 3967.55
4097.72 3968.56
4098.73 3969.56
4099.73 3970.57
4100.74 3971.57
4101.74 3972.58
4102.74 3973.58
4103.75 3974.58
4104.75 3975.59
4105.76 3976.59

real    0m20.079s
user    &lt;font color=&quot;lightblue&quot;&gt;0m0.000s&lt;/font&gt;
sys     &lt;font color=&quot;lightblue&quot;&gt;0m0.000s&lt;/font&gt;
&lt;/pre&gt;
前半は外部コマンドの sleep を使っており、後半は read -t ＆ FIFO 方式です。なお、時間の経過が読み取り易いように、/proc/uptime を表示しています。&lt;br/&gt;
外部コマンドを用いた場合は、user+sys で 52 ミリ秒のオーバーヘッドが見えているのに対して、read -t &amp; FIFO 方式では、ゼロ (オーバーヘッドが1ミリ秒未満) に見えています。期待通りです。&lt;br/&gt;
&lt;br/&gt;
システムの負荷が高いと、fork &amp; exec が遅延する場合があるので、実験で用いたスクリプトのように小刻みに sleep する処理は、影響を受け易いです。そんな場面に遭遇したら、read -t &amp; FIFO 方式を試してみては。&lt;br/&gt;
それだったら、無理に bash で書かなくてもいいんじゃないのという声もありそうですが。&lt;br/&gt;
そりゃその通りで、適材適所で perl に Ruby に Python に・・・豊かな時代ですね。&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8780226058800981893-2141692817004033948?l=luna2-linux.blogspot.com' alt='' /&gt;&lt;/div&gt;</description>
<category>bash</category>
<category> Linux</category>
<author>luna2</author>
<guid>http://luna2-linux.blogspot.com/2011/12/bash-sleep.html</guid>
<pubDate>Sat, 17 Dec 2011 22:00:00 +0900</pubDate>
</item>
<item>
<title>mawk は確かに速い（２倍くらい）</title>
<link>http://luna2-linux.blogspot.com/2011/11/mawk.html</link>
<description>AWK Users JP の次の記事を読んで、手持ちのよく使う awk スクリプトを mawk で実行してみたところ、確かに速かったです。軒並み２倍速かった。&lt;br/&gt;
&lt;br/&gt;
&lt;a href=&quot;http://gauc.no-ip.org/awk-users-jp/blis.cgi/DoukakuAWK_287&quot;&gt;awk のパフォーマンス&lt;/a&gt;&lt;br/&gt;
&lt;br/&gt;
試しは、Fedora 16 上で行いましたが、常用している CentOS 5 (or RHEL5) でも簡単に利用できるかどうか &lt;a href=&quot;http://download.fedora.redhat.com/pub/epel/&quot;&gt;EPEL&lt;/a&gt; を見てみたら、有難いことに提供されてました。&lt;br/&gt;
というわけで、まず、インストールを。
&lt;pre class=&quot;console&quot;&gt;
[root@centos5 ~]# uname -a
Linux centos5 2.6.18-274.7.1.el5 #1 SMP Thu Oct 20 16:21:01 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux
[root@centos5 ~]# yum install mawk --enablerepo=epel
Loaded plugins: downloadonly, fastestmirror
Loading mirror speeds from cached hostfile
 * base: www.ftp.ne.jp
 * epel: ftp.jaist.ac.jp
 * extras: www.ftp.ne.jp
 * updates: www.ftp.ne.jp
Setting up Install Process
Resolving Dependencies
--&gt; Running transaction check
---&gt; Package mawk.x86_64 0:1.3.4-5.20100625.el5 set to be updated
--&gt; Finished Dependency Resolution

Dependencies Resolved

==========================================================================================
 Package         Arch              Version                          Repository       Size
==========================================================================================
Installing:
 mawk            x86_64            1.3.4-5.20100625.el5             epel            104 k

Transaction Summary
==========================================================================================
Install       1 Package(s)
Upgrade       0 Package(s)

Total download size: 104 k
Is this ok [y/N]: y
Downloading Packages:
mawk-1.3.4-5.20100625.el5.x86_64.rpm                               | 104 kB     00:00     
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing     : mawk                                                               1/1 

Installed:
  mawk.x86_64 0:1.3.4-5.20100625.el5                                                      

Complete!
[root@centos5 ~]# 
&lt;/pre&gt;
&lt;br/&gt;
次のテスト用の awk スクリプトは、a から zzzz までの文字列 (Linux の SCSI ディスク名の sdXX の XX 部分に使われている) を出力するものです。適度に重いかと。。
&lt;pre class=&quot;source&quot;&gt;
#
# Note: This awk script prints
#       a, b, ... z, aa, ab, ... zz, aaa, aab, ... zzz
#
function get_sdstr(n,   r,ret) {
        for (;;) {
                if (n &lt;= 26) {
                        return letter[n]&quot;&quot;ret

                } else {
                        r = n % 26 ; r = r ? r : 26
                        ret = letter[r]&quot;&quot;ret
                        n = (n-r)/26
                }
        }
}

BEGIN {
        for (i=1; i &lt;= 26; i++) {
                letter[i] = substr(&quot;abcdefghijklmnopqrstuvwxyz&quot;,i,1)
        }

        for (i=1; i &lt;= (26+26*26+26*26*26+26*26*26*26); i++) {
                print get_sdstr(i)
        }
        exit(0)
}
&lt;/pre&gt;
これを、gawk と mawk でそれぞれ実行して、/usr/bin/time でパフォーマンス測定した結果が、次の通りです。
&lt;pre class=&quot;console&quot;&gt;
[root@centos5 ~]# md5sum test.awk 
ee228358d1513e48e0495e1e79f3956c  test.awk
[root@centos5 ~]# rpm -q gawk
gawk-3.1.5-14.el5
[root@centos5 ~]# rpm -q mawk
mawk-1.3.4-5.20100625.el5
[root@centos5 ~]# 
[root@centos5 ~]# /usr/bin/time gawk -f ./test.awk | md5sum
3.43user 0.01system 0:0&lt;font color=&quot;yellow&quot;&gt;3.47&lt;/font&gt;elapsed 99%CPU (0avgtext+0avgdata 3824maxresident)k
0inputs+0outputs (0major+279minor)pagefaults 0swaps
a9de67bf77dec1b5285ee27f71ab3564  -
[root@centos5 ~]# 
[root@centos5 ~]# /usr/bin/time mawk -f ./test.awk | md5sum
1.48user 0.00system 0:0&lt;font color=&quot;skyblue&quot;&gt;1.49&lt;/font&gt;elapsed 99%CPU (0avgtext+0avgdata 2976maxresident)k
0inputs+0outputs (0major+220minor)pagefaults 0swaps
a9de67bf77dec1b5285ee27f71ab3564  -
&lt;/pre&gt;
このように、２倍くらい速いです。&lt;br/&gt;
まあ、処理内容によるでしょうけど、わたしが日頃使う手持ちスクリプトは軒並み２倍速かったので、これからは有難く常用させてもらおうと思います。作者さん＆メンテナー様に感謝。&lt;br/&gt;
&lt;br/&gt;
EPEL の使い方については、次の記事を参照ください。&lt;br/&gt;
&lt;a href=&quot;http://luna2-linux.blogspot.com/2011/07/centos-6-ntfs.html&quot;&gt;CentOS 6 で ntfs をマウントする&lt;/a&gt;&lt;br/&gt;
なお、CentOS 6 (or RHEL6) 用の EPEL チャネルにも mawk ありました。&lt;br/&gt;
&lt;br/&gt;
gawk で性能足りないということがあったら、最後の切り札に使える場合があるかも。ただし、GNU 拡張等、互換性に注意する必要がある。&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8780226058800981893-3247353068250727687?l=luna2-linux.blogspot.com' alt='' /&gt;&lt;/div&gt;</description>
<category>gawk</category>
<category> CentOS</category>
<category> Linux</category>
<category> Fedora</category>
<author>luna2</author>
<guid>http://luna2-linux.blogspot.com/2011/11/mawk.html</guid>
<pubDate>Sun, 27 Nov 2011 23:34:00 +0900</pubDate>
</item>
<item>
<title>Ruby からシステムコールを直接呼び出す方法</title>
<link>http://luna2-linux.blogspot.com/2011/11/ruby.html</link>
<description>Ruby からシステムコールを直接呼び出す方法です。自分用のメモ。&lt;br/&gt;
&lt;br/&gt;
perl には syscall() が用意されており、使ったことがありましたので、Ruby にもあるかな？とライブラリリファレンスを参照してみると、案の定ありました。&lt;br/&gt;
clock_gettime(CLOCK_MONOTONIC) を呼び出すサンプルです。
&lt;pre class=&quot;source&quot;&gt;
#!/usr/bin/env ruby

NR_clock_gettime = 228  # defined in asm-x86_64/unistd.h
CLOCK_MONOTONIC = 1     # CLOCK_MONOTONIC defined in linux/time.h
ts = ' ' * 16
&lt;font color=&quot;blue&quot;&gt;syscall(NR_clock_gettime, CLOCK_MONOTONIC, ts)&lt;/font&gt;
(tv_sec, tv_nsec) = ts.unpack(&quot;l!l!&quot;)
printf &quot;%d.%09d\n&quot;, tv_sec, tv_nsec

&lt;/pre&gt;
次が実行結果です。
&lt;pre class=&quot;console&quot;&gt;
# ./monotonic.rb ; cat /proc/uptime 
134772.112499324
134772.11 134476.00
&lt;/pre&gt;
なお、一般に、システムコール番号はアーキテクチャ毎に異なります。上記の 228 は、x86_64 の場合です。&lt;br/&gt;
&lt;br/&gt;
&lt;a href=&quot;http://luna2-linux.blogspot.com/2011/11/blog-post.html&quot;&gt;経過時間の計測方法&lt;/a&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8780226058800981893-3568357885181576?l=luna2-linux.blogspot.com' alt='' /&gt;&lt;/div&gt;</description>
<category>Ruby</category>
<category> Linux</category>
<author>luna2</author>
<guid>http://luna2-linux.blogspot.com/2011/11/ruby.html</guid>
<pubDate>Sun, 13 Nov 2011 22:46:00 +0900</pubDate>
</item>
<item>
<title>ビルトインを自作して、bash で処理時間をミリ秒単位で計測</title>
<link>http://luna2-linux.blogspot.com/2011/11/bash.html</link>
<description>先日、&lt;a href=&quot;http://luna2-linux.blogspot.com/2011/10/bash-10.html&quot;&gt;bash で処理時間（経過時間）を 10 ミリ秒の粒度で計測する方法&lt;/a&gt;を書きました。おそらく、bash 自体やプロセス生成のオーバーヘッドを考えると、実用上はそれで十分と思います。&lt;br/&gt;
この記事では、いささかオーバースペック（と言うか諸々のオーバーヘッドを加味すると無意味かも? ）ですが、bash のビルトイン（builtin）作成方法に興味があり、練習として、ミリ秒より細かく計測するためのインターフェースを作成してみました。&lt;br/&gt;
&lt;br/&gt;
以下、CentOS 5.7 x86_64 上、root で作業しています。&lt;br/&gt;
&lt;br/&gt;
まずは、bash のソース RPM (.src.rpm) を入手して、展開します。&lt;br/&gt;
http://vault.centos.org/5.7/os/SRPMS/&lt;br/&gt;
この時点で最新の bash-3.2-32.el5.src.rpm を使いました（作業環境と同じバージョン）。
&lt;pre class=&quot;console&quot;&gt;
# rpm -ivh bash-3.2-32.el5.src.rpm
# rpmbuild -bc /usr/src/redhat/SPEC/bash.spec
&lt;/pre&gt;
上の操作で、/usr/src/redhat/BUILD/bash-3.2/ の下にソースが展開されます。&lt;br/&gt;
ここで、bash ビルトインのコンパイル環境を整えるため、-bp ではなくて、-bc とします。&lt;br/&gt;
-bp のあとに、手動で configure という流れで作業すると、作成したビルトインの enable 時にリンクエラーになってしまいます（具体的には sh_xrealloc で引っかかりました）。&lt;br/&gt;
&lt;br/&gt;
次に、ソースツリーの下の example/loadables の下へ作業ディレクトリを移動して、ひとまずサンプルをビルドして、使ってみます。
&lt;pre class=&quot;console&quot;&gt;
# cd /usr/src/redhat/BUILD/bash-3.2/examples/loadables/
# make -k
&lt;font color=&quot;yellow&quot;&gt;※ビルド過程は省略します。わたしの環境では、多少エラーが出てました。&lt;/font&gt;
# enable -f ./strftime strftime  ※もしリンクエラーになると、bash が落ちます
# enable | grep strftime         ※落ちなければロードされたはずですが、確認です
enable strftime
# strftime &quot;%F %T&quot;               ※試しに strftime を実行
2011-11-06 15:11:13
&lt;/pre&gt;
&lt;br/&gt;
ここまでで、ビルトインを自作する環境が整います。あとは、サンプルを参考にしながら monotonic というビルトインを自作してみました。strftime.c を下敷きにしています。
&lt;pre class=&quot;source&quot;&gt;
     1  /* monotonic - loadable builtin interface to clock_gettime(CLOCK_MONOTONIC) */
     2  
     3  /* Copyright (C) 2011-2011
     4     luna2 at http://luna2-linux.blogspot.com/
     5     If you contact luna2, email to blue3waters at gmail.com.
     6  
     7     This file is subject to the GNU General Public License.
     8     It comes with NO WARRANTY.
     9   */
    10  
    11  /* See Makefile for compilation details. */
    12  
    13  #include &lt;config.h&gt;
    14  
    15  #if defined (HAVE_UNISTD_H)
    16  #  include &lt;unistd.h&gt;
    17  #endif
    18  
    19  #include &quot;bashtypes.h&quot;
    20  #include &quot;posixtime.h&quot;
    21  
    22  #include &lt;stdio.h&gt;
    23  
    24  #include &quot;builtins.h&quot;
    25  #include &quot;shell.h&quot;
    26  #include &quot;common.h&quot;
    27  #include &quot;bashgetopt.h&quot;
    28  
    29  #include &lt;time.h&gt;       /* clock_gettime */
    30  
    31  int
    32  monotonic_builtin (list)
    33    WORD_LIST *list ;
    34  {
    35    char  *tbuf = NULL ;
    36    size_t tbsize ;
    37    char  *tv_sec = NULL ;
    38    char  *tv_nsec = NULL ;
    39    struct timespec t ;
    40  
    41    if (list == 0) {
    42      builtin_usage() ;
    43      return EX_USAGE ;
    44    }
    45  
    46    tv_sec = list-&gt;word-&gt;word ;
    47    if (tv_sec == 0 || *tv_sec == 0) {
    48      builtin_usage() ;
    49      return EX_USAGE ;
    50    }
    51  
    52    list = list-&gt;next ;
    53  
    54    if (list &amp;&amp; list-&gt;word-&gt;word) {
    55      tv_nsec = list-&gt;word-&gt;word ;
    56    } else {
    57      builtin_usage() ;
    58      return EX_USAGE ;
    59    }
    60  
    61    &lt;font color=&quot;blue&quot;&gt;clock_gettime(CLOCK_MONOTONIC, &amp;t) ;&lt;/font&gt;
    62  
    63    tbsize = 32 ;         /* enough to store ULONG_MAX */
    64    tbuf = xmalloc(tbsize) ;
    65    snprintf(tbuf, tbsize, &quot;%lu&quot;, t.tv_sec) ;
    66    bind_variable(tv_sec, tbuf, 0) ;
    67    free(tbuf) ; tbuf = NULL ;    /* erase immediately */
    68  
    69    tbsize = 32 ;
    70    tbuf = xmalloc(tbsize) ;
    71    snprintf(tbuf, tbsize, &quot;%lu&quot;, t.tv_nsec) ;
    72    bind_variable(tv_nsec, tbuf, 0) ;
    73    free(tbuf) ; tbuf = NULL ;
    74  
    75    return EXECUTION_SUCCESS ;
    76  }
    77  
    78  /* An array of strings forming the `long' documentation for a builtin xxx,
    79     which is printed by `help xxx'.  It must end with a NULL. */
    80  char *monotonic_doc[] = {
    81          &quot;The interface to clock_gettime(CLOCK_MONOTONIC).&quot;,
    82          &quot;Store the results in shell variable TV_SEC and TV_NSEC&quot;,
    83          (char *)NULL
    84  } ;
    85  
    86  /* The standard structure describing a builtin command.  bash keeps an array
    87     of these structures.  The flags must include BUILTIN_ENABLED so the
    88     builtin can be used. */
    89  struct builtin monotonic_struct = {
    90          &quot;monotonic&quot;,            /* builtin name */
    91          monotonic_builtin,      /* function implementing the builtin */
    92          BUILTIN_ENABLED,        /* initial flags for builtin */
    93          monotonic_doc,          /* array of long documentation strings. */
    94          &quot;monotonic TV_SEC TV_NSEC&quot;,     /* usage synopsis; becomes short_doc */
    95          0                       /* reserved for internal use */
    96  } ;
&lt;/pre&gt;
これをビルドするため、Makefile を書き換えます。差分は、次の通りです。
&lt;pre class=&quot;console&quot;&gt;
# diff -u Makefile.org Makefile
--- Makefile.org        2011-11-06 12:35:25.000000000 +0900
+++ Makefile    2011-11-06 14:00:09.000000000 +0900
@@ -69,7 +69,7 @@
 SHOBJ_CFLAGS = -fPIC
 SHOBJ_LD = ${CC}
 SHOBJ_LDFLAGS = -shared -Wl,-soname,$@
-SHOBJ_XLDFLAGS = 
&lt;font color=&quot;yellow&quot;&gt;+SHOBJ_XLDFLAGS = -lrt&lt;/font&gt;
 SHOBJ_LIBS = 
 SHOBJ_STATUS = supported
 
@@ -83,7 +83,7 @@
 
 ALLPROG = print truefalse sleep pushd finfo logname basename dirname \
          tty pathchk tee head mkdir rmdir printenv id whoami \
-         uname sync push ln unlink cut realpath getconf strftime
+         uname sync push ln unlink cut realpath getconf strftime monotonic
 OTHERPROG = necho hello cat
 
 all:   $(SHOBJ_STATUS)
@@ -186,6 +186,9 @@
 strftime:      strftime.o
        $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ strftime.o $(SHOBJ_LIBS)
 
+monotonic:     monotonic.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ monotonic.o $(SHOBJ_LIBS)
+
 # pushd is a special case.  We use the same source that the builtin version
 # uses, with special compilation options.
 #
@@ -236,3 +239,4 @@
 mkdir.o: mkdir.c
 realpath.o: realpath.c
 strftime.o: strftime.c
+monotonic.o: monotonic.c
&lt;/pre&gt;
特に、librt のリンクが必要なので、SHOBJ_XLDFLAGS に -lrt を設定しています。&lt;br/&gt;
&lt;br/&gt;
もう一度 make -k を実行すれば、monotonic が出来上がります。&lt;br/&gt;
&lt;pre class=&quot;console&quot;&gt;
# make -k
# ls -l monotonic*
-rwxr-xr-x 1 root root 11463 Nov  6 15:29 monotonic
-rw-r--r-- 1 root root  2379 Nov  6 15:29 monotonic.c
-rw-r--r-- 1 root root  9992 Nov  6 15:29 monotonic.o
&lt;/pre&gt;
&lt;br/&gt;
試しに動かしてみた結果です。
&lt;pre class=&quot;console&quot;&gt;
# enable -f ./monotonic monotonic
# enable | grep monotonic
enable monotonic
# help monotonic
monotonic: monotonic TV_SEC TV_NSEC
    The interface to clock_gettime(CLOCK_MONOTONIC).
    Store the results in shell variable TV_SEC and TV_NSEC
# monotonic TV_SEC TV_NSEC
# echo $TV_SEC $TV_NSEC
12115 474565954
# cat /proc/uptime ; monotonic TV_SEC TV_NSEC ; echo $TV_SEC $TV_NSEC
12148.86 11976.46
12148 861371954
&lt;/pre&gt;
どうやら、うまく動きました。&lt;br/&gt;
monotonic は、指定されたシェル変数（上では TV_SEC および TV_NSEC ですが、他の名前でも可）に、clock_gettime(CLOCK_MONOTONIC) で得られた値を設定します。&lt;br/&gt;
&lt;br/&gt;
経過時間を計測する場合、得られた値の差を求めれば良いので、実際にやってみます。
&lt;pre class=&quot;source&quot;&gt;
#!/bin/bash
#
# Name: elaps_ns.bash
#

enable -f ./monotonic monotonic

set_START() {
        monotonic START START_NSEC
}

get_ELAPS() {
        monotonic END END_NSEC
        if [ $END_NSEC -ge $START_NSEC ] ; then
                let ELAPS=END-START
                let ELAPS_NS=END_NSEC-START_NSEC
        else
                let ELAPS=END-START-1
                let ELAPS_NS=1000000000+END_NSEC-START_NSEC
        fi
}

echo SECONDS=$SECONDS   #bash's builtin
time {
        set_START
}
echo START=$START NSEC=$START_NSEC

echo -e &quot;\n### sleep (2500 x 1000) [us]  using usleep&quot;
time {
        usleep 2500000
}

time {
        get_ELAPS
}
echo END=$END NSEC=$END_NSEC
printf &quot;ELAPS=START-END=$ELAPS.%09d\n&quot; $ELAPS_NS
echo
echo SECONDS=$SECONDS   #bash's builtin
&lt;/pre&gt;
&lt;pre class=&quot;console&quot;&gt;
# ./elaps_ns.bash 
SECONDS=0

real    0m0.000s
user    0m0.000s
sys     0m0.000s
START=14665 NSEC=852954954

### sleep (2500 x 1000) [us]  using usleep

real    0m&lt;font color=&quot;yellow&quot;&gt;2.503&lt;/font&gt;s
user    0m0.000s
sys     0m0.000s

real    0m0.000s
user    0m0.000s
sys     0m0.000s
END=14668 NSEC=356643954
ELAPS=START-END=&lt;font color=&quot;yellow&quot;&gt;2.503&lt;/font&gt;689000

SECONDS=2
&lt;/pre&gt;
bash 組み込みの time で計った経過時間 2.503 と一致することが確認できます。&lt;br/&gt;
&lt;br/&gt;
利用したシステムコール clock_gettime(CLOCK_MONOTONIC) については、次の記事を参照してください。&lt;br/&gt;
&lt;br/&gt;
&lt;a href=&quot;http://luna2-linux.blogspot.com/2011/11/blog-post.html&quot;&gt;経過時間の計測方法&lt;/a&gt;&lt;br/&gt;
&lt;br/&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8780226058800981893-1312408247883706817?l=luna2-linux.blogspot.com' alt='' /&gt;&lt;/div&gt;</description>
<category>CentOS</category>
<category> bash</category>
<category> Linux</category>
<author>luna2</author>
<guid>http://luna2-linux.blogspot.com/2011/11/bash.html</guid>
<pubDate>Sun, 06 Nov 2011 14:37:00 +0900</pubDate>
</item>
<item>
<title>経過時間の計測方法</title>
<link>http://luna2-linux.blogspot.com/2011/11/blog-post.html</link>
<description>最近、スクリプト言語の恩恵により、C で書く機会というのは滅多にないのですが、ふと経過時間測定のための bash 用 builtin を書きたいと思い、その基礎として、現在の Linux で利用できるインタフェースについて調べました。&lt;br/&gt;
&lt;br/&gt;
わたしの過去の C プログラミング経験 (某UNIX,10年くらい前) では、経過時間の計測には gettimeofday() を使っていました。たぶんそれしか無かった (?) ので。&lt;br/&gt;
しかし、その場合、システム時間が遡ってしまう可能性 (システム管理者が日時設定する時など) を考慮する必要があります。&lt;br/&gt;
&lt;small&gt;&lt;font color=&quot;darkblue&quot;&gt;2011-11-06追記、省みると、その当時,その UNIX でも times() はあったでしょうから、わたしが無知だったということですね。&lt;a href=&quot;http://www.jpcert.or.jp/sc-rules/c-int30-c.html&quot;&gt;wrap への考慮&lt;/a&gt;は必要としても。&lt;/font&gt;&lt;/small&gt;&lt;br/&gt;
&lt;br/&gt;
調べてみると、clock_gettime(CLOCK_MONOTONIC,) を使えば良さそうだと知りました。&lt;br/&gt;
このシステムコールを使えば、システム起動からの経過時間を高精度で得られるようです。&lt;br/&gt;
つまり、(カーネルソースまで調べてないですが、おそらくは) /proc/uptime の左側数字の情報源を高精度で得られます。&lt;br/&gt;
これなら、システム時刻が遡るタイミングであっても、経過時間を高精度で計測できます。&lt;br/&gt;
よく、times() システムコールの戻り値を、経過時間の計測に使ってバグっている (wrap のタイミングで) のを見かけますが、こちらを使えば、そんなバグも作らずに済みそうです。(Solaris やら HP-UX も対応しようとして、共通に使えるものを探した結果そうなるのでしょうけど … ) &lt;br/&gt;
&lt;br/&gt;
以下が、サンプルプログラムです。コンパイル時には、librt をリンクするため、リンクオプション -lrt を付加する必要があります。
&lt;pre class=&quot;source&quot;&gt;
/*
    gcc -o monotonic monotonic.c -lrt
*/
#include &lt;time.h&gt;
#include &lt;stdio.h&gt;

main()
{
        struct timespec tp ;
        &lt;font color=&quot;blue&quot;&gt;clock_gettime(CLOCK_MONOTONIC, &amp;tp) ;&lt;/font&gt;
        printf(&quot;%llu %llu\n&quot;, tp.tv_sec, tp.tv_nsec) ;
}
&lt;/pre&gt;
実行結果は次の通りです。
&lt;pre class=&quot;console&quot;&gt;
# cat /etc/redhat-release 
CentOS release 5.7 (Final)
# uname -a
Linux xxx 2.6.18-274.3.1.el5 #1 SMP Tue Sep 6 20:13:52 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux
# gcc -o monotonic monotonic.c -lrt
# ./monotonic ; cat /proc/uptime 
&lt;font color=&quot;yellow&quot;&gt;10714 102582089&lt;/font&gt;
&lt;font color=&quot;yellow&quot;&gt;10714.10&lt;/font&gt; 10559.35
&lt;/pre&gt;
このように、/proc/uptime の値が高精度で得られている様子が見えます。&lt;br/&gt;
&lt;br/&gt;
&lt;font color=&quot;darkblue&quot;&gt;2011-11-06追記&lt;/font&gt;&lt;br/&gt;
実際に、clock_gettime(CLOCK_MONOTONIC) を呼び出す bash ビルトインを自作してみました。次の記事を参照ください。&lt;br/&gt;
&lt;br/&gt;
&lt;a href=&quot;http://luna2-linux.blogspot.com/2011/11/bash.html&quot;&gt;ビルトインを自作して、bash で処理時間をミリ秒単位で計測&lt;/a&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;font color=&quot;darkblue&quot;&gt;2011-11-12追記&lt;/font&gt;&lt;br/&gt;
ソースから、/proc/uptime と clock_gettime(CLOCK_MONOTONIC) の情報源が同じであることを確かめました。参照したのは、kernel-2.6.18-274.el5 です。&lt;br/&gt;
まず、/proc/uptime は次のようになっています。
&lt;pre class=&quot;source&quot;&gt;
     97 static int uptime_read_proc(char *page, char **start, off_t off,
     98                                  int count, int *eof, void *data)
     99 {
    100         struct timespec uptime;
    101         struct timespec idle;
    102         int len;
    103         cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
    104 
&lt;font color=&quot;blue&quot;&gt;*   105         do_posix_clock_monotonic_gettime(&amp;uptime);&lt;/font&gt;
    106         cputime_to_timespec(idletime, &amp;idle);
    107         len = sprintf(page,&quot;%lu.%02lu %lu.%02lu\n&quot;,
    108                         (unsigned long) uptime.tv_sec,
    109                         (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
    110                         (unsigned long) idle.tv_sec,
    111                         (idle.tv_nsec / (NSEC_PER_SEC / 100)));
    112 
    113         return proc_calc_metrics(page, start, off, count, eof, len);
    114 }
&quot;fs/proc/proc_misc.c&quot;
&lt;/pre&gt;
105行目の do_posix_clock_monotonic_gettime() は、もう名前からして、clock_gettime(CLOCK_MONOTONIC) に対応していそうですが、その通りです。
&lt;pre class=&quot;source&quot;&gt;
    114 #define do_posix_clock_monotonic_gettime(ts) &lt;font color=&quot;blue&quot;&gt;ktime_get_ts&lt;/font&gt;(ts)
&quot;include/linux/time.h&quot;
&lt;/pre&gt;
&lt;pre class=&quot;source&quot;&gt;
    157 /*
    158  * Call the k_clock hook function if non-null, or the default function.
    159  */
*   160 #define &lt;font color=&quot;blue&quot;&gt;CLOCK_DISPATCH&lt;/font&gt;(clock, call, arglist) \
    161         ((clock) &lt; 0 ? posix_cpu_##call arglist : \
    162          (posix_clocks[clock].call != NULL \
    163           ? (*posix_clocks[clock].call) arglist : common_##call arglist))
...
    218 /*
    219  * Get monotonic time for posix timers
    220  */
    221 static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp)
    222 {
*   223         &lt;font color=&quot;blue&quot;&gt;ktime_get_ts&lt;/font&gt;(tp);
    224         return 0;
    225 }
    226 
    227 /*
    228  * Initialize everything, well, just everything in Posix clocks/timers ;)
    229  */
    230 static __init int init_posix_timers(void)
    231 {
    232         struct k_clock clock_realtime = {
    233                 .clock_getres = hrtimer_get_res,
    234         };
    235         struct k_clock clock_monotonic = {
    236                 .clock_getres = hrtimer_get_res,
*   237                 &lt;font color=&quot;blue&quot;&gt;.clock_get = posix_ktime_get_ts,&lt;/font&gt;
    238                 .clock_set = do_posix_clock_nosettime,
    239         };
    240 
    241         register_posix_clock(CLOCK_REALTIME, &amp;clock_realtime);
*   242         register_posix_clock(&lt;font color=&quot;blue&quot;&gt;CLOCK_MONOTONIC, &amp;clock_monotonic&lt;/font&gt;);
    243 
    244         posix_timers_cache = kmem_cache_create(&quot;posix_timers_cache&quot;,
    245                                         sizeof (struct k_itimer), 0, 0, NULL, NULL);
    246         idr_init(&amp;posix_timers_id);
    247         return 0;
    248 }
...
    920 asmlinkage long
    921 sys_clock_gettime(const clockid_t which_clock, struct timespec __user *tp)
    922 {
    923         struct timespec kernel_tp;
    924         int error;
    925 
    926         if (invalid_clockid(which_clock))
    927                 return -EINVAL;
*   928         error = &lt;font color=&quot;blue&quot;&gt;CLOCK_DISPATCH&lt;/font&gt;(which_clock, clock_get,
    929                                (which_clock, &amp;kernel_tp));
    930         if (!error &amp;&amp; copy_to_user(tp, &amp;kernel_tp, sizeof (kernel_tp)))
    931                 error = -EFAULT;
    932 
    933         return error;
    934 
    935 }
&quot;kernel/posix-timers.c&quot;
&lt;/pre&gt;
モノトニック時刻の実装詳細は、ktime_get_ts() の先にありますが、この記事では情報源の確認までにします。&lt;tt&gt;jiffies_64&lt;/tt&gt; に帰着するのかと思ってましたが、そうでは無いようでした。興味のある方は、先を追ってみては。&lt;br/&gt;
以上から、10ミリ秒精度で十分であれば、モノトニック時刻の取得は、/proc/uptime の読み出しで代用できるということが確かめられました。各種スクリプト言語から、簡単に利用できて便利と思います。&lt;br/&gt;
なお、主要スクリプト言語について、clock_gettime() を呼び出すインターフェースがあるか調べてみました。以下。&lt;br/&gt;
&lt;br/&gt;
&lt;b&gt;perl&lt;/b&gt;&lt;br/&gt;
&lt;a href=&quot;http://perldoc.perl.org/Time/HiRes.html&quot;&gt;http://perldoc.perl.org/Time/HiRes.html&lt;/a&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;b&gt;Ruby&lt;/b&gt;&lt;br/&gt;
見つけられませんでした。&lt;font color=&quot;darkblue&quot;&gt;&lt;small&gt;2011-11-13追記、Ruby にも perl と同様な syscall() が用意されていますので、&lt;a href=&quot;http://luna2-linux.blogspot.com/2011/11/ruby.html&quot;&gt;強引に呼び出す&lt;/a&gt;ことはできました。&lt;/small&gt;&lt;/font&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;b&gt;Python&lt;/b&gt;&lt;br/&gt;
&lt;a href=&quot;http://stackoverflow.com/questions/1205722/how-do-i-get-monotonic-time-durations-in-python&quot;&gt;http://stackoverflow.com/questions/1205722/how-do-i-get-monotonic-time-durations-in-python&lt;/a&gt;&lt;br/&gt;
同様にして、ほとんど何でも C ライブラリを呼び出せそうです。すごいな Python は。&lt;br/&gt;
perl でも、システムコールであれば、syscall() を使って無理すれば呼べますが、こんなにキレイにはできません。&lt;font color=&quot;darkblue&quot;&gt;&lt;small&gt;2011-11-13追記、実際動かしてみると、CentOS 5 の python 2.4 では動かず、CentOS 6 の python 2.6 なら動きました。CentOS 5 では ctypes が足りませんでした。&lt;/small&gt;&lt;/font&gt;&lt;br/&gt;
Ruby については、システムコール直呼び出しはやったことないので不明です。今度、調べてみよう。&lt;br/&gt;
&lt;br/&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8780226058800981893-1119587132916202554?l=luna2-linux.blogspot.com' alt='' /&gt;&lt;/div&gt;</description>
<category>CentOS</category>
<category> Ruby</category>
<category> Linux</category>
<category> Fedora</category>
<category> perl</category>
<category> Python</category>
<author>luna2</author>
<guid>http://luna2-linux.blogspot.com/2011/11/blog-post.html</guid>
<pubDate>Sat, 05 Nov 2011 23:44:00 +0900</pubDate>
</item>
<item>
<title>VirtualHost</title>
<link>http://www.yumidon.com/?p=2613</link>
<description>名前ベースのVirtualHostで作ってみました。 北陸APRS/VoIPユーザーズクラブ（JH9YWO） 固定IPは1個でOKってことね(^^)v httpd.confの設定は、Includeすれば、あっさり振り分け [...]</description>
<category>サーバ</category>
<author>Yumidon</author>
<guid>http://www.yumidon.com/?p=2613</guid>
<pubDate>Thu, 03 Nov 2011 23:24:33 +0900</pubDate>
</item>
<item>
<title>bash で処理時間を 10 ミリ秒単位で計測する方法</title>
<link>http://luna2-linux.blogspot.com/2011/10/bash-10.html</link>
<description>bash スクリプト中の特定部分の処理時間（経過時間）を、１秒より細かい粒度で計測したいため、その方法を考えてみました。&lt;br/&gt;
&lt;br/&gt;
まず、秒単位で良ければ、次の場所にあれこれと書いてある方法で良いかと思います。&lt;br/&gt;
&lt;br/&gt;
&lt;a href=&quot;http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=22451&amp;forum=10&quot;&gt;http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=22451&amp;forum=10&lt;/a&gt;&lt;br/&gt;
&lt;/br&gt;
ただ、bash には組み込み変数 SECONDS (シェルが起動されてからの経過秒数) があるので、次のように書いたほうがオーバーヘッドが少ないはずです。
&lt;pre class=&quot;source&quot;&gt;
#!/bin/bash
#
# Name: elaps.bash
#

sleep 1

START=&lt;font color=&quot;blue&quot;&gt;$SECONDS  #bash's builtin&lt;/font&gt;
echo START=$START

echo -e &quot;\n### sleep 2&quot;
sleep 2
echo

END=$SECONDS
let ELAPS=$END-$START
echo END=$END
echo ELAPS=START-END=$ELAPS
&lt;/pre&gt;
&lt;pre class=&quot;console&quot;&gt;
# ./elaps.bash 
START=1

### sleep 2

END=3
ELAPS=START-END=2
&lt;/pre&gt;
&lt;br/&gt;
さて、わたしが取り組んでいる内容に対して、秒では粗すぎます。ミリ秒程度まで取得したいのですが、標準では bash から直接 gettimeofday() を呼ぶことができません。&lt;a href=&quot;http://cfajohnson.com/shell/articles/dynamically-loadable/&quot;&gt;builtin を作れば不可能ではありません&lt;/a&gt;が、ターゲットがそこまで自由に出来る環境ではないので、別の方法を考えました。&lt;br/&gt;
&lt;br/&gt;
目をつけたのは、/proc/uptime です。このファイルから、システム起動からの経過時間を 10 ミリ秒の粒度で読み取ることができます。man proc 参照。
&lt;pre class=&quot;console&quot;&gt;
# cat /proc/uptime 
&lt;font color=&quot;yellow&quot;&gt;4542.13&lt;/font&gt; 4528.56
# uptime
 11:42am  up  1:15,  2 users,  load average: 0.13, 0.07, 0.02
&lt;/pre&gt;
bash の組み込みコマンド read を利用すれば、オーバーヘッド少なく 10 ミリ秒の粒度で経過時間を計測できるはずです。次が、テストスクリプトです。
&lt;pre class=&quot;source&quot;&gt;
#!/bin/bash
#
# Name: elaps_ms.bash
#

set_START() {
        local dummy
        &lt;font color=&quot;blue&quot;&gt;read START dummy &lt; /proc/uptime&lt;/font&gt;
}

get_ELAPS() {
        local dummy
        &lt;font color=&quot;blue&quot;&gt;read END dummy &lt; /proc/uptime&lt;/font&gt;
        let ELAPS=${END/./}0-${START/./}0
}

echo SECONDS=$SECONDS   #bash's builtin
time {
        set_START
}
echo START=$START

echo -e &quot;\n### sleep (50 x 10 x 1000) [us]  using usleep&quot;
time {
        usleep 500000
}

time {
        get_ELAPS
}
echo END=$END
echo ELAPS=START-END=$ELAPS
echo
echo SECONDS=$SECONDS   #bash's builtin
&lt;/pre&gt;
&lt;pre class=&quot;console&quot;&gt;
# ./elaps_ms.bash 
SECONDS=0

real    0m0.001s
user    0m0.000s
sys     0m0.000s
START=5579.40

### sleep (50 x 10 x 1000) [us]  using usleep

real    0m0.&lt;font color=&quot;lightblue&quot;&gt;520&lt;/font&gt;s
user    0m0.000s
sys     0m0.010s

real    0m0.001s
user    0m0.000s
sys     0m0.000s
END=5579.92
ELAPS=START-END=&lt;font color=&quot;lightblue&quot;&gt;520&lt;/font&gt;

SECONDS=&lt;font color=&quot;red&quot;&gt;0&lt;/font&gt;
&lt;/pre&gt;
このように、500 ミリ秒の usleep 実行の経過時間を 52 x 10 ミリ秒 = 520 ミリ秒と計測することができました。bash 組み込みの time コマンドの計測結果とも一致しています。一方、SECONDS による計測では、0 秒となってしまっています。&lt;br/&gt;
&lt;br/&gt;
さてここで、少しだけ気になる点があります、bash で扱える整数の範囲です。上述のテストスクリプトでは、/proc/uptime から読み取った小数（小数点以下 2 桁）を、単位ミリ秒の整数に変換しています。１日をミリ秒で表すと 24 x 60 x 60 x 1000 = 86400000 となりますが、
&lt;pre class=&quot;console&quot;&gt;
# getconf INT_MAX
2147483647
# bc -l
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
2147483647 / (24 * 60 * 60 * 1000)
24.85513480324074074074
&lt;/pre&gt;
なので、システム起動から 25 日経過した時に大丈夫かな？と不安になりませんか？&lt;br/&gt;
しかし、過去に調べたとおり、最近は 32bit 環境の bash でも、64bit 幅までの整数を扱えるので、大丈夫なはずです。次の記事を参照してください。&lt;br/&gt;
&lt;br/&gt;
&lt;a href=&quot;http://luna2-linux.blogspot.com/2010/07/bash.html&quot;&gt;bash で扱える整数の上限&lt;/a&gt;&lt;br/&gt;
&lt;br/&gt;
&lt;font color=&quot;darkblue&quot;&gt;2011-11-06追記&lt;/font&gt;&lt;br/&gt;
試しに bash のビルトインを自作して、もっと細かい粒度で経過時間を測定してみました。&lt;br/&gt;
&lt;br/&gt;
&lt;a href=&quot;http://luna2-linux.blogspot.com/2011/11/bash.html&quot;&gt;ビルトインを自作して、bash で処理時間をミリ秒単位で計測&lt;/a&gt;&lt;br/&gt;
&lt;br/&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8780226058800981893-5282477001702243524?l=luna2-linux.blogspot.com' alt='' /&gt;&lt;/div&gt;</description>
<category>bash</category>
<category> Linux</category>
<author>luna2</author>
<guid>http://luna2-linux.blogspot.com/2011/10/bash-10.html</guid>
<pubDate>Sun, 30 Oct 2011 11:02:00 +0900</pubDate>
</item>
</channel>
</rss>

