[OS] Thread Local Storage (TLS)
TLS(Thread Local Storage)๋?
TLS๋ Thread Local Storage์ ์ฝ์๋ก thread๋ณ๋ก ๊ณ ์ ํ ์ ์ญ/์ ์ ๋ณ์๋ฅผ ์ ์ฅํ ์ ์๊ฒ ํ๋ ๊ณต๊ฐ์ด๋ค.
์ค๋ ๋๋ ์๋ ์ค๋ ๋ ๋ณ๋ก ๊ณ ์ ์ ์คํ์ ๊ฐ์ง์ง๋ง, ์ ์ญ/์ ์ ๋ณ์๋ ํ๋ก์ธ์ค์ ๋ชจ๋ ์ค๋ ๋๊ฐ ์ ๊ทผ ๊ฐ๋ฅํ๋ค. ๋ฐ๋ผ์ ์ ์ญ/์ ์ ๋ณ์๋ฅผ ์ค๋ ๋ ๋ณ๋ก ํ ๋นํด์ฃผ๊ณ ์ถ์ ๋ TLS๋ฅผ ์ฌ์ฉํ๋ค. (๋ฐ๋ผ์ TLS์ ๋ค์ด์๋ ์ ๋ค์ ์ง์ญ ๋ณ์์ ๋ค๋ฅด๊ฒ ํจ์ above์์ ๋ค visibleํ๋ค) TLS๋ ํ๋ก์ธ์ค ์คํ์ ํ์ํ ์ฌ๋ฌ ์ ๋ณด๊ฐ ๋ค์ด์๋ค
fs๋ TLS๋ฅผ ๊ฐ๋ฆฌํค๋๋ฐ, ์๋ฅผ ๋ค์ด fs:0x28์๋ ์คํ ์นด๋๋ฆฌ์ ๊ฐ์ผ๋ก ์ฐ์ด๋ ๋๋คํ ๊ฐ์ด ์ ์ฅ๋๋ค.
๋์ถฉ tls ์์ฑํ๋ ํจ์์ ์๋๋ ใ ใ
static void *
init_tls (void)
{
/* Construct the static TLS block and the dtv for the initial
thread. For some platforms this will include allocating memory
for the thread descriptor. The memory for the TLS block will
never be freed. It should be allocated accordingly. The dtv
array can be changed if dynamic loading requires it. */
void *tcbp = _dl_allocate_tls_storage (); //_dl_allocate_tls_storage๋ก tls๋ฅผ ์์ฑํจ
if (tcbp == NULL)
_dl_fatal_printf ("\
cannot allocate TLS data structures for initial thread\n");
/* Store for detection of the special case by __tls_get_addr
so it knows not to pass this dtv to the normal realloc. */
GL(dl_initial_dtv) = GET_DTV (tcbp); //์ ์ผ๋ฐ realloc์ผ๋ก ์ด๋ถ๋ถ ํ ๋นํ์ง์๊ฒ ํ๋ ๊ฒ์ธ๋ฏํจ
/* And finally install it for the main thread. */
const char *lossage = TLS_INIT_TP (tcbp); //TLS_INIT_TP ๋งคํฌ๋ก๋ก FS๋ฅผ TLS๋ก ์ด๊ธฐํํจ
//๋ด๋ถ์ arch_prctlํจ์์ ์ธ์๋ก SET_FS๋ tcbp๋ก ๋๊ฒจ์ฃผ๋๋ฐ
//์ด์น๊ตฌ๊ฐ FS๋ฅผ tcbp๋ก ์ด๊ธฐํํ๋ ๊ฒ์
if (__glibc_unlikely (lossage != NULL))
_dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
tls_init_tp_called = true;
return tcbp;
}
TLS_INIT_TP ๋งคํฌ๋ก์ ์์์ ์ฌ๊ธฐ์ FS๋ถ๋ถ์ TLS๋ฅผ ์ด๊ธฐํํ๋ค๊ณ ํ์
# define TLS_INIT_TP(thrdescr) \
({ void *_thrdescr = (thrdescr); \
tcbhead_t *_head = _thrdescr; \
int _result; \
\
_head->tcb = _thrdescr; \
/* For now the thread descriptor is at the same address. */ \
_head->self = _thrdescr; \
\
/* It is a simple syscall to set the %fs value for the thread. */ \
asm volatile ("syscall" \
: "=a" (_result) \
: "0" ((unsigned long int) __NR_arch_prctl), \
"D" ((unsigned long int) ARCH_SET_FS), \
"S" (_thrdescr) \
: "memory", "cc", "r11", "cx"); \
\
_result ? "cannot set %fs base address for thread-local storage" : 0; \
})
์๋ฅผ ํตํด FS ์ธ๊ทธ๋จผํธ ๋ ์ง์คํฐ๋ ์ด๋๋ฅผ ๊ฐ๋ฆฌํจ๋ค? ๋ฐ๋ก TLS๋ฅผ ๊ฐ๋ฆฌํค๊ฒ๋๋ค~
(FS๊ฐ TLS๊ฐ๋ฆฌํค๋ ๊ฑฐ์ TLS๊ฐ FS ๊ฐ๋ฆฌํค๋๊ฒ ์๋๋ผ! (์๋ง?))
References
https://en.wikipedia.org/wiki/Thread-local_storage
https://learn.microsoft.com/ko-kr/windows/win32/procthread/thread-local-storage?redirectedfrom=MSDN
http://egloos.zum.com/sweeper/v/1985738
tls๋ ์คํ๋ง๋ค ํ๋์ฉ ์์ฑ๋จ
info thread๋ก ์ฐ์์ ๋ ์๋ง ๋์ค๋๋ฐ TLS base์ธ๋ฏ?