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