eal: add generic thread-local-storage functions
[dpdk.git] / lib / librte_eal / unix / rte_thread.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2021 Mellanox Technologies, Ltd
3  */
4
5 #include <errno.h>
6 #include <pthread.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include <rte_common.h>
11 #include <rte_errno.h>
12 #include <rte_log.h>
13 #include <rte_thread.h>
14
15 struct eal_tls_key {
16         pthread_key_t thread_index;
17 };
18
19 int
20 rte_thread_tls_key_create(rte_tls_key *key, void (*destructor)(void *))
21 {
22         int err;
23
24         *key = malloc(sizeof(**key));
25         if ((*key) == NULL) {
26                 RTE_LOG(DEBUG, EAL, "Cannot allocate TLS key.\n");
27                 return -1;
28         }
29         err = pthread_key_create(&((*key)->thread_index), destructor);
30         if (err) {
31                 RTE_LOG(DEBUG, EAL, "pthread_key_create failed: %s\n",
32                          strerror(err));
33                 free(*key);
34                 return -1;
35         }
36         return 0;
37 }
38
39 int
40 rte_thread_tls_key_delete(rte_tls_key key)
41 {
42         int err;
43
44         if (!key) {
45                 RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
46                 return -1;
47         }
48         err = pthread_key_delete(key->thread_index);
49         if (err) {
50                 RTE_LOG(DEBUG, EAL, "pthread_key_delete failed: %s\n",
51                          strerror(err));
52                 free(key);
53                 return -1;
54         }
55         free(key);
56         return 0;
57 }
58
59 int
60 rte_thread_tls_value_set(rte_tls_key key, const void *value)
61 {
62         int err;
63
64         if (!key) {
65                 RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
66                 return -1;
67         }
68         err = pthread_setspecific(key->thread_index, value);
69         if (err) {
70                 RTE_LOG(DEBUG, EAL, "pthread_setspecific failed: %s\n",
71                         strerror(err));
72                 return -1;
73         }
74         return 0;
75 }
76
77 void *
78 rte_thread_tls_value_get(rte_tls_key key)
79 {
80         if (!key) {
81                 RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
82                 rte_errno = EINVAL;
83                 return NULL;
84         }
85         return pthread_getspecific(key->thread_index);
86 }