EN JA
PMCLOG(3)
PMCLOG(3) FreeBSD Library Functions Manual PMCLOG(3)

名称

pmclog_open, pmclog_close, pmclog_read, pmclog_feedhwpmc(4) によって生成されたイベントログデータを解析する

ライブラリ

Performance Counters Library (libpmc, -lpmc)

書式

#include < pmclog.h>

void *
pmclog_open( int fd);

void
pmclog_close( void *cookie);

int
pmclog_read( void *cookie, struct pmclog_ev *ev);

int
pmclog_feed( void *cookie, char *data, int len);

解説

これらの関数は、アプリケーションプログラムが hwpmc(4) によって生成されたイベントストリームからイベントを抽出する方法を提供します。

新しいイベントログパーサは、 pmclog_open() を使用して割り付けられます。引数 fd は、イベントストリームがファイルに存在するなら、読み込みでオープンされたファイル記述子、またはイベントストリームががメモリに存在するなら、定数 PMCLOG_FD_NONE です。この関数は、この API のセットで他の関数に渡されるクッキーを返します。

関数 pmclog_read() は、引数 cookie に関連しているイベントストリームで次の利用可能なイベントを返します。引数 ev は、イベントの解析が成功した結果を含むイベント記述子へのポインタです。

pmclog_read() によって返されたイベント記述子は、次の構造体があります:

struct pmclog_ev { 
       enum pmclog_state pl_state;    /* 'get_event()' の後のパーサ状態 */ 
       off_t             pl_offset;   /* ストリーム中のバイトオフセット */ 
       size_t            pl_count;    /* 今までのレコードカウント */ 
       struct timespec   pl_ts;       /* タイムスタンプのログエントリ */ 
       enum pmclog_type  pl_type;     /* 種別のログエントリ */ 
       union {         /* データのログエントリ */ 
  struct pmclog_ev_closelog    pl_cl; 
  struct pmclog_ev_dropnotify  pl_d; 
  struct pmclog_ev_initialize  pl_i; 
  struct pmclog_ev_map_in      pl_mi; 
  struct pmclog_ev_map_out     pl_mo; 
  struct pmclog_ev_pcsample    pl_s; 
  struct pmclog_ev_pmcallocate pl_a; 
  struct pmclog_ev_pmcattach   pl_t; 
  struct pmclog_ev_pmcdetach   pl_d; 
  struct pmclog_ev_proccsw     pl_c; 
  struct pmclog_ev_procexec    pl_x; 
  struct pmclog_ev_procexit    pl_e; 
  struct pmclog_ev_procfork    pl_f; 
  struct pmclog_ev_sysexit     pl_e; 
  struct pmclog_ev_userdata    pl_u; 
       } pl_u; 
};

パーサの現在の状態は pl_state に記録されます。このフィールドは次の値を取ることができます:

PMCLOG_EOF
(ファイルに基づいているパーサのみ) 設定されたファイル記述子は、ファイルの終り状態となりました。
PMCLOG_ERROR
構文解析の間にエラーが発生しました。
PMCLOG_OK
完全なイベントレコードは *ev から読み込まれました。
PMCLOG_REQUIRE_DATA
完全なイベントレコードを組み立てるために、イベントストリームには不十分なデータがありました。メモリに基づいているパーサについては、関数 pmclog_feed() を使用して、より多くのデータをパーサに送り込むことができます。ファイルに基づいているパーサについては、関数 pmclog_read() は、データが設定されたファイル記述子で利用可能であるときに、再試行されるかもしれません。

イベント構造体の残りは、フィールド pl_statePMCLOG_OK を含んでいる場合にだけ有効です。フィールド pl_offset は、バイトストリームでの現在のレコードのオフセットを含んでいます。フィールド pl_count は、このイベントのシリアル番号を含んでいます。フィールド pl_ts は、イベントが起こったとき、システムタイムでのタイムスタンプを含んでいます。フィールド pl_type は、引数 *ev で返されたイベントの種類を示し、次の一つです:

PMCLOG_TYPE_CLOSELOG
ログファイルのクローズが成功していることを示すマークです。このレコードは、ログファイルの最後のレコードとなります。
PMCLOG_TYPE_DROPNOTIFY
hwpmc(4) が、リソース制限のためにデータを落さなければならないことを示すマークです。
PMCLOG_TYPE_INITIALIZE
初期化レコード。これは、ログファイルの最初のレコードです。
PMCLOG_TYPE_MAP_IN
kldload(2) または mmap(2) システムコールによって実行形式のオブジェクトへのマッピングの導入について記述するレコード。
PMCLOG_TYPE_MAP_OUT
kldunload(2) または munmap(2) システムコールによって実行形式のオブジェクトへのマッピングの削除について記述するレコード。
PMCLOG_TYPE_PCSAMPLE
命令ポインタのサンプルを含むレコード。
PMCLOG_TYPE_PMCALLOCATE
PMC 割り付け操作について記述するレコード。
PMCLOG_TYPE_PMCATTACH
PMC アタッチ操作について記述するレコード。
PMCLOG_TYPE_PMCDETACH
PMC 出タッチ操作について記述するレコード。
PMCLOG_TYPE_PROCCSW
プロセスのコンテキストスイッチの時点で PMC 読み込みについて記述するレコード。
PMCLOG_TYPE_PROCEXEC
ターゲットプロセスによる execve(2) について記述するレコード。
PMCLOG_TYPE_PROCEXIT
_exit(2) の時点でプロセスのための蓄積された PMC 読み込みについて記述するレコード。
PMCLOG_TYPE_PROCFORK
ターゲットプロセスでの fork(2) について記述するレコード。
PMCLOG_TYPE_SYSEXIT
システム全体のサンプリング PMC を所有しているプロセスに送られた、プロセス終了ついて記述するレコード。
PMCLOG_TYPE_USERDATA
ユーザデータを含むレコード。

関数 pmclog_feed() は、メモリに基づいたイベントストリームを解析するために設定されるパーサで使用されます。関数 pmclog_read() が、イベント構造体の引数のフィールド pl_state で返される PMCLOG_REQUIRE_DATA よって、より多くのデータの必要性を示すとき、呼び出されるためのものです。引数 data は、新しいイベントデータを含むメモリバッファの始まりを指します。引数 len は、利用可能なデータバイトの数を示します。メモリ範囲[ data, data + len]は、この次に pmclog_read() がエラーを返すまで、有効なままで残らなければなりません。ファイルデータを解析するために設定されたパーサで pmclog_feed() を使用するエラーです。

関数 pmclog_close() は pmclog_open() への前の呼び出しによって割り付けられた内部の状態を解放します。

戻り値

関数 pmclog_open() は、成功すれば、 NULL でない値を返すか、そうでなければ NULL を返します。

関数 pmclog_read() は、完全なイベントレコードの読み込みが成功した場合には 0 を返し、エラーの場合には-1 を返し、イベントレコードの pl_state フィールドに適切なコードを設定します。

関数 pmclog_feed() は、成功すれば 0 を返し、失敗の場合には-1 を返します。

使用例

ログファイル構文解析 API で使用するテンプレートは、以下の擬似コードで示されます:

void *parser;   /* クッキー */ 
struct pmclog_ev ev;  /* 解析されたイベント */ 
int fd;    /* ファイル記述子 */ 
 
fd = open(filename, O_RDONLY); /* ログファイルをオープン */ 
parser = pmclog_open(fd); /* パーサの初期化 */ 
if (parser == NULL) 
 --メモリ不足エラーを操作--; 
 
/* データを読み込み解析する */ 
while (pmclog_read(parser, &ev) == 0) { 
 assert(ev.pl_state == PMCLOG_OK); 
 /* イベント処理 */ 
 switch (ev.pl_type) { 
 case PMCLOG_TYPE_ALLOCATE: 
  --pmc 割り付けレコードを処理-- 
  break; 
 case PMCLOG_TYPE_PROCCSW: 
  --スレッドコンテキストスイッチレコードを処理-- 
  break; 
 case PMCLOG_TYPE_PCSAMPLE: 
  --PC サンプルを処理-- 
  break; 
 --その他-- 
 } 
} 
 
/* パーサ状態を調査 */ 
switch (ev.pl_state) { 
case PMCLOG_EOF: 
 --正常終了-- 
 break; 
case PMCLOG_ERROR: 
 --ここで errno を見る-- 
 break; 
case PMCLOG_REQUIRE_DATA: 
 --構文解析に利用可能である多くのデータを準備する-- 
 break; 
default: 
 assert(0); 
 /*NOTREACHED*/ 
} 
 
pmclog_close(parser);  /* クリーンアップ */

エラー

pmclog_init_parser() への呼び出しは、 malloc(3) によって返されるエラーのいずれかで失敗するかもしれません。

ファイルに基づいたパーサのための pmclog_read() への呼び出しは、 read(2) によって返されるエラーのいずれかで失敗するかもしれません。

歴史

pmclog API は、現在、開発中です。それは、 FreeBSD 6.0 ではじめて登場しました。
March 26, 2006 FreeBSD