Macのシステムコール
Mac OS XでPOSIX以外のシステムコールについての情報が中々無かったので、ここに文書化しておく。http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/ このページといくつかのオープソースのソースコードを参考にした。
Load Average を取得
Load averageはhost_load_info構造体のaverun[]というメンバーに格納される。avenrunには5,15,60秒間でのload averageが格納されている。
#include <mach/host_info.h> #define CPU_STATE_USER 0 #define CPU_STATE_SYSTEM 1 #define CPU_STATE_IDLE 2 struct host_load_info { integer_t avenrun[3]; integer_t mach_factor[3]; }; typedef struct host_load_info* host_load_info_t;
この構造体を用いて有効な値を取得する時には次のhost_info関数を使う
#include <mach/host_info.h> kern_return_t host_info (host_t host, host_flavor_t flavor, host_info_t host_info, mach_msg_type_number_t host_info_count);
hostは情報を得たいhostをさしてるhost_t構造体。flavorは取得する情報の種類を表す。Load averageを取得するときはHOST_LOAD_INFOと指定。
正常に動作したときはhost_infoに値が格納される。尚、この値はLOAD_SCALEという大きさでスケールされている。host_info_countは入力時にはhost_infoの確保しているメモリの大きさ、正常に動作したときは返り値としてのhost_infoの大きさが格納されている。
また、プログラムを実行するマシンに対応したhost_t構造体を得るときは次の関数を使う。
#include <mach/host_info.h> host_name_port_t mach_host_self( void );
以下はサンプルコード。
/* load.c 60秒間で平均を取ったload averageを標準出力に表示する。 */ #include <mach/host_info.h> /* LOAD_SCALE が定義されている */ #include <mach/processor_info.h> #include <stdio.h> int main(int argc, char *argv[]) { struct host_load_info hl; mach_msg_type_number_t count = HOST_LOAD_INFO_COUNT; kern_return_t error = host_statistics(mach_host_self(),HOST_LOAD_INFO,(host_info_t)&hl,&count); double res = (double)(hl.avenrun[2])/(double)(LOAD_SCALE); printf("%lf\n",res); return 0; }
総メモリ量を取得
次のhost_basic_info構造体を用いる。
#include <mach/host_info.h> struct host_basic_info { integer_t max_cpus; integer_t avail_cpus; vm_size_t memory_size; cpu_type_t cpu_type; cpu_subtype_t cpu_subtype; };
前エントリのhost_info関数をflavorをHOST_BASIC_INFOにして実行すると、memory_sizeに総メモリ量が格納される。
/* 総メモリ量を標準出力に表示 */ #include <mach/host_info.h> #include <stdio.h> int main(int argc, char *argv[]) { struct host_basic_info host; mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&host, &count); printf("%d\n",host.memory_size); return 0; }
空きメモリ量の取得
空きメモリ量を取得する際にはvm_statistics構造体を用いる。
#include <mach/vm_statistics.h> struct vm_statistics { integer_t free_count; integer_t active_count; integer_t inactive_count; integer_t wire_count; integer_t zero_fill_count; integer_t reactivations; integer_t pageins; integer_t pageouts; integer_t faults; integer_t cow_faults; integer_t lookups; integer_t hits; }; typedef struct vm_statistics* vm_statistics_t;
この構造体のfree_countに空きメモリのページ数が格納される。尚、mach/vm_statistics.hはmach/host_info.hを読み込むと自動的に読み込まれる。
有効な値を取得する為には次のhost_statistics関数を用いる。
#include <mach/host_info.h> kern_return_t host_statistics (host_priv_t host_priv, host_flavor_t flavor, host_info_t host_info, mach_msg_type_number_t host_info_count);
host_privは統計情報を取りたいhostを示す。プログラムを実行するマシンの情報を得たいときはmach_host_self()関数を用いる。flavorは取得したい情報を示す。この場合はHOST_VM_INFOを指定する。正常に動作したときはhost_info
に値が格納される。host_info_countは入力時にはhost_infoの確保しているメモリの大きさ、正常に動作したときは返り値としてのhost_infoの大きさが格納されている。
以下はサンプルコード。
/* 空きメモリ量を標準出力に表示する */ #include <mach/host_info.h> #include <mach/mach_init.h> #include <stdio.h> int main(int argc, char *argv[]) { struct vm_statistics vm_info; mach_msg_type_number_t count = HOST_VM_INFO_COUNT; host_statistics(mach_host_self(),HOST_VM_INFO,(host_info_t)&vm_info,&count); printf("%d\n",vm_info.free_count*vm_page_size); return 0; }