printfの挙動 EOFの扱い readとwriteについて stdioの実装にreadvとwritevを使用している シグナルマスクとsetjmp/longjmp 正規表現 exitが複数回呼ばれるときの振る舞い Dynamic linkerにおけるlazy bindingの未サポート dlclose はmuslでは何もしない スレッドセーフなdlerror これはPOSIXを尊重してglibcと異なる挙動になっていたのが、musl 1.1.9からglibcと同じ挙動になったということらしい symbolのバーションについての扱い Threadのスタックサイズ Threadキャンセル時の挙動 localeの扱い (deault localeなど) iconv 古い東アジアのマルチバイトエンコーディングについては出力先として指定することができない ISO-2022-JPへの変換はステートレスとなる 等 浮動小数点についてはC99 Annex Fの範囲をサポートする 浮動小数点の例外についてアンマスクをサポートしない 名前解決 glibcは候補を順にみていくがmuslは同時に問合せを行い最初に返ってきた結果を採用する?
【Makefile】変数加工のtips
$(name:op%os=np%ns)
$(name)の各語に対し、先頭のopと末尾のosを削除して、先頭にnp, 末尾にnsを付加する。
用途としてはこんな感じ。特定ディレクトリ配下のファイルを取得して指定したパスに加えて拡張子をつけるみたいなケース
vars := $(filter-out Makefile, $(shell ls -1)) all: @echo $(vars:%=/tmp/%.txt)
上記に適当なファイルを作成しておくことで実行すると以下のようになる。ローカル -> Linuxの実行パスにファイル名を変えつつ動的に配置するファイルを決定させたいケースみたいなので便利。
make /tmp/dep.yml.txt /tmp/pv.yml.txt /tmp/pvc.yml.txt
【Perl】CによるPerl拡張 XSに入門する
概要
休み明け一発目から古のperlを使った謎モジュールのビルドエラーの確認作業になった。cもmakefileもそれなりに読めるし余裕だろって思ってたらそんなことはなかったのでメモ
XSでハマったというよりはそもそもXSが何なのかをそんなに理解してなかったので理解用に書く
XSとは
XS は Perl と(Perl と一緒に使いたい)C のコード(または C ライブラリ)との 間の拡張インターフェースを作るのに使われるインターフェース記述 ファイルフォーマットです。 XS インターフェースはライブラリと動的または静的にリンクされて、 Perl とリンクすることのできる新しいライブラリを生成します。 XS インターフェース記述はは XS 言語で書かれており、 Perl 拡張インターフェースのコアコンポーネントです。
XSはCをベースに独自のマクロを持った言語。PerlからCコードを呼び出すぐらいにしかわかってなかったけどリファレンス読むと思ったより高機能なのが分かる
XS 言語の特徴
拡張子は(.xs)でファイルの中にはC言語のソースコードとXSUBが含まれます。XSUBはXSで言語で書かれC言語の関数にぱっと見は似ています。正直拡張を見ないとCの独自仕様かな?と思うくらいには似ているので理解するのも難しいです。
#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" MODULE = SomeModule PACKAGE = SomeModule
なのでXSを取得するにCとPerlあたりの知識が必須となっている。
使ってみる
minilという雛形生成ツールを使って最小コードのxsを生成してみた。
ぱっと見はC。SVとかその辺はそのままperlの用語に紐づく形となっている
#ifdef __cplusplus extern "C" { #endif #define PERL_NO_GET_CONTEXT /* we want efficiency */ #include <EXTERN.h> #include <perl.h> #include <XSUB.h> #ifdef __cplusplus } /* extern "C" */ #endif #define NEED_newSVpvn_flags #include "ppport.h" MODULE = Acme::MyModuele PACKAGE = Acme::MyModuele PROTOTYPES: DISABLE void hello() CODE: { ST(0) = newSVpvs_flags("Hello, world!", SVs_TEMP); }
SVの操作
XSからPerlのデータを操作する方法
SV の中身をダンプして出力
sv_dump(sv)
新しい SV をつくりたい。整数値から SV をつくりたい
SV* sv = newSViv(5963);
符号なし整数値から SV をつくりたい
SV* sv = newSVuv(5963);
文字列から SV をつくりたい
SV* sv = newSVpvn("hello", strlen("hello"));
SV から SV をつくりたい
SV* new_sv = newSVsv(sv);
SV の値が真か偽かがしりたい
bool b = SvTRUE(sv);
sprintf したい。
SV* sv = newSVpvf("%d", 3);
参照カウンターをインクリメントしたい
SvREFCNT_inc(sv);
参照カウンターをデクリメントしたい
SvREFCNT_dec(sv);
ppport.hのインターフェース
PerlのC APIを呼び出すことでPerlのデータ構造に対する操作を行う事ができるのはなんとなく上まで書いていて理解はできました。CのAPIはPerlの歴史が経つにつれて変わっていくのが上記のCPANで公開されているモジュールから見て取れます。
モジュールを使うことである程度の変更は吸収してくれるようですが例えばperl5.10で追加された関数を使ったモジュールを5.8のperlでビルドしようとすると失敗するみたいなことは往々にして起き得ます。
仮に存在しない関数を使った場合この辺はビルド時にエラーになるので関数名がわかったら上記のcpanでchangelogを眺めてどこで追加されたのかを確認するのが良さそうです。
参考
【Go】ベンチマーク ツールのtips
- -benchmem
メモリ関連の情報を出力。
- -benchtime t
計測に使う時間をt
で指定する。defaultは1s
- -cpuprofile=*.prof
詳細なCPUプロファイルが取れる go tool pprof
で内容を見る
- -count
テストする回数を指定
- -cpu
実行するcpu数
- -memprofile=*.prof
詳細なMemoryプロファイルが取れる go tool pprof
で内容を見る