リンカーとライブラリ

スレッド固有領域ブロックの遅延割り当て

動的な TLS モデルでは、スレッド t がオブジェクト m の TLS ブロックにアクセスする必要が生じた場合、コードは dtv t を更新し、TLS ブロックの初期割り当てを行います。スレッドライブラリは、動的な TLS 割り当てが行えるように、次のインタフェースを提供します。

typedef struct {
    unsigned long ti_moduleid;
    unsigned long ti_tlsoffset;
} TLS_index;

extern void * __tls_get_addr(TLS_index * ti);     (SPARC and x64)
extern void * ___tls_get_addr(TLS_index * ti);    (32–bit x86)

注 –

この関数の SPARC 定義と 64ビットの x86 定義は、同一の関数シグニチャーを持ちます。しかし 32 ビットの x86 バージョンは、スタック上で引数を渡すデフォルトの呼び出し規約を使用しません。代わりに 32 ビットの x86 バージョンは、より効率の良い %eax レジスタによって引数を渡します。この代替呼び出し手法を使用することを示すため、32 ビットの x86 関数名にはその先頭に 3 つの下線が付いています。


tls_get_addr() の両バージョンとも、スレッドごとの生成カウンタ gent を調べ、ベクトルが更新を必要としていないかを確認します。ベクトル dtvt が古い場合、ルーチンがベクトルを更新し、必要に応じ、追加エントリ用のスペースを確保するため再割り当てを行います。続いてこのルーチンは、dtvt,m に対応する TLS ブロックがすでに割り当てられているかを調べます。ベクトルが割り当てられていない場合、このルーチンはブロックの割 り当てと初期化を行います。このルーチンは、実行時リンカーが提供する初期化レコードリスト内の情報を使用します。ポインタ dtv t,m は、割り当てられたブロックを指すように設定されます。ルーチンは、ブロック内の指定されたオフセットへのポインタを返します。