Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy accessing pthread keys' sequence number is not synchronized in glibc's NPTL implementation?
    text
    copied!<p>Recently when I look into how the thread-local storage is implemented in glibc, I found the following code, which implements the API <code>pthread_key_create()</code></p> <pre><code>int __pthread_key_create (key, destr) pthread_key_t *key; void (*destr) (void *); { /* Find a slot in __pthread_kyes which is unused. */ for (size_t cnt = 0; cnt &lt; PTHREAD_KEYS_MAX; ++cnt) { uintptr_t seq = __pthread_keys[cnt].seq; if (KEY_UNUSED (seq) &amp;&amp; KEY_USABLE (seq) /* We found an unused slot. Try to allocate it. */ &amp;&amp; ! atomic_compare_and_exchange_bool_acq (&amp;__pthread_keys[cnt].seq, seq + 1, seq)) { /* Remember the destructor. */ __pthread_keys[cnt].destr = destr; /* Return the key to the caller. */ *key = cnt; /* The call succeeded. */ return 0; } } return EAGAIN; } </code></pre> <p><code>__pthread_keys</code> is a global array accessed by all threads. I don't understand why the read of its member <code>seq</code> is not synchronized as in the following:</p> <pre><code>uintptr_t seq = __pthread_keys[cnt].seq; </code></pre> <p>although it is syncrhonized when modified later.</p> <p>FYI, <code>__pthread_keys</code> is an array of type <code>struct pthread_key_struct</code>, which is defined as follows:</p> <pre><code>/* Thread-local data handling. */ struct pthread_key_struct { /* Sequence numbers. Even numbers indicated vacant entries. Note that zero is even. We use uintptr_t to not require padding on 32- and 64-bit machines. On 64-bit machines it helps to avoid wrapping, too. */ uintptr_t seq; /* Destructor for the data. */ void (*destr) (void *); }; </code></pre> <p>Thanks in advance.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload