All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tal Shnaiderman <talshn@nvidia.com>
To: dev@dpdk.org
Cc: thomas@monjalon.net, pallavi.kadam@intel.com,
	dmitry.kozliuk@gmail.com, navasile@linux.microsoft.com,
	dmitrym@microsoft.com, david.marchand@redhat.com
Subject: [dpdk-dev] [PATCH v3] eal: add generic thread-local-storage functions
Date: Thu, 17 Dec 2020 19:49:13 +0200	[thread overview]
Message-ID: <20201217174913.14280-1-talshn@nvidia.com> (raw)
In-Reply-To: <20201213202437.12880-1-talshn@nvidia.com>

Add support for tls functionality in EAL.

The following functions are added:
rte_tls_create_key - function to create a tls data key.
rte_tls_delete_key - function to delete a tls data key.
rte_tls_set_thread_value - function to set value bound to the tls key
rte_tls_get_thread_value - function to get value bound to the tls key

tls key will be defied by the new type rte_tls_key_t

Signed-off-by: Tal Shnaiderman <talshn@nvidia.com>
---
v3: switch from pthread shim to generic eal implementation [DmitryK]
---
 lib/librte_eal/include/meson.build |  1 +
 lib/librte_eal/include/rte_tls.h   | 88 ++++++++++++++++++++++++++++++++++++++
 lib/librte_eal/rte_eal_exports.def |  5 +++
 lib/librte_eal/unix/eal_unix_tls.c | 79 ++++++++++++++++++++++++++++++++++
 lib/librte_eal/unix/meson.build    |  1 +
 lib/librte_eal/version.map         |  6 +++
 lib/librte_eal/windows/eal_tls.c   | 72 +++++++++++++++++++++++++++++++
 lib/librte_eal/windows/meson.build |  1 +
 8 files changed, 253 insertions(+)
 create mode 100644 lib/librte_eal/include/rte_tls.h
 create mode 100644 lib/librte_eal/unix/eal_unix_tls.c
 create mode 100644 lib/librte_eal/windows/eal_tls.c

diff --git a/lib/librte_eal/include/meson.build b/lib/librte_eal/include/meson.build
index dc007084ff..a307137242 100644
--- a/lib/librte_eal/include/meson.build
+++ b/lib/librte_eal/include/meson.build
@@ -41,6 +41,7 @@ headers += files(
 	'rte_string_fns.h',
 	'rte_tailq.h',
 	'rte_time.h',
+	'rte_tls.h',
 	'rte_trace.h',
 	'rte_trace_point.h',
 	'rte_trace_point_register.h',
diff --git a/lib/librte_eal/include/rte_tls.h b/lib/librte_eal/include/rte_tls.h
new file mode 100644
index 0000000000..3f84c683bc
--- /dev/null
+++ b/lib/librte_eal/include/rte_tls.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Mellanox Technologies, Ltd
+ */
+
+#include <rte_compat.h>
+
+#ifndef _RTE_TLS_H_
+#define _RTE_TLS_H_
+
+/**
+ * @file
+ *
+ * TLS functions
+ *
+ * Simple TLS functionality supplied by eal.
+ */
+
+/**
+ * Opaque pointer for tls key.
+ */
+typedef struct eal_tls_key *rte_tls_key_t;
+
+/**
+ * Function to create a tls data key visible to all threads in the process
+ * function need to be called once to create a key usable by all threads.
+ * rte_tls_key_t is an opaque pointer used to store the allocated key.
+ * and optional destructor can be set to be called when a thread expires.
+ *
+ * @param key
+ *   The rte_tls_key_t will cantain the allocated key
+ * @param destructor
+ *   The function to be called when the thread expires
+ *   Not supported on Windows OS.
+ *
+ * @return
+ *   On success, zero.
+ *   On failure, a negative error number -ENOMEM or -ENOEXEC
+ */
+__rte_experimental
+int
+rte_tls_create_key(rte_tls_key_t *key, void (*destructor)(void *));
+
+/**
+ * Function to delete a tls data key visible to all threads in the process
+ * rte_tls_key_t is an opaque pointer used to allocated the key.
+ *
+ * @param key
+ *   The rte_tls_key_t will cantain the allocated key
+ *
+ * @return
+ *   On success, zero.
+ *   On failure, a negative error number -ENOMEM or -ENOEXEC
+ */
+__rte_experimental
+int
+rte_tls_delete_key(rte_tls_key_t key);
+
+/**
+ * Function to set value bound to the tls key on behalf of the calling thread
+ *
+ * @param key
+ *   The rte_tls_key_t key
+ * @param value
+ *   The value bound to the rte_tls_key_t key for the calling thread.
+ *
+ * @return
+ *   On success, zero.
+ *   On failure, a negative error number -ENOMEM or -ENOEXEC
+ */
+__rte_experimental
+int
+rte_tls_set_thread_value(rte_tls_key_t key, const void *value);
+
+/**
+ * Function to get value bound to the tls key on behalf of the calling thread
+ *
+ * @param key
+ *   The rte_tls_key_t key
+ *
+ * @return
+ *   On success, value data pointer.
+ *   On failure, a negative error number is set in rte_errno.
+ */
+__rte_experimental
+void *
+rte_tls_get_thread_value(rte_tls_key_t key);
+
+#endif /* _RTE_TLS_H_ */
diff --git a/lib/librte_eal/rte_eal_exports.def b/lib/librte_eal/rte_eal_exports.def
index 6a6be1cfa6..2d5078eb76 100644
--- a/lib/librte_eal/rte_eal_exports.def
+++ b/lib/librte_eal/rte_eal_exports.def
@@ -306,6 +306,11 @@ EXPORTS
 	rte_vect_get_max_simd_bitwidth
 	rte_vect_set_max_simd_bitwidth
 
+	rte_tls_create_key
+	rte_tls_delete_key
+	rte_tls_set_thread_value
+	rte_tls_get_thread_value
+
 	rte_mem_lock
 	rte_mem_map
 	rte_mem_page_size
diff --git a/lib/librte_eal/unix/eal_unix_tls.c b/lib/librte_eal/unix/eal_unix_tls.c
new file mode 100644
index 0000000000..8b99f8d701
--- /dev/null
+++ b/lib/librte_eal/unix/eal_unix_tls.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2020 Mellanox Technologies, Ltd
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_log.h>
+#include <rte_tls.h>
+
+struct eal_tls_key {
+	pthread_key_t thread_index;
+};
+
+int
+rte_tls_create_key(rte_tls_key_t *key, void (*destructor)(void *))
+{
+	int err;
+
+	*key = malloc(sizeof(struct eal_tls_key));
+	if ((*key) == NULL) {
+		RTE_LOG(DEBUG, EAL, "Cannot allocate tls key.");
+		return -ENOMEM;
+	}
+	err = pthread_key_create(&((*key)->thread_index), destructor);
+	if (err) {
+		RTE_LOG(DEBUG, EAL, "pthread_key_create failed: %s\n",
+			 rte_strerror(err));
+		free(*key);
+		return -ENOEXEC;
+	}
+	return 0;
+}
+
+int
+rte_tls_delete_key(rte_tls_key_t key)
+{
+	int err;
+
+	if (!key)
+		return -EINVAL;
+	err = pthread_key_delete(key->thread_index);
+	if (err) {
+		RTE_LOG(DEBUG, EAL, "pthread_key_delete failed: %s\n",
+			 rte_strerror(err));
+		free(key);
+		return -ENOEXEC;
+	}
+	free(key);
+	return 0;
+}
+
+int
+rte_tls_set_thread_value(rte_tls_key_t key, const void *value)
+{
+	int err;
+
+	if (!key)
+		return -EINVAL;
+	err = pthread_setspecific(key->thread_index, value);
+	if (err) {
+		RTE_LOG(DEBUG, EAL, "pthread_setspecific failed: %s\n",
+			 rte_strerror(err));
+		free(key);
+		return -ENOEXEC;
+	}
+	return 0;
+}
+
+void *
+rte_tls_get_thread_value(rte_tls_key_t key)
+{
+	if (!key)
+		rte_errno = EINVAL;
+	return pthread_getspecific(key->thread_index);
+}
diff --git a/lib/librte_eal/unix/meson.build b/lib/librte_eal/unix/meson.build
index d3af6b6fe2..74596a8817 100644
--- a/lib/librte_eal/unix/meson.build
+++ b/lib/librte_eal/unix/meson.build
@@ -5,4 +5,5 @@ sources += files(
 	'eal_file.c',
 	'eal_unix_memory.c',
 	'eal_unix_timer.c',
+	'eal_unix_tls.c',
 )
diff --git a/lib/librte_eal/version.map b/lib/librte_eal/version.map
index 354c068f31..3ec95d4cbb 100644
--- a/lib/librte_eal/version.map
+++ b/lib/librte_eal/version.map
@@ -403,6 +403,12 @@ EXPERIMENTAL {
 	rte_service_lcore_may_be_active;
 	rte_vect_get_max_simd_bitwidth;
 	rte_vect_set_max_simd_bitwidth;
+
+	# added in 21.02
+	rte_tls_create_key;
+	rte_tls_delete_key;
+	rte_tls_set_thread_value;
+	rte_tls_get_thread_value;
 };
 
 INTERNAL {
diff --git a/lib/librte_eal/windows/eal_tls.c b/lib/librte_eal/windows/eal_tls.c
new file mode 100644
index 0000000000..73fb17ef6d
--- /dev/null
+++ b/lib/librte_eal/windows/eal_tls.c
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2020 Mellanox Technologies, Ltd
+ */
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_tls.h>
+#include <rte_windows.h>
+
+struct eal_tls_key {
+	DWORD thread_index;
+};
+
+int
+rte_tls_create_key(rte_tls_key_t *key,
+		__rte_unused void (*destructor)(void *))
+{
+	*key = malloc(sizeof(struct eal_tls_key));
+	if ((*key) == NULL) {
+		RTE_LOG(DEBUG, EAL, "Cannot allocate tls key.");
+		return -ENOMEM;
+	}
+	(*key)->thread_index = TlsAlloc();
+	if ((*key)->thread_index == TLS_OUT_OF_INDEXES) {
+		RTE_LOG_WIN32_ERR("TlsAlloc()");
+		free(*key);
+		return -ENOEXEC;
+	}
+	return 0;
+}
+
+int
+rte_tls_delete_key(rte_tls_key_t key)
+{
+	if (!key)
+		return -EINVAL;
+	if (!TlsFree(key->thread_index)) {
+		RTE_LOG_WIN32_ERR("TlsFree()");
+		free(key);
+		return -ENOEXEC;
+	}
+	free(key);
+	return 0;
+}
+
+int
+rte_tls_set_thread_value(rte_tls_key_t key, const void *value)
+{
+	if (!key)
+		return -EINVAL;
+	/* discard const qualifier */
+	char *p = (char *) (uintptr_t) value;
+
+	if (!TlsSetValue(key->thread_index, p)) {
+		RTE_LOG_WIN32_ERR("TlsSetValue()");
+		return -ENOEXEC;
+	}
+	return 0;
+}
+
+void *
+rte_tls_get_thread_value(rte_tls_key_t key)
+{
+	if (!key)
+		rte_errno = EINVAL;
+	void *output = TlsGetValue(key->thread_index);
+	if (GetLastError() != ERROR_SUCCESS) {
+		RTE_LOG_WIN32_ERR("TlsGetValue()");
+		rte_errno = ENOEXEC;
+		return NULL;
+	}
+	return output;
+}
diff --git a/lib/librte_eal/windows/meson.build b/lib/librte_eal/windows/meson.build
index 3b2faf29eb..38f51f8967 100644
--- a/lib/librte_eal/windows/meson.build
+++ b/lib/librte_eal/windows/meson.build
@@ -17,6 +17,7 @@ sources += files(
 	'eal_mp.c',
 	'eal_thread.c',
 	'eal_timer.c',
+	'eal_tls.c',
 	'fnmatch.c',
 	'getopt.c',
 )
-- 
2.16.1.windows.4


  parent reply	other threads:[~2020-12-17 17:49 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-13 20:24 [dpdk-dev] [PATCH v2] eal/windows: add pthread TLS function support Tal Shnaiderman
2020-12-15 22:36 ` Dmitry Kozlyuk
2020-12-17 17:49 ` Tal Shnaiderman [this message]
2020-12-17 20:56   ` [dpdk-dev] [PATCH v3] eal: add generic thread-local-storage functions Dmitry Kozlyuk
2020-12-18 19:37     ` Tal Shnaiderman
2020-12-22  7:30   ` [dpdk-dev] [PATCH v4] " Tal Shnaiderman
2020-12-23  1:18     ` Dmitry Kozlyuk
2020-12-23 11:44       ` Tal Shnaiderman
2020-12-23 11:58         ` Dmitry Kozlyuk
2020-12-23 18:16           ` [dpdk-dev] [EXTERNAL] " Dmitry Malloy (MESHCHANINOV)
2020-12-26 16:08     ` [dpdk-dev] [PATCH v5] " Tal Shnaiderman
2020-12-29 23:13       ` Dmitry Kozlyuk
2020-12-30 10:04         ` Tal Shnaiderman
2020-12-30 11:12       ` [dpdk-dev] [PATCH v6] " Tal Shnaiderman
2021-01-01 22:16         ` Dmitry Kozlyuk
2021-01-05 11:53         ` Thomas Monjalon
2021-01-05 17:06       ` [dpdk-dev] [PATCH v7 0/2] support generic threading functions Tal Shnaiderman
2021-01-05 17:06         ` [dpdk-dev] [PATCH v7 1/2] eal: move thread affinity functions to new file Tal Shnaiderman
2021-01-06 14:40           ` Dmitry Kozlyuk
2021-01-06 19:45           ` [dpdk-dev] [PATCH v8 0/2] support generic threading functions Tal Shnaiderman
2021-01-06 19:45             ` [dpdk-dev] [PATCH v8 1/2] eal: move thread affinity functions to new file Tal Shnaiderman
2021-01-06 19:45             ` [dpdk-dev] [PATCH v8 2/2] eal: add generic thread-local-storage functions Tal Shnaiderman
2021-01-06 20:10               ` Dmitry Kozlyuk
2021-01-06 20:33                 ` Tal Shnaiderman
2021-01-06 20:35             ` [dpdk-dev] [PATCH v9 0/2] support generic threading functions Tal Shnaiderman
2021-01-06 20:35               ` [dpdk-dev] [PATCH v9 1/2] eal: move thread affinity functions to new file Tal Shnaiderman
2021-01-06 20:35               ` [dpdk-dev] [PATCH v9 2/2] eal: add generic thread-local-storage functions Tal Shnaiderman
2021-01-07 14:46                 ` Dmitry Kozlyuk
2021-02-10 13:33                 ` Burakov, Anatoly
2021-02-10 14:26                   ` Medvedkin, Vladimir
2021-02-11  7:34                     ` Tal Shnaiderman
2021-02-11  7:26                   ` Tal Shnaiderman
2021-01-11 22:33               ` [dpdk-dev] [PATCH v9 0/2] support generic threading functions Thomas Monjalon
2021-01-05 17:06         ` [dpdk-dev] [PATCH v7 2/2] eal: add generic thread-local-storage functions Tal Shnaiderman
2021-01-06 15:05           ` Dmitry Kozlyuk
2021-01-06 16:04             ` Tal Shnaiderman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201217174913.14280-1-talshn@nvidia.com \
    --to=talshn@nvidia.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=dmitry.kozliuk@gmail.com \
    --cc=dmitrym@microsoft.com \
    --cc=navasile@linux.microsoft.com \
    --cc=pallavi.kadam@intel.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.