1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2021 Mellanox Technologies, Ltd
3 * Copyright (C) 2022 Microsoft Corporation
4 */
5
6 #include <errno.h>
7 #include <pthread.h>
8 #include <stdlib.h>
9 #include <string.h>
10
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 rte_thread_t
rte_thread_self(void)20 rte_thread_self(void)
21 {
22 RTE_BUILD_BUG_ON(sizeof(pthread_t) > sizeof(uintptr_t));
23
24 rte_thread_t thread_id;
25
26 thread_id.opaque_id = (uintptr_t)pthread_self();
27
28 return thread_id;
29 }
30
31 int
rte_thread_key_create(rte_thread_key * key,void (* destructor)(void *))32 rte_thread_key_create(rte_thread_key *key, void (*destructor)(void *))
33 {
34 int err;
35
36 *key = malloc(sizeof(**key));
37 if ((*key) == NULL) {
38 RTE_LOG(DEBUG, EAL, "Cannot allocate TLS key.\n");
39 rte_errno = ENOMEM;
40 return -1;
41 }
42 err = pthread_key_create(&((*key)->thread_index), destructor);
43 if (err) {
44 RTE_LOG(DEBUG, EAL, "pthread_key_create failed: %s\n",
45 strerror(err));
46 free(*key);
47 rte_errno = ENOEXEC;
48 return -1;
49 }
50 return 0;
51 }
52
53 int
rte_thread_key_delete(rte_thread_key key)54 rte_thread_key_delete(rte_thread_key key)
55 {
56 int err;
57
58 if (!key) {
59 RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
60 rte_errno = EINVAL;
61 return -1;
62 }
63 err = pthread_key_delete(key->thread_index);
64 if (err) {
65 RTE_LOG(DEBUG, EAL, "pthread_key_delete failed: %s\n",
66 strerror(err));
67 free(key);
68 rte_errno = ENOEXEC;
69 return -1;
70 }
71 free(key);
72 return 0;
73 }
74
75 int
rte_thread_value_set(rte_thread_key key,const void * value)76 rte_thread_value_set(rte_thread_key key, const void *value)
77 {
78 int err;
79
80 if (!key) {
81 RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
82 rte_errno = EINVAL;
83 return -1;
84 }
85 err = pthread_setspecific(key->thread_index, value);
86 if (err) {
87 RTE_LOG(DEBUG, EAL, "pthread_setspecific failed: %s\n",
88 strerror(err));
89 rte_errno = ENOEXEC;
90 return -1;
91 }
92 return 0;
93 }
94
95 void *
rte_thread_value_get(rte_thread_key key)96 rte_thread_value_get(rte_thread_key key)
97 {
98 if (!key) {
99 RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
100 rte_errno = EINVAL;
101 return NULL;
102 }
103 return pthread_getspecific(key->thread_index);
104 }
105
106 int
rte_thread_set_affinity_by_id(rte_thread_t thread_id,const rte_cpuset_t * cpuset)107 rte_thread_set_affinity_by_id(rte_thread_t thread_id,
108 const rte_cpuset_t *cpuset)
109 {
110 return pthread_setaffinity_np((pthread_t)thread_id.opaque_id,
111 sizeof(*cpuset), cpuset);
112 }
113
114 int
rte_thread_get_affinity_by_id(rte_thread_t thread_id,rte_cpuset_t * cpuset)115 rte_thread_get_affinity_by_id(rte_thread_t thread_id,
116 rte_cpuset_t *cpuset)
117 {
118 return pthread_getaffinity_np((pthread_t)thread_id.opaque_id,
119 sizeof(*cpuset), cpuset);
120 }
121