Skip to main content

IAR Embedded Workbench for Arm 9.70.x

スレッド ローカル ストレージ(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_sizeDLib_Threads.hで宣言済み)を呼び出すことで、取得できます。

TLSのメモリの取得の一部のオプション:

  • OSからのメモリの取得

  • ヒープメモリの割り当て

  • スレッドが完了するまでリターンしない関数のスタックでのスペースの使用

  • 専用のセクションでのスペースの使用

TLSメモリの初期化

TLSメモリを初期化するには、メモリエリアに、ポインタのある関数__iar_tls_initDLib_Threads.hで宣言済み)を呼び出します。

初期化関数はリンカセクション__iar_tls$$INIT_DATAの内容をメモリにコピーし、セクション__iar_tls$$DATAのサイズまでの残りのメモリをゼロ初期化します。C++環境では、関数__iar_call_tls_ctorsも呼び出されます。これは、セクション __iar_tls$$PREINIT_ARRAYのすべてのコンストラクタを実行します。初期化を実行すると、スレッド ローカル ストレージを使用することができます。すべてのTLS変数 にはその初期値があり、C++環境では、すべてのスレッドローカルオブジェクトが構築されています。

TLSメモリの割り当て解除

スレッドを破棄するときは、スレッドローカル ストレージ領域も処理する必要があります。C++環境では、スレッドローカルオブジェクトは、メモリ自体が処理される前に破壊されます。これは、関数__call_thread_dtorsDLib_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 */
  ...