ovs-thread: Add checking for mutex and rwlock initialization.
[sliver-openvswitch.git] / lib / ovs-thread.c
1 /*
2  * Copyright (c) 2013, 2014 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18 #include "ovs-thread.h"
19 #include <errno.h>
20 #include <poll.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include "compiler.h"
24 #include "hash.h"
25 #include "ovs-rcu.h"
26 #include "poll-loop.h"
27 #include "socket-util.h"
28 #include "util.h"
29
30 #ifdef __CHECKER__
31 /* Omit the definitions in this file because they are somewhat difficult to
32  * write without prompting "sparse" complaints, without ugliness or
33  * cut-and-paste.  Since "sparse" is just a checker, not a compiler, it
34  * doesn't matter that we don't define them. */
35 #else
36 #include "vlog.h"
37
38 VLOG_DEFINE_THIS_MODULE(ovs_thread);
39
40 /* If there is a reason that we cannot fork anymore (unless the fork will be
41  * immediately followed by an exec), then this points to a string that
42  * explains why. */
43 static const char *must_not_fork;
44
45 /* True if we created any threads beyond the main initial thread. */
46 static bool multithreaded;
47
48 #define LOCK_FUNCTION(TYPE, FUN) \
49     void \
50     ovs_##TYPE##_##FUN##_at(const struct ovs_##TYPE *l_, \
51                             const char *where) \
52         OVS_NO_THREAD_SAFETY_ANALYSIS \
53     { \
54         struct ovs_##TYPE *l = CONST_CAST(struct ovs_##TYPE *, l_); \
55         int error; \
56  \
57         /* Verify that 'l' was initialized. */ \
58         ovs_assert(l->where); \
59  \
60         error = pthread_##TYPE##_##FUN(&l->lock); \
61         if (OVS_UNLIKELY(error)) { \
62             ovs_abort(error, "pthread_%s_%s failed", #TYPE, #FUN); \
63         } \
64         l->where = where; \
65  }
66 LOCK_FUNCTION(mutex, lock);
67 LOCK_FUNCTION(rwlock, rdlock);
68 LOCK_FUNCTION(rwlock, wrlock);
69
70 #define TRY_LOCK_FUNCTION(TYPE, FUN) \
71     int \
72     ovs_##TYPE##_##FUN##_at(const struct ovs_##TYPE *l_, \
73                             const char *where) \
74         OVS_NO_THREAD_SAFETY_ANALYSIS \
75     { \
76         struct ovs_##TYPE *l = CONST_CAST(struct ovs_##TYPE *, l_); \
77         int error; \
78  \
79         /* Verify that 'l' was initialized. */ \
80         ovs_assert(l->where); \
81  \
82         error = pthread_##TYPE##_##FUN(&l->lock); \
83         if (OVS_UNLIKELY(error) && error != EBUSY) { \
84             ovs_abort(error, "pthread_%s_%s failed", #TYPE, #FUN); \
85         } \
86         if (!error) { \
87             l->where = where; \
88         } \
89         return error; \
90     }
91 TRY_LOCK_FUNCTION(mutex, trylock);
92 TRY_LOCK_FUNCTION(rwlock, tryrdlock);
93 TRY_LOCK_FUNCTION(rwlock, trywrlock);
94
95 #define UNLOCK_FUNCTION(TYPE, FUN, WHERE) \
96     void \
97     ovs_##TYPE##_##FUN(const struct ovs_##TYPE *l_) \
98         OVS_NO_THREAD_SAFETY_ANALYSIS \
99     { \
100         struct ovs_##TYPE *l = CONST_CAST(struct ovs_##TYPE *, l_); \
101         int error; \
102  \
103         /* Verify that 'l' was initialized. */ \
104         ovs_assert(l->where); \
105  \
106         l->where = WHERE; \
107         error = pthread_##TYPE##_##FUN(&l->lock); \
108         if (OVS_UNLIKELY(error)) { \
109             ovs_abort(error, "pthread_%s_%sfailed", #TYPE, #FUN); \
110         } \
111     }
112 UNLOCK_FUNCTION(mutex, unlock, "<unlocked>");
113 UNLOCK_FUNCTION(mutex, destroy, NULL);
114 UNLOCK_FUNCTION(rwlock, unlock, "<unlocked>");
115 UNLOCK_FUNCTION(rwlock, destroy, NULL);
116
117 #define XPTHREAD_FUNC1(FUNCTION, PARAM1)                \
118     void                                                \
119     x##FUNCTION(PARAM1 arg1)                            \
120     {                                                   \
121         int error = FUNCTION(arg1);                     \
122         if (OVS_UNLIKELY(error)) {                      \
123             ovs_abort(error, "%s failed", #FUNCTION);   \
124         }                                               \
125     }
126 #define XPTHREAD_FUNC2(FUNCTION, PARAM1, PARAM2)        \
127     void                                                \
128     x##FUNCTION(PARAM1 arg1, PARAM2 arg2)               \
129     {                                                   \
130         int error = FUNCTION(arg1, arg2);               \
131         if (OVS_UNLIKELY(error)) {                      \
132             ovs_abort(error, "%s failed", #FUNCTION);   \
133         }                                               \
134     }
135 #define XPTHREAD_FUNC3(FUNCTION, PARAM1, PARAM2, PARAM3)\
136     void                                                \
137     x##FUNCTION(PARAM1 arg1, PARAM2 arg2, PARAM3 arg3)  \
138     {                                                   \
139         int error = FUNCTION(arg1, arg2, arg3);         \
140         if (OVS_UNLIKELY(error)) {                      \
141             ovs_abort(error, "%s failed", #FUNCTION);   \
142         }                                               \
143     }
144
145 XPTHREAD_FUNC1(pthread_mutex_lock, pthread_mutex_t *);
146 XPTHREAD_FUNC1(pthread_mutex_unlock, pthread_mutex_t *);
147 XPTHREAD_FUNC1(pthread_mutexattr_init, pthread_mutexattr_t *);
148 XPTHREAD_FUNC1(pthread_mutexattr_destroy, pthread_mutexattr_t *);
149 XPTHREAD_FUNC2(pthread_mutexattr_settype, pthread_mutexattr_t *, int);
150 XPTHREAD_FUNC2(pthread_mutexattr_gettype, pthread_mutexattr_t *, int *);
151
152 XPTHREAD_FUNC1(pthread_rwlockattr_init, pthread_rwlockattr_t *);
153 XPTHREAD_FUNC1(pthread_rwlockattr_destroy, pthread_rwlockattr_t *);
154 #ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
155 XPTHREAD_FUNC2(pthread_rwlockattr_setkind_np, pthread_rwlockattr_t *, int);
156 #endif
157
158 XPTHREAD_FUNC2(pthread_cond_init, pthread_cond_t *, pthread_condattr_t *);
159 XPTHREAD_FUNC1(pthread_cond_destroy, pthread_cond_t *);
160 XPTHREAD_FUNC1(pthread_cond_signal, pthread_cond_t *);
161 XPTHREAD_FUNC1(pthread_cond_broadcast, pthread_cond_t *);
162
163 XPTHREAD_FUNC3(pthread_barrier_init, pthread_barrier_t *,
164                pthread_barrierattr_t *, unsigned int);
165 XPTHREAD_FUNC1(pthread_barrier_destroy, pthread_barrier_t *);
166
167 XPTHREAD_FUNC2(pthread_join, pthread_t, void **);
168
169 typedef void destructor_func(void *);
170 XPTHREAD_FUNC2(pthread_key_create, pthread_key_t *, destructor_func *);
171 XPTHREAD_FUNC1(pthread_key_delete, pthread_key_t);
172 XPTHREAD_FUNC2(pthread_setspecific, pthread_key_t, const void *);
173
174 static void
175 ovs_mutex_init__(const struct ovs_mutex *l_, int type)
176 {
177     struct ovs_mutex *l = CONST_CAST(struct ovs_mutex *, l_);
178     pthread_mutexattr_t attr;
179     int error;
180
181     l->where = "<unlocked>";
182     xpthread_mutexattr_init(&attr);
183     xpthread_mutexattr_settype(&attr, type);
184     error = pthread_mutex_init(&l->lock, &attr);
185     if (OVS_UNLIKELY(error)) {
186         ovs_abort(error, "pthread_mutex_init failed");
187     }
188     xpthread_mutexattr_destroy(&attr);
189 }
190
191 /* Initializes 'mutex' as a normal (non-recursive) mutex. */
192 void
193 ovs_mutex_init(const struct ovs_mutex *mutex)
194 {
195     ovs_mutex_init__(mutex, PTHREAD_MUTEX_ERRORCHECK);
196 }
197
198 /* Initializes 'mutex' as a recursive mutex. */
199 void
200 ovs_mutex_init_recursive(const struct ovs_mutex *mutex)
201 {
202     ovs_mutex_init__(mutex, PTHREAD_MUTEX_RECURSIVE);
203 }
204
205 /* Initializes 'mutex' as a recursive mutex. */
206 void
207 ovs_mutex_init_adaptive(const struct ovs_mutex *mutex)
208 {
209 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
210     ovs_mutex_init__(mutex, PTHREAD_MUTEX_ADAPTIVE_NP);
211 #else
212     ovs_mutex_init(mutex);
213 #endif
214 }
215
216 void
217 ovs_rwlock_init(const struct ovs_rwlock *l_)
218 {
219     struct ovs_rwlock *l = CONST_CAST(struct ovs_rwlock *, l_);
220     pthread_rwlockattr_t attr;
221     int error;
222
223     l->where = "<unlocked>";
224
225     xpthread_rwlockattr_init(&attr);
226 #ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
227     xpthread_rwlockattr_setkind_np(
228         &attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
229 #endif
230     error = pthread_rwlock_init(&l->lock, NULL);
231     if (OVS_UNLIKELY(error)) {
232         ovs_abort(error, "pthread_rwlock_init failed");
233     }
234     xpthread_rwlockattr_destroy(&attr);
235 }
236
237 void
238 ovs_mutex_cond_wait(pthread_cond_t *cond, const struct ovs_mutex *mutex_)
239 {
240     struct ovs_mutex *mutex = CONST_CAST(struct ovs_mutex *, mutex_);
241     int error;
242
243     ovsrcu_quiesce_start();
244     error = pthread_cond_wait(cond, &mutex->lock);
245     ovsrcu_quiesce_end();
246
247     if (OVS_UNLIKELY(error)) {
248         ovs_abort(error, "pthread_cond_wait failed");
249     }
250 }
251
252 int
253 xpthread_barrier_wait(pthread_barrier_t *barrier)
254 {
255     int error;
256
257     ovsrcu_quiesce_start();
258     error = pthread_barrier_wait(barrier);
259     ovsrcu_quiesce_end();
260
261     if (error && OVS_UNLIKELY(error != PTHREAD_BARRIER_SERIAL_THREAD)) {
262         ovs_abort(error, "pthread_barrier_wait failed");
263     }
264
265     return error;
266 }
267 \f
268 DEFINE_EXTERN_PER_THREAD_DATA(ovsthread_id, 0);
269
270 struct ovsthread_aux {
271     void *(*start)(void *);
272     void *arg;
273     char name[16];
274 };
275
276 static void *
277 ovsthread_wrapper(void *aux_)
278 {
279     static atomic_uint next_id = ATOMIC_VAR_INIT(1);
280
281     struct ovsthread_aux *auxp = aux_;
282     struct ovsthread_aux aux;
283     unsigned int id;
284
285     atomic_add(&next_id, 1, &id);
286     *ovsthread_id_get() = id;
287
288     aux = *auxp;
289     free(auxp);
290
291     /* The order of the following calls is important, because
292      * ovsrcu_quiesce_end() saves a copy of the thread name. */
293     set_subprogram_name("%s%u", aux.name, id);
294     ovsrcu_quiesce_end();
295
296     return aux.start(aux.arg);
297 }
298
299 /* Starts a thread that calls 'start(arg)'.  Sets the thread's name to 'name'
300  * (suffixed by its ovsthread_id()).  Returns the new thread's pthread_t. */
301 pthread_t
302 ovs_thread_create(const char *name, void *(*start)(void *), void *arg)
303 {
304     struct ovsthread_aux *aux;
305     pthread_t thread;
306     int error;
307
308     forbid_forking("multiple threads exist");
309     multithreaded = true;
310     ovsrcu_quiesce_end();
311
312     aux = xmalloc(sizeof *aux);
313     aux->start = start;
314     aux->arg = arg;
315     ovs_strlcpy(aux->name, name, sizeof aux->name);
316
317     error = pthread_create(&thread, NULL, ovsthread_wrapper, aux);
318     if (error) {
319         ovs_abort(error, "pthread_create failed");
320     }
321     return thread;
322 }
323 \f
324 bool
325 ovsthread_once_start__(struct ovsthread_once *once)
326 {
327     ovs_mutex_lock(&once->mutex);
328     if (!ovsthread_once_is_done__(once)) {
329         return false;
330     }
331     ovs_mutex_unlock(&once->mutex);
332     return true;
333 }
334
335 void
336 ovsthread_once_done(struct ovsthread_once *once)
337 {
338     atomic_store(&once->done, true);
339     ovs_mutex_unlock(&once->mutex);
340 }
341 \f
342 bool
343 single_threaded(void)
344 {
345     return !multithreaded;
346 }
347
348 /* Asserts that the process has not yet created any threads (beyond the initial
349  * thread).
350  *
351  * ('where' is used in logging.  Commonly one would use
352  * assert_single_threaded() to automatically provide the caller's source file
353  * and line number for 'where'.) */
354 void
355 assert_single_threaded_at(const char *where)
356 {
357     if (multithreaded) {
358         VLOG_FATAL("%s: attempted operation not allowed when multithreaded",
359                    where);
360     }
361 }
362
363 #ifndef _WIN32
364 /* Forks the current process (checking that this is allowed).  Aborts with
365  * VLOG_FATAL if fork() returns an error, and otherwise returns the value
366  * returned by fork().
367  *
368  * ('where' is used in logging.  Commonly one would use xfork() to
369  * automatically provide the caller's source file and line number for
370  * 'where'.) */
371 pid_t
372 xfork_at(const char *where)
373 {
374     pid_t pid;
375
376     if (must_not_fork) {
377         VLOG_FATAL("%s: attempted to fork but forking not allowed (%s)",
378                    where, must_not_fork);
379     }
380
381     pid = fork();
382     if (pid < 0) {
383         VLOG_FATAL("%s: fork failed (%s)", where, ovs_strerror(errno));
384     }
385     return pid;
386 }
387 #endif
388
389 /* Notes that the process must not call fork() from now on, for the specified
390  * 'reason'.  (The process may still fork() if it execs itself immediately
391  * afterward.) */
392 void
393 forbid_forking(const char *reason)
394 {
395     ovs_assert(reason != NULL);
396     must_not_fork = reason;
397 }
398
399 /* Returns true if the process is allowed to fork, false otherwise. */
400 bool
401 may_fork(void)
402 {
403     return !must_not_fork;
404 }
405 \f
406 /* ovsthread_stats. */
407
408 void
409 ovsthread_stats_init(struct ovsthread_stats *stats)
410 {
411     int i;
412
413     ovs_mutex_init(&stats->mutex);
414     for (i = 0; i < ARRAY_SIZE(stats->buckets); i++) {
415         stats->buckets[i] = NULL;
416     }
417 }
418
419 void
420 ovsthread_stats_destroy(struct ovsthread_stats *stats)
421 {
422     ovs_mutex_destroy(&stats->mutex);
423 }
424
425 void *
426 ovsthread_stats_bucket_get(struct ovsthread_stats *stats,
427                            void *(*new_bucket)(void))
428 {
429     unsigned int idx = ovsthread_id_self() & (ARRAY_SIZE(stats->buckets) - 1);
430     void *bucket = stats->buckets[idx];
431     if (!bucket) {
432         ovs_mutex_lock(&stats->mutex);
433         bucket = stats->buckets[idx];
434         if (!bucket) {
435             bucket = stats->buckets[idx] = new_bucket();
436         }
437         ovs_mutex_unlock(&stats->mutex);
438     }
439     return bucket;
440 }
441
442 size_t
443 ovs_thread_stats_next_bucket(const struct ovsthread_stats *stats, size_t i)
444 {
445     for (; i < ARRAY_SIZE(stats->buckets); i++) {
446         if (stats->buckets[i]) {
447             break;
448         }
449     }
450     return i;
451 }
452
453 \f
454 /* Parses /proc/cpuinfo for the total number of physical cores on this system
455  * across all CPU packages, not counting hyper-threads.
456  *
457  * Sets *n_cores to the total number of cores on this system, or 0 if the
458  * number cannot be determined. */
459 static void
460 parse_cpuinfo(long int *n_cores)
461 {
462     static const char file_name[] = "/proc/cpuinfo";
463     char line[128];
464     uint64_t cpu = 0; /* Support up to 64 CPU packages on a single system. */
465     long int cores = 0;
466     FILE *stream;
467
468     stream = fopen(file_name, "r");
469     if (!stream) {
470         VLOG_DBG("%s: open failed (%s)", file_name, ovs_strerror(errno));
471         return;
472     }
473
474     while (fgets(line, sizeof line, stream)) {
475         unsigned int id;
476
477         /* Find the next CPU package. */
478         if (ovs_scan(line, "physical id%*[^:]: %u", &id)) {
479             if (id > 63) {
480                 VLOG_WARN("Counted over 64 CPU packages on this system. "
481                           "Parsing %s for core count may be inaccurate.",
482                           file_name);
483                 cores = 0;
484                 break;
485             }
486
487             if (cpu & (1 << id)) {
488                 /* We've already counted this package's cores. */
489                 continue;
490             }
491             cpu |= 1 << id;
492
493             /* Find the number of cores for this package. */
494             while (fgets(line, sizeof line, stream)) {
495                 int count;
496
497                 if (ovs_scan(line, "cpu cores%*[^:]: %u", &count)) {
498                     cores += count;
499                     break;
500                 }
501             }
502         }
503     }
504     fclose(stream);
505
506     *n_cores = cores;
507 }
508
509 /* Returns the total number of cores on this system, or 0 if the number cannot
510  * be determined.
511  *
512  * Tries not to count hyper-threads, but may be inaccurate - particularly on
513  * platforms that do not provide /proc/cpuinfo, but also if /proc/cpuinfo is
514  * formatted different to the layout that parse_cpuinfo() expects. */
515 int
516 count_cpu_cores(void)
517 {
518     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
519     static long int n_cores;
520
521     if (ovsthread_once_start(&once)) {
522 #ifndef _WIN32
523         parse_cpuinfo(&n_cores);
524         if (!n_cores) {
525             n_cores = sysconf(_SC_NPROCESSORS_ONLN);
526         }
527 #else
528         SYSTEM_INFO sysinfo;
529         GetSystemInfo(&sysinfo);
530         n_cores = sysinfo.dwNumberOfProcessors;
531 #endif
532         ovsthread_once_done(&once);
533     }
534
535     return n_cores > 0 ? n_cores : 0;
536 }
537 \f
538 /* ovsthread_key. */
539
540 #define L1_SIZE 1024
541 #define L2_SIZE 1024
542 #define MAX_KEYS (L1_SIZE * L2_SIZE)
543
544 /* A piece of thread-specific data. */
545 struct ovsthread_key {
546     struct list list_node;      /* In 'inuse_keys' or 'free_keys'. */
547     void (*destructor)(void *); /* Called at thread exit. */
548
549     /* Indexes into the per-thread array in struct ovsthread_key_slots.
550      * This key's data is stored in p1[index / L2_SIZE][index % L2_SIZE]. */
551     unsigned int index;
552 };
553
554 /* Per-thread data structure. */
555 struct ovsthread_key_slots {
556     struct list list_node;      /* In 'slots_list'. */
557     void **p1[L1_SIZE];
558 };
559
560 /* Contains "struct ovsthread_key_slots *". */
561 static pthread_key_t tsd_key;
562
563 /* Guards data structures below. */
564 static struct ovs_mutex key_mutex = OVS_MUTEX_INITIALIZER;
565
566 /* 'inuse_keys' holds "struct ovsthread_key"s that have been created and not
567  * yet destroyed.
568  *
569  * 'free_keys' holds "struct ovsthread_key"s that have been deleted and are
570  * ready for reuse.  (We keep them around only to be able to easily locate
571  * free indexes.)
572  *
573  * Together, 'inuse_keys' and 'free_keys' hold an ovsthread_key for every index
574  * from 0 to n_keys - 1, inclusive. */
575 static struct list inuse_keys OVS_GUARDED_BY(key_mutex)
576     = LIST_INITIALIZER(&inuse_keys);
577 static struct list free_keys OVS_GUARDED_BY(key_mutex)
578     = LIST_INITIALIZER(&free_keys);
579 static unsigned int n_keys OVS_GUARDED_BY(key_mutex);
580
581 /* All existing struct ovsthread_key_slots. */
582 static struct list slots_list OVS_GUARDED_BY(key_mutex)
583     = LIST_INITIALIZER(&slots_list);
584
585 static void *
586 clear_slot(struct ovsthread_key_slots *slots, unsigned int index)
587 {
588     void **p2 = slots->p1[index / L2_SIZE];
589     if (p2) {
590         void **valuep = &p2[index % L2_SIZE];
591         void *value = *valuep;
592         *valuep = NULL;
593         return value;
594     } else {
595         return NULL;
596     }
597 }
598
599 static void
600 ovsthread_key_destruct__(void *slots_)
601 {
602     struct ovsthread_key_slots *slots = slots_;
603     struct ovsthread_key *key;
604     unsigned int n;
605     int i;
606
607     ovs_mutex_lock(&key_mutex);
608     list_remove(&slots->list_node);
609     LIST_FOR_EACH (key, list_node, &inuse_keys) {
610         void *value = clear_slot(slots, key->index);
611         if (value && key->destructor) {
612             key->destructor(value);
613         }
614     }
615     n = n_keys;
616     ovs_mutex_unlock(&key_mutex);
617
618     for (i = 0; i < n / L2_SIZE; i++) {
619         free(slots->p1[i]);
620     }
621     free(slots);
622 }
623
624 /* Initializes '*keyp' as a thread-specific data key.  The data items are
625  * initially null in all threads.
626  *
627  * If a thread exits with non-null data, then 'destructor', if nonnull, will be
628  * called passing the final data value as its argument.  'destructor' must not
629  * call any thread-specific data functions in this API.
630  *
631  * This function is similar to xpthread_key_create(). */
632 void
633 ovsthread_key_create(ovsthread_key_t *keyp, void (*destructor)(void *))
634 {
635     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
636     struct ovsthread_key *key;
637
638     if (ovsthread_once_start(&once)) {
639         xpthread_key_create(&tsd_key, ovsthread_key_destruct__);
640         ovsthread_once_done(&once);
641     }
642
643     ovs_mutex_lock(&key_mutex);
644     if (list_is_empty(&free_keys)) {
645         key = xmalloc(sizeof *key);
646         key->index = n_keys++;
647         if (key->index >= MAX_KEYS) {
648             abort();
649         }
650     } else {
651         key = CONTAINER_OF(list_pop_back(&free_keys),
652                             struct ovsthread_key, list_node);
653     }
654     list_push_back(&inuse_keys, &key->list_node);
655     key->destructor = destructor;
656     ovs_mutex_unlock(&key_mutex);
657
658     *keyp = key;
659 }
660
661 /* Frees 'key'.  The destructor supplied to ovsthread_key_create(), if any, is
662  * not called.
663  *
664  * This function is similar to xpthread_key_delete(). */
665 void
666 ovsthread_key_delete(ovsthread_key_t key)
667 {
668     struct ovsthread_key_slots *slots;
669
670     ovs_mutex_lock(&key_mutex);
671
672     /* Move 'key' from 'inuse_keys' to 'free_keys'. */
673     list_remove(&key->list_node);
674     list_push_back(&free_keys, &key->list_node);
675
676     /* Clear this slot in all threads. */
677     LIST_FOR_EACH (slots, list_node, &slots_list) {
678         clear_slot(slots, key->index);
679     }
680
681     ovs_mutex_unlock(&key_mutex);
682 }
683
684 static void **
685 ovsthread_key_lookup__(const struct ovsthread_key *key)
686 {
687     struct ovsthread_key_slots *slots;
688     void **p2;
689
690     slots = pthread_getspecific(tsd_key);
691     if (!slots) {
692         slots = xzalloc(sizeof *slots);
693
694         ovs_mutex_lock(&key_mutex);
695         pthread_setspecific(tsd_key, slots);
696         list_push_back(&slots_list, &slots->list_node);
697         ovs_mutex_unlock(&key_mutex);
698     }
699
700     p2 = slots->p1[key->index / L2_SIZE];
701     if (!p2) {
702         p2 = xzalloc(L2_SIZE * sizeof *p2);
703         slots->p1[key->index / L2_SIZE] = p2;
704     }
705
706     return &p2[key->index % L2_SIZE];
707 }
708
709 /* Sets the value of thread-specific data item 'key', in the current thread, to
710  * 'value'.
711  *
712  * This function is similar to pthread_setspecific(). */
713 void
714 ovsthread_setspecific(ovsthread_key_t key, const void *value)
715 {
716     *ovsthread_key_lookup__(key) = CONST_CAST(void *, value);
717 }
718
719 /* Returns the value of thread-specific data item 'key' in the current thread.
720  *
721  * This function is similar to pthread_getspecific(). */
722 void *
723 ovsthread_getspecific(ovsthread_key_t key)
724 {
725     return *ovsthread_key_lookup__(key);
726 }
727 #endif