xref: /dpdk/lib/eal/unix/rte_thread.c (revision 56539289b8719213008d9309dcdc4888fa342410)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright 2021 Mellanox Technologies, Ltd
3*56539289STyler Retzlaff  * Copyright (C) 2022 Microsoft Corporation
499a2dd95SBruce Richardson  */
599a2dd95SBruce Richardson 
699a2dd95SBruce Richardson #include <errno.h>
799a2dd95SBruce Richardson #include <pthread.h>
899a2dd95SBruce Richardson #include <stdlib.h>
999a2dd95SBruce Richardson #include <string.h>
1099a2dd95SBruce Richardson 
1199a2dd95SBruce Richardson #include <rte_errno.h>
1299a2dd95SBruce Richardson #include <rte_log.h>
1399a2dd95SBruce Richardson #include <rte_thread.h>
1499a2dd95SBruce Richardson 
1599a2dd95SBruce Richardson struct eal_tls_key {
1699a2dd95SBruce Richardson 	pthread_key_t thread_index;
1799a2dd95SBruce Richardson };
1899a2dd95SBruce Richardson 
19*56539289STyler Retzlaff rte_thread_t
20*56539289STyler Retzlaff rte_thread_self(void)
21*56539289STyler Retzlaff {
22*56539289STyler Retzlaff 	RTE_BUILD_BUG_ON(sizeof(pthread_t) > sizeof(uintptr_t));
23*56539289STyler Retzlaff 
24*56539289STyler Retzlaff 	rte_thread_t thread_id;
25*56539289STyler Retzlaff 
26*56539289STyler Retzlaff 	thread_id.opaque_id = (uintptr_t)pthread_self();
27*56539289STyler Retzlaff 
28*56539289STyler Retzlaff 	return thread_id;
29*56539289STyler Retzlaff }
30*56539289STyler Retzlaff 
3199a2dd95SBruce Richardson int
3299a2dd95SBruce Richardson rte_thread_key_create(rte_thread_key *key, void (*destructor)(void *))
3399a2dd95SBruce Richardson {
3499a2dd95SBruce Richardson 	int err;
3599a2dd95SBruce Richardson 
3699a2dd95SBruce Richardson 	*key = malloc(sizeof(**key));
3799a2dd95SBruce Richardson 	if ((*key) == NULL) {
3899a2dd95SBruce Richardson 		RTE_LOG(DEBUG, EAL, "Cannot allocate TLS key.\n");
3999a2dd95SBruce Richardson 		rte_errno = ENOMEM;
4099a2dd95SBruce Richardson 		return -1;
4199a2dd95SBruce Richardson 	}
4299a2dd95SBruce Richardson 	err = pthread_key_create(&((*key)->thread_index), destructor);
4399a2dd95SBruce Richardson 	if (err) {
4499a2dd95SBruce Richardson 		RTE_LOG(DEBUG, EAL, "pthread_key_create failed: %s\n",
4599a2dd95SBruce Richardson 			 strerror(err));
4699a2dd95SBruce Richardson 		free(*key);
4799a2dd95SBruce Richardson 		rte_errno = ENOEXEC;
4899a2dd95SBruce Richardson 		return -1;
4999a2dd95SBruce Richardson 	}
5099a2dd95SBruce Richardson 	return 0;
5199a2dd95SBruce Richardson }
5299a2dd95SBruce Richardson 
5399a2dd95SBruce Richardson int
5499a2dd95SBruce Richardson rte_thread_key_delete(rte_thread_key key)
5599a2dd95SBruce Richardson {
5699a2dd95SBruce Richardson 	int err;
5799a2dd95SBruce Richardson 
5899a2dd95SBruce Richardson 	if (!key) {
5999a2dd95SBruce Richardson 		RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
6099a2dd95SBruce Richardson 		rte_errno = EINVAL;
6199a2dd95SBruce Richardson 		return -1;
6299a2dd95SBruce Richardson 	}
6399a2dd95SBruce Richardson 	err = pthread_key_delete(key->thread_index);
6499a2dd95SBruce Richardson 	if (err) {
6599a2dd95SBruce Richardson 		RTE_LOG(DEBUG, EAL, "pthread_key_delete failed: %s\n",
6699a2dd95SBruce Richardson 			 strerror(err));
6799a2dd95SBruce Richardson 		free(key);
6899a2dd95SBruce Richardson 		rte_errno = ENOEXEC;
6999a2dd95SBruce Richardson 		return -1;
7099a2dd95SBruce Richardson 	}
7199a2dd95SBruce Richardson 	free(key);
7299a2dd95SBruce Richardson 	return 0;
7399a2dd95SBruce Richardson }
7499a2dd95SBruce Richardson 
7599a2dd95SBruce Richardson int
7699a2dd95SBruce Richardson rte_thread_value_set(rte_thread_key key, const void *value)
7799a2dd95SBruce Richardson {
7899a2dd95SBruce Richardson 	int err;
7999a2dd95SBruce Richardson 
8099a2dd95SBruce Richardson 	if (!key) {
8199a2dd95SBruce Richardson 		RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
8299a2dd95SBruce Richardson 		rte_errno = EINVAL;
8399a2dd95SBruce Richardson 		return -1;
8499a2dd95SBruce Richardson 	}
8599a2dd95SBruce Richardson 	err = pthread_setspecific(key->thread_index, value);
8699a2dd95SBruce Richardson 	if (err) {
8799a2dd95SBruce Richardson 		RTE_LOG(DEBUG, EAL, "pthread_setspecific failed: %s\n",
8899a2dd95SBruce Richardson 			strerror(err));
8999a2dd95SBruce Richardson 		rte_errno = ENOEXEC;
9099a2dd95SBruce Richardson 		return -1;
9199a2dd95SBruce Richardson 	}
9299a2dd95SBruce Richardson 	return 0;
9399a2dd95SBruce Richardson }
9499a2dd95SBruce Richardson 
9599a2dd95SBruce Richardson void *
9699a2dd95SBruce Richardson rte_thread_value_get(rte_thread_key key)
9799a2dd95SBruce Richardson {
9899a2dd95SBruce Richardson 	if (!key) {
9999a2dd95SBruce Richardson 		RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
10099a2dd95SBruce Richardson 		rte_errno = EINVAL;
10199a2dd95SBruce Richardson 		return NULL;
10299a2dd95SBruce Richardson 	}
10399a2dd95SBruce Richardson 	return pthread_getspecific(key->thread_index);
10499a2dd95SBruce Richardson }
105