kthreadで補完を実装するカーネルモジュールを書き込もうとしています。
私がコーディングしようとしているロジックは次foo()
のとおりbar()
です。親はkthreadを作成します。foo()
呼び出しwait_for_completion()
て、スレッドbar()
が終了するのを待ちます。bar()
本体を実行してから、complete()
直前に呼び出しますreturn()
。親foo()
は残りのコードを最後まで続行します。
コードの抜粋は次のとおりです。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/completion.h>
#include <linux/kthread.h>
#include <net/tcp.h>
//A couple of standard descriptions
MODULE_LICENSE("GPL");
//Struct used to pass kthread args
typedef struct {
int side; //Specify motor side
int direction; //Specify motor rotation direction
struct completion wait_for_motor; //completion struct
} kthread_arg;
//kthread struct declaration
static struct task_struct *left_motor;
static int motor_rotate(void* data) {
//Cast and dereference argument structure
kthread_arg in = *(kthread_arg*)data;
int i = in.side;
printk(KERN_NOTICE "Module: motor side=%d\n",i);
printk(KERN_NOTICE "Module: Completing kthread...\n");
//Signal completion
complete(&(in.wait_for_motor));
printk(KERN_NOTICE "Module: Kthread Completed.\n");
return 0;
}
//Init function
static int main_init(void)
{
/* Body of code */
//Initialize argument structures;
static kthread_arg kta_left_motor;
//Set motor side
kta_left_motor.side = 0;
//Initialize completion
init_completion(&kta_left_motor.wait_for_motor);
//Create and run kthread
left_motor = kthread_run(&motor_rotate, (void*)&kta_left_motor, "motor_rotate_0");
printk(KERN_NOTICE "Module: Wait_for_completion...\n");
//Put function to sleep until kthread signals completion
wait_for_completion(&(kta_left_motor.wait_for_motor));
printk(KERN_NOTICE "Module: Completion done.\n");
/* More function calls and code */
return 0;
}
//Exit function
static void leave_exit(void)
{
printk(KERN_INFO "Exit module.\n");
}
module_init(main_init);
module_exit(leave_exit);
ここでkern.log
出力は:
Module: Wait_for_completion...
Module: motor side=0
Module: Completing kthread...
Module Kthread Completed.
親関数がウェイクアップされることはなく、行に到達しないことに注意してくださいprintk(KERN_NOTICE "Module: Completion done.\n");
。このコードを実行すると、モジュールがハングします。
完了ドキュメントを上から下まで約100回読みましたが、を使用してcomplete_all()
、done
(常に0を出力する)の値を確認し、を使用completion_done()
しtry_wait_for_completion()
て成功しませんでした。
上で説明した目標を達成するためのより良い方法があるかどうかはわかりません。
私は補完の実装を削除した場合、完全に私は親関数があることを見つけるfoo()
常に完了まで実行される前に、すべてのkthreadsが稼働し始める私が必要とするためであるのに対し、foo()
のみ実行するようにした後 、すべてのkthreadsの実行が行われます。
Ubuntu
uname -r: 4.10.0-42-generic
motor_rotate()
以下に示すように変更します。
kthread_arg *in = (kthread_arg *) data;
int i = in->side;
complete(&(in->wait_for_motor));
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加