LoginSignup
6
5

More than 5 years have passed since last update.

thread_local修飾子

Posted at

systemdではthread_local修飾子が使われている。thread_localは、C11で導入された、スレッドローカルな変数を定義するための修飾子である (参考: C11: A New C Standard Aiming at Safer Programming)。

とはいえ、かなり新しいコンパイラでないとサポートしていないので、systemdでは以下のようなマクロを定義して、サポートしていないコンパイラでは古い修飾子を使うようにしている。

src/shared/macro.h
/* Define C11 thread_local attribute even on older gcc compiler
 * version */
#ifndef thread_local
/*
 * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
 * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
 */
#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
#define thread_local _Thread_local
#else
#define thread_local __thread
#endif
#endif

systemdでは主にstaticローカル変数でthread_localを使っている。staticローカル変数を使いつつ、スレッドセーフを実現するためだと思われる。

例えば、inhibit_what_to_string というユーティリティ関数がある。

src/login/logind-inhibit.c
const char *inhibit_what_to_string(InhibitWhat w) {
        static thread_local char buffer[97];

        if (w < 0 || w >= _INHIBIT_WHAT_MAX)
                return NULL;

        p = buffer;
        if (w & INHIBIT_SHUTDOWN)
                p = stpcpy(p, "shutdown:");
        if (w & INHIBIT_SLEEP)
                p = stpcpy(p, "sleep:");

        /* snip */

        return buffer;

エラーコードに従ってエラーメッセージのための文字列を返すのだが、static thread_localローカル変数の文字列バッファを使っているので、呼び出し側は文字列を解放しなくても良い。しかも、スレッドセーフである。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5