EN JA
KTHREAD(9)
KTHREAD(9) FreeBSD Kernel Developer's Manual KTHREAD(9)

名称

kthread_start, kthread_shutdown, kthread_add, kthread_exit, kthread_resume, kthread_suspend, kthread_suspend_checkカーネルスレッド

書式

#include < sys/kthread.h>

void
kthread_start( const void *udata);

void
kthread_shutdown( void *arg, int howto);

void
kthread_exit( void);

int
kthread_resume( struct thread *td);

int
kthread_suspend( struct thread *td, int timo);

void
kthread_suspend_check( void);

#include < sys/unistd.h>

int
kthread_add( void (*func)(void *), void *arg, struct proc *procp, struct thread **newtdpp, int flags, int pages, const char *fmt, ...);

int
kproc_kthread_add( void (*func)(void *), void *arg, struct proc **procptr, struct thread **tdptr, int flags, int pages, char * procname, const char *fmt, ...);

解説

FreeBSD 8.0 では、古い kthread_*( 9) 関数ファミリは、以前に、誤った名前付けで実際に生成されたカーネルプロセスであったので、 kproc_*( 9) 関数ファミリとなるように名前を変えられました。この新しい kthread_*( 9) 関数ファミリは、 実際の カーネルスレッドを生成するために追加されました。名前を変えられた呼び出しに関する詳しい情報については、 kproc(9) マニュアルページを参照してください。また、 kproc_kthread_add( 9) 関数は、機能性が分割されて、両方のページに現れることに注意してください。

関数 kthread_start() は、 bufdaemon, pagedaemon, vmdaemonsyncer のような“内部の”デーモンを開始するために使用され、 SYSINIT(9) から呼び出されることを目的としています。 udata 引数は、次のように作成されるべきであるカーネルスレッドについて記述する struct kthread_desc への実際のポインタです:

struct kthread_desc { 
 char  *arg0; 
 void  (*func)(void); 
 struct thread **global_threadpp; 
};

構造体のメンバは、次のように kthread_start() によって使用されます:

arg0
スレッドの名前に使用される文字列。この文字列は、新しいスレッドの struct threadtd_name メンバにコピーされます。
func
実行するこのカーネルスレッドのためのメイン関数。
global_threadpp
新たに作成されたスレッドの thread 構造体を指すために更新されるべきである struct thread ポインタへのポインタ。この変数が NULL であるなら、無視されます。スレッドは、 proc0 (PID 0) のサブスレッドになります。

kthread_add() 関数は、カーネルスレッドを作成するために使用されます。新しいスレッドは、カーネルモードだけで実行します。 procp 引数、または、それが NULL であるなら、 proc0 によって指定されたプロセスに追加されるます。 func 引数は、スレッドが実行するべきである関数を指定します。 arg 引数は、それが新しいスレッドによって呼び出されるとき、唯一の引数として func に渡される任意のポインタです。 newtdpp ポインタは、新たに作成されたスレッドを指すために更新される struct thread ポインタを指します。この引数が NULL であるなら、無視されます。 flags 引数は、停止している状態のスレッドを離れるために RFSTOPPED に設定されます。呼び出し側は、スレッドを開始するために sched_add() を呼び出さなければなりません。 pages 引数は、ページの新しいカーネルスレッドのスタックのサイズを指定します。 0 が使用されるなら、デフォルトのカーネルスタックサイズが割り付けられます。引数の残りは、新しいスレッドの名前を構築するために使用され、新しいスレッドの struct threadtd_name メンバに格納される、 printf(9) 形式の引数リストとなります。

kproc_kthread_add() 関数は、kproc が既に存在していないなら、作成されることを除いて、上記の kthread_add() 関数によく似ています。この関数は、 kproc(9) マニュアルページによりよく文書化されています。

kthread_exit() 関数は、カーネルスレッドを終了するために使用されます。それは、主な関数が呼び出し側に戻るよりむしろカーネルスレッドの主な関数によって呼び出されるべきです。

kthread_resume(), kthread_suspend() と kthread_suspend_check() 関数は、カーネルスレッドをサスペンドして、再開 (レジューム) するために使用されます。実行のメインループの間、それ自体がサスペンドすることを可能にしたいカーネルスレッドは、サスペンドを求めているかどうか調べるために kthread_suspend_check() を呼び出すべきです。そうであるなら、再開を伝えられるまで msleep(9) します。一旦、再開を伝えられたなら、カーネルスレッドの実行が継続するのを許して返ります。他の 2 つの関数は、サスペンドか再開要求をカーネルスレッドに通知するために使用されます。 td 引数は、サスペンドか、または再開するカーネルスレッドの struct thread を指します。 kthread_suspend() のために、 timo 引数は、サスペンド要求とそれ自体をサスペンドに応答するカーネルスレッドを待つためのタイムアウトを指定します。

kthread_shutdown() 関数は、システムシャットダウン活動を妨げないようにシステムシャットダウンの間に、自発的にサスペンドする必要があるカーネルスレッドのためのシャットダウンイベントとして登録されるように作られています。カーネルスレッドの実際のサスペンドは、 kthread_suspend() と共に行われます。

戻り値

kthread_add(), kthread_resume() と kthread_suspend() 関数は、成功すれば 0 を返し、失敗すれば 0 以外を返します。

使用例

この例は、 struct kthread_desc の使用と bufdaemon プロセスを走らせるために関数 kthread_start(), kthread_shutdown() と kthread_suspend_check() を示しています。

static struct thread *bufdaemonthread; 
 
static struct kthread_desc buf_kp = { 
 "bufdaemon", 
 buf_daemon, 
 &bufdaemonthread 
}; 
SYSINIT(bufdaemon, SI_SUB_KTHREAD_BUF, SI_ORDER_FIRST, kthread_start, 
    &buf_kp) 
 
static void 
buf_daemon() 
{ 
 ... 
 /* 
  * このプロセスは、シャットダウン sync の前にサスペンドする 
  * 必要があります. 
  */ 
 EVENTHANDLER_REGISTER(shutdown_pre_sync, kthread_shutdown, 
     bufdaemonthread, SHUTDOWN_PRI_LAST); 
 ... 
 for (;;) { 
  kthread_suspend_check(bufdaemonthread); 
  ... 
 } 
}

エラー

kthread_resume() と kthread_suspend() 関数は、次の場合に失敗します:
[ EINVAL]
td 引数は、カーネルスレッドを参照していません。

kthread_add() 関数は、次の場合に失敗します:

[ ENOMEM]
スレッドのスタックのためのメモリを割り付けすることができませんでした。

関連項目

kproc(9), SYSINIT(9), wakeup(9)

歴史

kthread_start() 関数は、完全なプロセスを作成する場合に FreeBSD 2.2 ではじめて登場しました。それは、 FreeBSD 8.0 でスレッドを作成するようにに変換されました。 kthread_shutdown(), kthread_exit(), kthread_resume(), kthread_suspend() と kthread_suspend_check() 関数は、 FreeBSD 4.0 で導入され、 FreeBSD 8.0 でスレッドに変換されました。 kthread_create() 呼び出しは、 FreeBSD 8.0kthread_add() に改名されました。カーネルのプロセスを作成する古い機能は、 kproc_create(9) に改名されました。 FreeBSD 5.0 より前では、 kthread_shutdown(), kthread_resume(), kthread_suspend() と kthread_suspend_check() 関数は、それぞれ shutdown_kproc(), resume_kproc(), shutdown_kproc() と kproc_suspend_loop() と名前が付けられていました。
January 24, 2010 FreeBSD