DATA型のbufのメモリを確保し,初期化し,ごにゃごにゃし,解放するという流れを作りたいのですが…
なんかかたまってしまう…(@_@)
#define MAXNUM 10
typedef struct
{
int now_pid;
u64 now_pmc0;
u64 now_tsc;
} DATA;
static DATA *buf;
…
buf = (DATA *)vmalloc(sizeof(DATA) * MAXNUM);
memset(buf, 0, sizeof(DATA) * MAXNUM);
…
vfree(buf);
きっと何かこのへんがおかしいんだろう….
WHERE?!?!
早く抜け出したい(>_<;)
1/7***
ちなみに
memset(buf, 0, sizeof(DATA) * MAXNUM);
の直前に
printk("buf add is 0x%08x\n",(ulong)buf);
をいれると動くっていう…(@_@)
1/8***
vmalloc ではなく kmalloc を用いれば printk を挟まなくてもうまく動きました..
vmalloc 領域の変なとこをさわっていたのかな?原因不明です..
が,とりあえず vmalloc 使うのはこわいんでやめておきます.
2009年10月19日月曜日
kmalloc()/kfree()
カーネル内でメモリを確保/解放するための関数
●使い方
#include <slab.h>
void* kmalloc( size_t size, int flags );
void kfree( void* ptr );
sizeには確保したいバイト数,flagsには以下のどちらかを指定.
GFP_KERNEL:即座にメモリ領域を用意できない場合、メモリ管理機能がスワップアウト 等によって領域を確保するまでスリープする可能性がある
GFP_ATOMIC:スリープせずにメモリ領域を確保しようとする。 必要な領域が確保できない場合は失敗する。 割り込みハンドラやタスクレット、タイムアウトハンドラ等の プロセスコンテキストと無関係に実行される箇所ではこれを使う
●例
u8 *buffer;
buffer = kmalloc(1000, GFP_ATOMIC);
if (!buffer)
return -ENOMEM;
kfree(buffer);
/*u8とは符号なし1バイト整数型(0~255)を表す基本型.
<linux/types.h>をincludeして利用する*/
●参照ページ:
カーネルモジュールを作る
●使い方
#include <slab.h>
void* kmalloc( size_t size, int flags );
void kfree( void* ptr );
sizeには確保したいバイト数,flagsには以下のどちらかを指定.
GFP_KERNEL:即座にメモリ領域を用意できない場合、メモリ管理機能がスワップアウト 等によって領域を確保するまでスリープする可能性がある
GFP_ATOMIC:スリープせずにメモリ領域を確保しようとする。 必要な領域が確保できない場合は失敗する。 割り込みハンドラやタスクレット、タイムアウトハンドラ等の プロセスコンテキストと無関係に実行される箇所ではこれを使う
●例
u8 *buffer;
buffer = kmalloc(1000, GFP_ATOMIC);
if (!buffer)
return -ENOMEM;
kfree(buffer);
/*u8とは符号なし1バイト整数型(0~255)を表す基本型.
<linux/types.h>をincludeして利用する*/
●参照ページ:
カーネルモジュールを作る
2009年9月30日水曜日
RDMSR / WRMSR in C
MSR(Model Specific Register)を読み書きするための命令
どちらも実行できるのは特権モード(ring 0)のみ
これらを C の中で使うには gcc インラインアセンブラを用いればOK
#ちなみにこのへんの記述は perfctr では /usr/include/asm-x86/msr.h にありますね
●インラインアセンブラ表記法
asm volatile ("アセンブラテンプレート"
: "出力オペランド"
: "入力オペランド"
: "アセンブラの実行で変更されてしまうもの");
出力オペランドは "=a" (出力先変数),
入力オペランドは "a" (入力) のように表記する.
ここで,各レジスタは以下のように表記する.
"a" eax
"b" ebx
"c" ecx
"d" edx
"A" edx:eax(上位bitにedx,下位bitにeax)
"g" gccが適当なレジスタに割り当てる
●RDMSR
ecx レジスタに MSR のアドレスを指定すると,edx:eax レジスタに MSR の内容を読み込む(上位 32bit が edx ,下位 32bit が eax に入る)
e.g.
asm volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr_addr));
asm volatile("rdmsr" : "=A"(val) : "c"(msr_addr));
●WRMSR
ecx レジスタに指定した MSR のアドレスに,edx:eax レジスタの内容を書き込む(〃)
e.g.
asm volatile("wrmsr" : : "c"(msr_addr), "=a"(low), "=d"(high) : "memory");
asm volatile("wrmsr" : : "c"(msr_addr), "=A"(val) : "memory");
参照ページ:
ほげほげまん: gccインラインアセンブラ
ほげほげまん: RDMSR / WRMSR
ほげほげまんめっちゃ分かりやすい.お世話になってますw
どちらも実行できるのは特権モード(ring 0)のみ
これらを C の中で使うには gcc インラインアセンブラを用いればOK
#ちなみにこのへんの記述は perfctr では /usr/include/asm-x86/msr.h にありますね
●インラインアセンブラ表記法
asm volatile ("アセンブラテンプレート"
: "出力オペランド"
: "入力オペランド"
: "アセンブラの実行で変更されてしまうもの");
出力オペランドは "=a" (出力先変数),
入力オペランドは "a" (入力) のように表記する.
ここで,各レジスタは以下のように表記する.
"a" eax
"b" ebx
"c" ecx
"d" edx
"A" edx:eax(上位bitにedx,下位bitにeax)
"g" gccが適当なレジスタに割り当てる
●RDMSR
ecx レジスタに MSR のアドレスを指定すると,edx:eax レジスタに MSR の内容を読み込む(上位 32bit が edx ,下位 32bit が eax に入る)
e.g.
asm volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr_addr));
asm volatile("rdmsr" : "=A"(val) : "c"(msr_addr));
●WRMSR
ecx レジスタに指定した MSR のアドレスに,edx:eax レジスタの内容を書き込む(〃)
e.g.
asm volatile("wrmsr" : : "c"(msr_addr), "=a"(low), "=d"(high) : "memory");
asm volatile("wrmsr" : : "c"(msr_addr), "=A"(val) : "memory");
参照ページ:
ほげほげまん: gccインラインアセンブラ
ほげほげまん: RDMSR / WRMSR
ほげほげまんめっちゃ分かりやすい.お世話になってますw
2008年12月25日木曜日
プログラムの実行時間の取得
そんなに精度が必要ない場合(秒単位で良い場合)
シェルスクリプト内で,
START=`date +%s`
・・・処理
END=`date +%s`
SS=`expr ${END} - ${START}`
とすれば秒単位での値が入ります.
参考ページ:
シェルスクリプトの処理時間
精度が必要な場合は,
gettimeofdayを使用
使い方は以下のページ参照.
マイクロ秒単位での取得が可能です.
参考ページ:
Manpage of GETOFDAY
C言語:実行時間測定の方法
シェルスクリプト内で,
START=`date +%s`
・・・処理
END=`date +%s`
SS=`expr ${END} - ${START}`
とすれば秒単位での値が入ります.
参考ページ:
シェルスクリプトの処理時間
精度が必要な場合は,
gettimeofdayを使用
使い方は以下のページ参照.
マイクロ秒単位での取得が可能です.
参考ページ:
Manpage of GETOFDAY
C言語:実行時間測定の方法
2008年12月10日水曜日
strcatには要注意
strcat(str1,str2)
によって文字列str1とstr2を連結することが可能です.
…が.
これは,str1にstr2をつないでいるので,str1の大きさを十分にとっておかないと,他の領域まで侵入してくちゃくちゃにしてしまうことがあります.
要注意.
参考ページ:
Manpage of STRCAT
によって文字列str1とstr2を連結することが可能です.
…が.
これは,str1にstr2をつないでいるので,str1の大きさを十分にとっておかないと,他の領域まで侵入してくちゃくちゃにしてしまうことがあります.
要注意.
参考ページ:
Manpage of STRCAT
登録:
投稿 (Atom)