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