私はx86_64のCでユーザーレベルのスレッドライブラリを開発しようとしています。 私はmachine_switch
という関数を持っています。この関数は、新しいスレッドと現在のスレッドのスタックポインタを引数として取ります。この関数は、現在のレジスタ値をバックアップし、新しいスタックポインタから新しい値を復元することによってスレッドを切り替えるものとします。これは私が試みたものです。セグメンテーションフォールトを与えるあるスレッドから別のスレッドに切り替える
.text
.global machine_switch
machine_switch:
# address of the new sp is arg1
# address of the current sp is arg2
# need to store all required registered for old tcb
# restore all required registred from the new tcb
# then when you return, you should get to the new thread
pushq %rbx
pushq %rbp
pushq %r12
pushq %r13
pushq %r14
pushq %r15
movq %rdi, %rsp
popq %r15
popq %r14
popq %r13
popq %r12
popq %rbp
popq %rbx
ret
これはスレッドを格納するために使用しているデータ構造です。
struct tcb {
void *sp; /* Address of stack pointer.
* Keep this as first element would ease switch.S
* You can do something else as well.
*/
int id;
int state; /* 1 - ready state
* 2 - running state
* 3 - blocked state
*/
};
私はtcb
のリストを持っています。 machine_switch
の引数として、を新しく入れて、sp
を渡しています。
しかし、この関数はスタックポインタを変更する際にセグメンテーションフォールトを与えます。 (movq %rdi, %rsp
に)。私は関数の引数をチェックしたが、正しい。何か不足していますか?
新しいスタックポインタはどうやって取得できますか?多分あなたは良い価値を使っていないでしょう。 –
[mcve]を作成してください。 – fuz
@FUZxxl私が知りたいのは、私が概念的に見逃したことです。あるスレッドから別のスレッドに切り替えるときに、より多くのことがあるかどうか。完全なコードは約600行なので、私はそれを投稿しませんでした。 – pahan