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