xref: /dpdk/lib/eal/unix/rte_thread.c (revision b70a9b7886254253ac1916d946029464fffd6e05)
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
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
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
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
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 *
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
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
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