「だいじょうぶ、問題ない、ほら簡単、楽勝だろう」 という意味らしい
例文:
>
>> -__ending_string(name, src)
ftrace で __ending_string() という新しいタイプを追加したくてだな。やっぱり固定長配列しかないのは不便なのだよ。トレースデータは先頭にサイズが入っているんだから、最後のメンバだけは可変長にしてもサイズは逆算できるはずで・・・
とかいう議論をしている。
> > can't we simply do __string(name, src) and output something like:
> >
> > struct {
> > u16 size;
> > char str[0];
> > } name;
> >
> > That would get rid of this __ending_ wart.
__ending なしの __string() にできないの? こんな風に
> Hmm, I don't understand.
> Such a thing doesn't seem to work. Once we fill the string it would
> override the fields that
> follow it if it's not at the end.
うむむ、よく分からん。
それは動かんように見えるぞ。その構造体をラストメンバ以外で使ったら後続メンバをオーバライドしちゃうじゃん
Just grow the thing to fit whatever string length -- rather common
pattern:
struct foo {
int length;
char data[0];
};
struct foo *bar = kmalloc(sizeof(struct foo) + data_size);
いやいや、kmallocのサイズを変えるだけじゃん
and bob's your uncle.
楽勝だろ?
とかとか。
このあと、トレースでkmallocは使えねーんだよバーヤバーヤ。とか議論があった後以下の仕様になった。
__field(int, foo);
__string(bar);
__field(int, foo2);
__string(bar2);
__field(int, foo3);
こんな感じで適当にメンバを宣言していく
struct plop {
int foo;
char *bar;
int foo2;
char *bar2;
int foo3;
char data[0];
}
これが、こんな構造体に変換される。でbarとかba2はdata配列のどこかのインデックスをポイントしている。
で、呼び出し方はこう
size = sizeof(struct plop);
size += strlen(bar) + 1;
size += strlen(bar2) + 1;
event = ring_buffer_lock_reserve(size);
offset = sizeof(struct plop);
my_plop.bar = (char *)offset;
offset += strlen(bar) + 1;
my_plop.bar2 = (char *)offset;
memcpy(&event, &my_plop, sizeof(struct plop));
memcpy(&event + my_plop.bar, bar, strlen(bar)+1);
memcpy(&event + my_plop.bar2, bar2, strlen(bar2)+1);
ring_buffer_unlock();
コメント