コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2022年4月15日 >>> 2022年4月15日
link もっと後

2022年4月15日

glibcのスレッドローカルストレージ - 変数宣言編

目次: C言語とlibc

スレッドごとに独立したデータを保持する空間をTLS(Thread Local Storage)といいます。日本語だと「スレッド局所記憶」というそうです。TLSへのアクセス方法、TLSの初期化方法などはアーキテクチャ依存ですので、今回はglibcのRISC-V版の実装を観察します。

スレッドローカル変数の宣言

変数宣言は __libc_tsd_define() マクロを使います。例として文字処理に使われるctype関連の変数を見ます。

ctype関連のスレッドローカル変数宣言

// glibc/ctype/ctype-info.c

__libc_tsd_define (, const uint16_t *, CTYPE_B)
__libc_tsd_define (, const int32_t *, CTYPE_TOLOWER)
__libc_tsd_define (, const int32_t *, CTYPE_TOUPPER)


// glibc/sysdeps/generic/libc-tsd.h

#define __libc_tsd_define(CLASS, TYPE, KEY)	\
  CLASS __thread TYPE __libc_tsd_##KEY attribute_tls_model_ie;


// glibc/include/libc-symbols.h

#define attribute_tls_model_ie __attribute__ ((tls_model ("initial-exec")))

マクロは下記のように展開されます。

スレッドローカル変数宣言マクロの展開例

// glibc/ctype/ctype-info.c

__libc_tsd_define (, const uint16_t *, CTYPE_B)
↓
__thread const uint16_t * __libc_tsd_CTYPE_B __attribute__ ((tls_model ("initial-exec")));


// glibc/include/ctype.h

__libc_tsd_define (extern, const uint16_t *, CTYPE_B)
↓
extern __thread const uint16_t * __libc_tsd_CTYPE_B __attribute__ ((tls_model ("initial-exec")));

ごちゃごちゃして見えますが、普通の変数宣言との違いは__thread指定子とtls_model("initial-exec") 属性の2つです。

スレッドローカル変数の宣言、詳細

これだけだと「そうですか」で終わってしまうので、もう少し詳しく調べます。

  • __thread: スレッドローカル変数であることを示します。
  • tls_model("initial-exec"): スレッドローカル変数のモデル、実行可能ファイルから参照可能な変数とします。

スレッドローカル変数のモデルは、Common Variable Attributes - Using the GNU Compiler Collection (GCC) を見る限り4種類あるようです。

  • global-dynamic
  • local-dynamic
  • initial-exec
  • local-exec

それぞれの意味は悲しいことにGCCのマニュアルに書いていないのです。どうして……。参考になるマニュアルとしては、-ftls-model (-qtls) - XL C/C++ for Linux - IBM Documentation もしくは スレッド固有ストレージのアクセスモデル - Oracle Solaris 11.1リンカーとライブラリガイドがわかりやすいです。

global-dynamic
すべてのスレッドローカル変数を参照できます。
local-dynamic
共有ライブラリのスレッドローカル変数を参照できますが、モジュール外からの参照は不可能です。global-dynamicより速いとのこと。
initial-exec
実行可能ファイルから共有ライブラリのスレッドローカル変数を参照できますが、実行可能ファイルと同時にロードされている必要があります(dlopenでロードしたライブラリは不可)。local-dynamicより速いとのこと。
local-exec
実行可能ファイル内のスレッドローカル変数のみ参照できます。initial-execより速いとのこと。

Solarisのリンカーのモデル名はGCCと少し違いますが、一見して対応がわかる程度の差でしょう。

次回は変数のアドレス取得について見たいと思います。

編集者:すずき(2022/04/22 03:01)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2022年4月15日 >>> 2022年4月15日
link もっと後

管理用メニュー

link 記事を新規作成

<2022>
<<<04>>>
-----12
3456789
10111213141516
17181920212223
24252627282930

最近のコメント5件

  • link 24年4月22日
    hdkさん (04/24 08:36)
    「うちのHHFZ4310は15年突破しまし...」
  • link 24年4月22日
    すずきさん (04/24 00:37)
    「ちゃんと数えてないですけど蛍光管が10年...」
  • link 24年4月22日
    hdkさん (04/23 20:52)
    「おお... うちのHHFZ4310より後...」
  • link 20年6月19日
    すずきさん (04/06 22:54)
    「ディレクトリを予め作成しておけば良いです...」
  • link 20年6月19日
    斎藤さん (04/06 16:25)
    「「Preferencesというメニューか...」

最近の記事3件

  • link 24年5月3日
    すずき (05/06 16:21)
    「[ROCK 3Cの青色LED点滅を止める] 目次: Arduinoゲーミングマシンの流行により、最近のコンピュータは意味もなく...」
  • link 23年6月2日
    すずき (05/06 16:10)
    「[Arduino - まとめリンク] 目次: Arduino一覧が欲しくなったので作りました。 M5Stackとesp32とA...」
  • link 24年4月25日
    すずき (04/29 10:08)
    「[AVIFの変換] AVIFが読めないアプリケーションがたまにあるので、AVIF(AV1 Image File Format)...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 05/06 16:21