C を使用した THREADLOCAL 共通ブロックと ILC

Fortran THREADLOCAL 共通ブロックは、 POSIX pthreads ライブラリーで定義された、スレッド固有のデータ機能を 使用してインプリメントされます。 スレッド固有のデータ域についての詳細は、 スレッド・プログラミングに関する の資料を参照してください。

内部的には、スレッド固有の共通ブロックのためのストレージは、 Fortran 実行時ライブラリーによって動的に割り振られます。 この Fortran 実行時ライブラリーは、共通ブロックについての情報を 保持する制御構造体を保守します。 この制御域は、共通ブロックの名前と同じ名前が付いた外部構造体のことです。

たとえば、以下のように Fortran で共通ブロックを宣言した場合、

         common /myblock/ i
!ibm*    threadlocal /myblock/

Fortran コンパイラーによって作成されるのは、スレッド固有の共通ブロックについての制御情報を 含む、myblock という外部構造体 (または共通域) です。

この制御構造体は以下のようなレイアウトになり、C でも同じようにコーディングされます。

       typedef struct {
          pthread_key_t key;
          int flags;
          void *unused_1;
          int unused_2;
       } FORT_LOCAL_COMMON;
       extern FORT_LOCAL_COMMON myblock;

「key」フィールドは、スレッド・ローカル・データ域を記述する、固有の ID です。 それぞれのスレッド・ローカルの共通ブロックには、独自のキーがあります。 「flags」フィールドは、共通ブロックのためにキーが取得されているかどうかを示します。 C 関数内では、スレッド・ローカルの共通域のスレッド固有アドレスを取得するために、pthread_getspecific への 呼び出しで、制御ブロックのこの 「key」を使用する必要があります。


! Example 1:  "fort_sub" is invoked by multiple threads.  This is an invalid example
! because "fort_sub" and "another_sub" both declare /block/ to be THREADLOCAL.
! They intend to share the common block, but they are executed by different threads.
 
SUBROUTINE fort_sub()
  COMMON /block/ j
  INTEGER :: j
  !IBM* THREADLOCAL /block/        ! Each thread executing fort_sub
                                   ! obtains its own copy of /block/.
  INTEGER a(10)
 
  ...
  !IBM* INDEPENDENT
  DO index = 1,10
    CALL another_sub(a(i))
  END DO
  ...
 
END SUBROUTINE fort_sub
 
SUBROUTINE another_sub(aa)        ! Multiple threads are used to execute another_sub.
  INTEGER aa
  COMMON /block/ j                ! Each thread obtains a new copy of the
  INTEGER :: j                    ! common block:  /block/.
  !IBM* THREADLOCAL /block/
  ...
  aa = j                          ! The value of 'j' is undefined.
END SUBROUTINE another_sub

詳細については、「XL Fortran ランゲージ・リファレンス」の『THREADLOCAL』ディレクティブを 参照してください。 IBM Copyright 2003