2013-10-21 12 views
8

私は昨年、私はユーザコンテキスト(ヘッダucontext.hで定義)を使ってプロジェクトのスレッドスケジューラ(各スレッドがプロセスをシミュレートしたもの)を実装しました。私は講義に参加していて、ユーザーのコンテキストについて話します。去年このプロジェクトを行ったにもかかわらず、getcontextシステムコールが実際に実際に何をしているのか本当に分かりません。getcontextシステムコール(ucontext.h)は本当に何をしますか?

getcontextのマニュアルページでは、「ucpが指している構造体を現在アクティブなコンテキストに初期化しています」と記載されています。また、引数がsetcontextの場合、「ucp引数がgetcontext()で作成された場合、プログラムの実行はgetcontext()の対応する呼び出しが戻ったかのように続きます」さて、私はそれを理解しています。

ここで私は混乱しています。一般的に、私はコンテキストスイッチを実行するために、それを学んだ方法については、一つはそのように設定/ ucontext_t構造体とスワップを初期化します:

ucontext_t ucp; 
ucontext_t oucp; 
getcontext(&ucp); 

// Initialize the stack_t struct in the ucontext_t struct 
ucp.uc_stack.ss_sp = malloc(STACK_SIZE); 
ucp.uc_stack.ss_size = STACK_SIZE; 
ucp.uc_stack.ss_flags = 0; 

ucp.uc_link = /* some other context, or just NULL */; 

// Don't block any signals in this context 
sigemptyset(&ucp.uc_sigmask); 
// Assume that fn is a function that takes 0 arguments and returns void 
makecontext(&ucp, fn, 0); 

// Perform the context switch. Function 'fn' will be active now 
swapcontext(&oucp, &ucp); 
// alternatively: setcontext(&ucp); 

私は小さなプログラムでgetcontextを省略すると、興味深い何も起こりません。ユーザーコンテクストを介してより多くのコンテキストを切り替える多少のプログラムでは、getcontextを追加することで解決されるセグメンテーションフォルトが発生します。

getcontextとは正確に何ですか?なぜucontext_t構造体を割り当て、uc_stackuc_sigmaskフィールドを初期化して初期化し、getcontextを除いてmakecontextを呼び出しても構わないのですか? getcontextが実行する必要がある初期化がありますか?makecontextは実行されませんか?

答えて

4

私は、x86/linuxアーキテクチャ上のucontextのGNU libc実装を見ました。したがって、次のことが成り立たないさまざまな実装があるかもしれません。 MAKECONTEXTに渡されたUCPパラメータがのgetcontext呼び出しによって初期化されなければならない

GNU libc manualは、と述べています。

あなたはglibcを/ sysdeps/UNIX/Linuxの/ x86の/ SYS/ucontext.hにmcontext_tを見ればにgetcontextに初期化された浮動小数点状態(fpregset_t fpregs)(へのポインタがあります)、再度間接参照setcontext()内にあります。ただし、makecontext()を使用して初期化されていません。私は、GDBとの簡単なテストを行なったし、私はucontext_tにおける浮動小数点コンテキストへのポインタを逆参照しようとしたときにgetcontextによって初期化されていない構造体のsetcontextでセグメンテーション違反()()だ:

=> 0x00007ffff784308c < 44を>:fldenv(%rcx)

+0

まあ、それはかなりの謎を解決します。 – kibibyte

関連する問題