スレッド ローカル ストレージ(TLS)の設定
スレッド ローカル ストレージ(TLS)は、C(C11で導入された_Thread_local型指定子を介して)およびC++(C++11で導入されたthread_local型指定子を介して)の両方でサポートされます。TLS変数はスレッド ローカル ストレージに配置され、スレッドが作成されるとメモリ領域がセットアップされます。スレッドが破壊されると、使用しているリソースはすべて、戻ります。C++環境では、スレッド ローカル ストレージがセットアップされるとTLSオブジェクトが作成され、スレッド ローカル ストレージが破壊される前にTLSオブジェクトが破壊されます。
オペレーションシステムを使用している場合は、関連のTLSドキュメントを参照してください。追加情報は、IARライブラリヘッダファイルDLib_Threads.hに記載されています。そのような特定のソースからの情報は、この通常の概要よりも優先されます。
メインスレッド
リンカオプション--threaded_libを指定すると、TLSが有効になります。通常のシステムのスタートアップは、メインスレッドのスレッド ローカル ストレージの初期化を実行します。メインスレッドの初期化したTLS変数は、リンカセクション.tdataに配置され、ゼロ初期化したTLS変数はセクション .tbssに配置されます。その他のすべてのスレッドは作成されると、そのスレッド ローカル ストレージをセットアップします。‑‑threaded_libが指定されていないと、.tdataおよび.tbss セクションのコンテンツは、.dataおよび.bssのように扱われます。ただし、そのような変数へのアクセスはまだTLSアクセスです。
TLSのメモリの取得
TLS変数はメモリに配置する必要があります。スレッドの存続期間中にメモリが利用可能であれば、これがどのように処理されるかは重要ではありません。スレッドのローカル記憶領域のサイズは、関数__iar_tls_size(DLib_Threads.hで宣言済み)を呼び出すことで、取得できます。
TLSのメモリの取得の一部のオプション:
OSからのメモリの取得
ヒープメモリの割り当て
スレッドが完了するまでリターンしない関数のスタックでのスペースの使用
専用のセクションでのスペースの使用
TLSメモリの初期化
TLSメモリを初期化するには、メモリエリアに、ポインタのある関数__iar_tls_init(DLib_Threads.hで宣言済み)を呼び出します。
初期化関数はリンカセクション__iar_tls$$INIT_DATAの内容をメモリにコピーし、セクション__iar_tls$$DATAのサイズまでの残りのメモリをゼロ初期化します。C++環境では、関数__iar_call_tls_ctorsも呼び出されます。これは、セクション __iar_tls$$PREINIT_ARRAYのすべてのコンストラクタを実行します。初期化を実行すると、スレッド ローカル ストレージを使用することができます。すべてのTLS変数 にはその初期値があり、C++環境では、すべてのスレッドローカルオブジェクトが構築されています。
TLSメモリの割り当て解除
スレッドを破棄するときは、スレッドローカル ストレージ領域も処理する必要があります。C++環境では、スレッドローカルオブジェクトは、メモリ自体が処理される前に破壊されます。これは、関数__call_thread_dtors(DLib_Threads.hで宣言済み)を呼び出すと行われます。メモリがハンドラ(ヒープ、OSなど)から取得された場合は、そのメモリを返す必要があります。
例として、このコードの断片情報は、ヒープのスレッド ローカル ストレージを割り当てます。tpは、スレッドコントロールオブジェクトへのポインタです。
/* creating a new thread */
...
/* initialize TLS */
void * tls_mem = malloc(__iar_tls_size()); /* get memory */
__iar_tls_init(tls_mem); /* init TLS in the */
/* new memory */
tp->tls_area = tls_mem; /* set the thread’s */
/* TLS area to the new memory */... /* destroying a thread */ ... /* destroy the TLS area */ __call_thread_dtors(); /* only if C++ is used */ free(tp->tls_area); /* return memory */ ...