makecontext() - ユーザー・コンテキストの変更

標準

標準/拡張機能 C/C++ 依存項目

XPG4.2
Single UNIX Specification、バージョン 3

両方 POSIX(ON)

形式

#define _XOPEN_SOURCE_EXTENDED 1
#include <ucontext.h>

void makecontext(ucontext_t *ucp, void (*func)(), int argc, …);

機能説明

makecontext() 関数は、ucp で指定されたコンテキストを 変更します。このコンテキストは getcontext() を使って初期化されたものです。このコンテキストが setcontext() または swapcontext() を使って 再開されると、プログラム実行は func() を 呼び出し、makecontext() 呼び出しの argc に続く引数を これに渡して続行します。

argc の値は、func() に渡される整数引数の 番号に一致しなければなりません。一致していない場合、動作は未定義になります。

ucontext_tuc_link メンバーは、makecontext() により変更中のコンテキストが戻るときに再開されるコンテキストを判別する場合に使用します。uc_link メンバーが 0 でない場合、uc_link メンバーにより指示されたコンテキストを使用する setcontext() 呼び出しのあとであるかのように、プロセスが継続します。uc_link メンバーが 0 の場合、プロセスは、exit() が呼び出されたかのように終了します。uc_link メンバーは、makecontext() 呼び出しの前に 初期化しておいてください。

この関数がサポートされるのは、POSIX プログラムだけです。

この関数は、AMODE 31 XPLINK 環境ではサポートされません (例えば、 AMODE 31 のときで、main() 関数が XPLINK オプションを指定してコンパイルされたか、 または XPLINK(ON) ランタイム・オプションが指定された環境)。

<ucontext.h> ヘッダー・ファイルは、次のメンバーをインクルードする構造体として、ucontext_t 型を定義します。
mcontext_t       uc_mcontext     A machine-specific representation
                                 of the saved context.
ucontext_t      *uc_link         Pointer to the context that will
                                 be resumed when this context returns.
sigset_t         uc_sigmask      The set of signals that are blocked
                                 when this context is active.
stack_t          uc_stack        The stack used by this context.

C++ の特殊な動作

C および C++ のリンケージ規約は非互換の ため、makecontext() は C++ 関数ポインターを受け取ることが できません。C++ 関数ポインターを makecontext() へ渡そうとすると、コンパイラーは エラーとしてフラグを立てます。C++ makecontext() 関数を使用するには、makecontext() 用に登録されているすべての関数が、関数を extern “C” と宣言することにより、C リンケージを とるようにする必要があります。例えば、次のようになります。
C:   void func(int, int);
     :
     makecontext(&context, func, 2, arg1, arg2);

C++: extern "C" void func();
     :
     makecontext(&context, func, 2, arg1, arg2);

AMODE 64 に関する考慮事項

スタック用のストレージは 2 GB 境界より上でなければなりません。 これは、__malloc24() または __malloc31() 関数で獲得されたストレージではない場合があります。 スタックは、1 M の保護ページ (1 M 境界上に位置合わせされる) を作成するのに十分な大きさである必要があります。

環境変数 _EDC_CONTEXT_GUARD は、どのようなときにスタックを保護するか、保護しないかを制御するために使用できます。_EDC_CONTEXT_GUARD 環境変数の詳細については、「z/OS XL C/C++ プログラミング・ガイド」の『環境変数の使用』の章を参照してください。

戻り値

makecontext() は、値を戻しません。

正常に実行されなかった場合、makecontext() は errno を次のいずれかの値に設定します。
エラー・コード
説明
EINVAL
変更中のコンテキストは代替スタックを使用している。また、ターゲット関数のエントリー・ポイントが有効な Language Environment® または C エントリー・ポイント ではない。

argc 引数が 0 未満の値を指定する。

ENOMEM
ucp 引数には、命令を完了するのに十分な スタックが残されていない。あるいは、16 以上の引数がターゲット関数に渡され、それらの引数のすべてを保持するのに十分なストレージがない。
注: ターゲット関数がまだロードされていない DLL にある 場合、makecontext() はサイズ要件を判別することができない ため、必要なサイズが MINSIGSTKSZ であると想定します。そのため、この場合、スタックのサイズを MINSIGSTKSZ が 示すサイズ以上にする必要があります。ターゲット関数が必要とするサイズが MINSIGSTKSZ を超える 場合は、makecontext() を呼び出す前に DLL をロードする必要があります。

この例では、メインで getcontext() ステートメントを使ってコンテキストを作成し、次にコンテキストに独自のスタックを持たせ、func 関数を呼び出すように変更します。ここでは、setcontext() ステートメントを使って関数を呼び出します。uc_link メンバーは 0 に設定されているので、このプロセスは関数が戻ると終了します。
/* This example shows the usage of makecontext().                    */

#define _XOPEN_SOURCE_EXTENDED 1
#include <stdlib.h>
#include <stdio.h>
#include <ucontext.h>
#include <errno.h>

 #ifdef _LP64
  #define STACK_SIZE 2097152+16384 /* large enough value for AMODE 64 */
 #else
  #define STACK_SIZE 16384         /* AMODE 31 addressing */
 #endif

void func(int);

ucontext_t context, *cp = &context;

int main(void) {

  int  value = 1;

  getcontext(cp);
  context.uc_link = 0;
  if ((context.uc_stack.ss_sp = (char *) malloc(STACK_SIZE)) != NULL) {
    context.uc_stack.ss_size = STACK_SIZE;
    context.uc_stack.ss_flags = 0;
             errno = 0;
    makecontext(cp,func,1,value);
              if(errno != 0){
                perror("Error reported by makecontext()");
                return -1;         /* Error occurred exit */ }
  }
  else {
    perror("not enough storage for stack");
    abort();
  }
  printf("context has been built¥n");
  setcontext(cp);
  perror("returned from setcontext");
  abort();

}

void func(int arg) {

  printf("function called with value %d¥n",arg);
  printf("process will exit when function returns¥n");
  return;

}
出力:
context has been built
function called with value 1
process will exit when function returns

関連情報