get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/86075/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 86075,
    "url": "http://patchwork.dpdk.org/api/patches/86075/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20210106203553.9876-3-talshn@nvidia.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20210106203553.9876-3-talshn@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210106203553.9876-3-talshn@nvidia.com",
    "date": "2021-01-06T20:35:53",
    "name": "[v9,2/2] eal: add generic thread-local-storage functions",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "ac6f2c71ea8218e9c1132ebaa18a1ea66d942c35",
    "submitter": {
        "id": 1893,
        "url": "http://patchwork.dpdk.org/api/people/1893/?format=api",
        "name": "Tal Shnaiderman",
        "email": "talshn@nvidia.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20210106203553.9876-3-talshn@nvidia.com/mbox/",
    "series": [
        {
            "id": 14562,
            "url": "http://patchwork.dpdk.org/api/series/14562/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=14562",
            "date": "2021-01-06T20:35:52",
            "name": "support generic threading functions",
            "version": 9,
            "mbox": "http://patchwork.dpdk.org/series/14562/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/86075/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/86075/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (xvm-189-124.dc0.ghst.net [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 4569FA09FF;\n\tWed,  6 Jan 2021 21:36:29 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 0CB4A140E49;\n\tWed,  6 Jan 2021 21:36:25 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by mails.dpdk.org (Postfix) with ESMTP id 1D52B140E31\n for <dev@dpdk.org>; Wed,  6 Jan 2021 21:36:22 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n talshn@nvidia.com) with SMTP; 6 Jan 2021 22:36:20 +0200",
            "from nvidia.com (l-wincomp04-vm.mtl.labs.mlnx [10.237.1.5])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 106KaKmv026677;\n Wed, 6 Jan 2021 22:36:20 +0200"
        ],
        "From": "Tal Shnaiderman <talshn@nvidia.com>",
        "To": "dev@dpdk.org",
        "Cc": "thomas@monjalon.net, pallavi.kadam@intel.com, dmitry.kozliuk@gmail.com,\n navasile@linux.microsoft.com, dmitrym@microsoft.com,\n david.marchand@redhat.com",
        "Date": "Wed,  6 Jan 2021 22:35:53 +0200",
        "Message-Id": "<20210106203553.9876-3-talshn@nvidia.com>",
        "X-Mailer": "git-send-email 2.16.1.windows.4",
        "In-Reply-To": "<20210106203553.9876-1-talshn@nvidia.com>",
        "References": "<20210106194543.14024-1-talshn@nvidia.com>\n <20210106203553.9876-1-talshn@nvidia.com>",
        "Subject": "[dpdk-dev] [PATCH v9 2/2] eal: add generic thread-local-storage\n functions",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add support for TLS functionality in EAL.\n\nThe following functions are added:\nrte_thread_tls_key_create - create a TLS data key.\nrte_thread_tls_key_delete - delete a TLS data key.\nrte_thread_tls_value_set - set value bound to the TLS key\nrte_thread_tls_value_get - get value bound to the TLS key\n\nTLS key is defined by the new type rte_tls_key.\n\nThe API allocates the thread local storage (TLS) key.\nAny thread of the process can subsequently use this key\nto store and retrieve values that are local to the thread.\n\nThose functions are added in addition to TLS capability\nin rte_per_lcore.h to allow abstraction of the pthread\nlayer for all operating systems.\n\nWindows implementation is under librte_eal/windows and\nimplemented using WIN32 API for Windows only.\n\nUnix implementation is under librte_eal/unix and\nimplemented using pthread for UNIX compilation.\n\nSigned-off-by: Tal Shnaiderman <talshn@nvidia.com>\n---\nv3: switch from pthread shim to generic eal implementation [DmitryK]\nv4: modify file names, function names, move unix code to common\nfor future external pthreads support [DmitryK]\nv5: rename var used for external pthreads, add description in\nmeson_options.txt. [DmitryK]\nv6: remove external_pthread support as it collide with pthread\nshim implementation [DmitryK]\nv7: move unix code to unix instead of common, rename functions\nadd more documentation [Thomas]\n---\n lib/librte_eal/include/rte_thread.h | 65 ++++++++++++++++++++++++++++\n lib/librte_eal/rte_eal_exports.def  |  5 +++\n lib/librte_eal/unix/meson.build     |  1 +\n lib/librte_eal/unix/rte_thread.c    | 86 +++++++++++++++++++++++++++++++++++++\n lib/librte_eal/version.map          |  6 +++\n lib/librte_eal/windows/meson.build  |  1 +\n lib/librte_eal/windows/rte_thread.c | 83 +++++++++++++++++++++++++++++++++++\n 7 files changed, 247 insertions(+)\n create mode 100644 lib/librte_eal/unix/rte_thread.c\n create mode 100644 lib/librte_eal/windows/rte_thread.c",
    "diff": "diff --git a/lib/librte_eal/include/rte_thread.h b/lib/librte_eal/include/rte_thread.h\nindex 43bf568d59..eca62b29ee 100644\n--- a/lib/librte_eal/include/rte_thread.h\n+++ b/lib/librte_eal/include/rte_thread.h\n@@ -19,6 +19,11 @@\n extern \"C\" {\n #endif\n \n+/**\n+ * TLS key type, an opaque pointer.\n+ */\n+typedef struct eal_tls_key *rte_tls_key;\n+\n /**\n  * Set core affinity of the current thread.\n  * Support both EAL and non-EAL thread and update TLS.\n@@ -40,6 +45,66 @@ int rte_thread_set_affinity(rte_cpuset_t *cpusetp);\n  */\n void rte_thread_get_affinity(rte_cpuset_t *cpusetp);\n \n+/**\n+ * Create a TLS data key visible to all threads in the process.\n+ * the created key is later used to get/set a value.\n+ * and optional destructor can be set to be called when a thread exits.\n+ *\n+ * @param key\n+ *   Pointer to store the allocated rte_tls_key\n+ * @param destructor\n+ *   The function to be called when the thread exits.\n+ *   Ignored on Windows OS.\n+ *\n+ * @return\n+ *   On success, zero.\n+ *   On failure, a negative number.\n+ */\n+\n+__rte_experimental\n+int rte_thread_tls_key_create(rte_tls_key *key, void (*destructor)(void *));\n+\n+/**\n+ * Delete a TLS data key visible to all threads in the process.\n+ *\n+ * @param key\n+ *   The rte_tls_key allocated by rte_thread_tls_key_create().\n+ *\n+ * @return\n+ *   On success, zero.\n+ *   On failure, a negative number.\n+ */\n+__rte_experimental\n+int rte_thread_tls_key_delete(rte_tls_key key);\n+\n+/**\n+ * Set value bound to the TLS key on behalf of the calling thread.\n+ *\n+ * @param key\n+ *   The rte_tls_key key allocated by rte_thread_tls_key_create.\n+ * @param value\n+ *   The value bound to the rte_tls_key key for the calling thread.\n+ *\n+ * @return\n+ *   On success, zero.\n+ *   On failure, a negative number.\n+ */\n+__rte_experimental\n+int rte_thread_tls_value_set(rte_tls_key key, const void *value);\n+\n+/**\n+ * Get value bound to the TLS key on behalf of the calling thread.\n+ *\n+ * @param key\n+ *   The rte_tls_key key allocated by rte_thread_tls_key_create.\n+ *\n+ * @return\n+ *   On success, value data pointer (can also be NULL).\n+ *   On failure, NULL and an error number is set in rte_errno.\n+ */\n+__rte_experimental\n+void *rte_thread_tls_value_get(rte_tls_key key);\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/librte_eal/rte_eal_exports.def b/lib/librte_eal/rte_eal_exports.def\nindex 6a6be1cfa6..a11b078ac6 100644\n--- a/lib/librte_eal/rte_eal_exports.def\n+++ b/lib/librte_eal/rte_eal_exports.def\n@@ -306,6 +306,11 @@ EXPORTS\n \trte_vect_get_max_simd_bitwidth\n \trte_vect_set_max_simd_bitwidth\n \n+\trte_thread_tls_key_create\n+\trte_thread_tls_key_delete\n+\trte_thread_tls_value_set\n+\trte_thread_tls_value_get\n+\n \trte_mem_lock\n \trte_mem_map\n \trte_mem_page_size\ndiff --git a/lib/librte_eal/unix/meson.build b/lib/librte_eal/unix/meson.build\nindex d3af6b6fe2..71221b84a4 100644\n--- a/lib/librte_eal/unix/meson.build\n+++ b/lib/librte_eal/unix/meson.build\n@@ -5,4 +5,5 @@ sources += files(\n \t'eal_file.c',\n \t'eal_unix_memory.c',\n \t'eal_unix_timer.c',\n+\t'rte_thread.c',\n )\ndiff --git a/lib/librte_eal/unix/rte_thread.c b/lib/librte_eal/unix/rte_thread.c\nnew file mode 100644\nindex 0000000000..ae58e1bf31\n--- /dev/null\n+++ b/lib/librte_eal/unix/rte_thread.c\n@@ -0,0 +1,86 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2021 Mellanox Technologies, Ltd\n+ */\n+\n+#include <errno.h>\n+#include <pthread.h>\n+#include <stdlib.h>\n+#include <string.h>\n+\n+#include <rte_common.h>\n+#include <rte_errno.h>\n+#include <rte_log.h>\n+#include <rte_thread.h>\n+\n+struct eal_tls_key {\n+\tpthread_key_t thread_index;\n+};\n+\n+int\n+rte_thread_tls_key_create(rte_tls_key *key, void (*destructor)(void *))\n+{\n+\tint err;\n+\n+\t*key = malloc(sizeof(**key));\n+\tif ((*key) == NULL) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Cannot allocate TLS key.\");\n+\t\treturn -1;\n+\t}\n+\terr = pthread_key_create(&((*key)->thread_index), destructor);\n+\tif (err) {\n+\t\tRTE_LOG(DEBUG, EAL, \"pthread_key_create failed: %s\\n\",\n+\t\t\t strerror(err));\n+\t\tfree(*key);\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+rte_thread_tls_key_delete(rte_tls_key key)\n+{\n+\tint err;\n+\n+\tif (!key) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid TLS key.\\n\");\n+\t\treturn -1;\n+\t}\n+\terr = pthread_key_delete(key->thread_index);\n+\tif (err) {\n+\t\tRTE_LOG(DEBUG, EAL, \"pthread_key_delete failed: %s\\n\",\n+\t\t\t strerror(err));\n+\t\tfree(key);\n+\t\treturn -1;\n+\t}\n+\tfree(key);\n+\treturn 0;\n+}\n+\n+int\n+rte_thread_tls_value_set(rte_tls_key key, const void *value)\n+{\n+\tint err;\n+\n+\tif (!key) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid TLS key.\\n\");\n+\t\treturn -1;\n+\t}\n+\terr = pthread_setspecific(key->thread_index, value);\n+\tif (err) {\n+\t\tRTE_LOG(DEBUG, EAL, \"pthread_setspecific failed: %s\\n\",\n+\t\t\tstrerror(err));\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+void *\n+rte_thread_tls_value_get(rte_tls_key key)\n+{\n+\tif (!key) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid TLS key.\\n\");\n+\t\trte_errno = EINVAL;\n+\t\treturn NULL;\n+\t}\n+\treturn pthread_getspecific(key->thread_index);\n+}\ndiff --git a/lib/librte_eal/version.map b/lib/librte_eal/version.map\nindex 354c068f31..272db0504a 100644\n--- a/lib/librte_eal/version.map\n+++ b/lib/librte_eal/version.map\n@@ -403,6 +403,12 @@ EXPERIMENTAL {\n \trte_service_lcore_may_be_active;\n \trte_vect_get_max_simd_bitwidth;\n \trte_vect_set_max_simd_bitwidth;\n+\n+\t# added in 21.02\n+\trte_thread_tls_key_create;\n+\trte_thread_tls_key_delete;\n+\trte_thread_tls_value_set;\n+\trte_thread_tls_value_get;\n };\n \n INTERNAL {\ndiff --git a/lib/librte_eal/windows/meson.build b/lib/librte_eal/windows/meson.build\nindex 3b2faf29eb..42ff5c2d59 100644\n--- a/lib/librte_eal/windows/meson.build\n+++ b/lib/librte_eal/windows/meson.build\n@@ -19,6 +19,7 @@ sources += files(\n \t'eal_timer.c',\n \t'fnmatch.c',\n \t'getopt.c',\n+\t'rte_thread.c',\n )\n \n dpdk_conf.set10('RTE_EAL_NUMA_AWARE_HUGEPAGES', true)\ndiff --git a/lib/librte_eal/windows/rte_thread.c b/lib/librte_eal/windows/rte_thread.c\nnew file mode 100644\nindex 0000000000..5cb3a91483\n--- /dev/null\n+++ b/lib/librte_eal/windows/rte_thread.c\n@@ -0,0 +1,83 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2021 Mellanox Technologies, Ltd\n+ */\n+\n+#include <rte_common.h>\n+#include <rte_errno.h>\n+#include <rte_thread.h>\n+#include <rte_windows.h>\n+\n+struct eal_tls_key {\n+\tDWORD thread_index;\n+};\n+\n+int\n+rte_thread_tls_key_create(rte_tls_key *key,\n+\t\t__rte_unused void (*destructor)(void *))\n+{\n+\t*key = malloc(sizeof(**key));\n+\tif ((*key) == NULL) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Cannot allocate TLS key.\");\n+\t\treturn -1;\n+\t}\n+\t(*key)->thread_index = TlsAlloc();\n+\tif ((*key)->thread_index == TLS_OUT_OF_INDEXES) {\n+\t\tRTE_LOG_WIN32_ERR(\"TlsAlloc()\");\n+\t\tfree(*key);\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+int\n+rte_thread_tls_key_delete(rte_tls_key key)\n+{\n+\tif (!key) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid TLS key.\\n\");\n+\t\treturn -1;\n+\t}\n+\tif (!TlsFree(key->thread_index)) {\n+\t\tRTE_LOG_WIN32_ERR(\"TlsFree()\");\n+\t\tfree(key);\n+\t\treturn -1;\n+\t}\n+\tfree(key);\n+\treturn 0;\n+}\n+\n+int\n+rte_thread_tls_value_set(rte_tls_key key, const void *value)\n+{\n+\tchar *p;\n+\n+\tif (!key) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid TLS key.\\n\");\n+\t\treturn -1;\n+\t}\n+\t/* discard const qualifier */\n+\tp = (char *) (uintptr_t) value;\n+\tif (!TlsSetValue(key->thread_index, p)) {\n+\t\tRTE_LOG_WIN32_ERR(\"TlsSetValue()\");\n+\t\treturn -1;\n+\t}\n+\treturn 0;\n+}\n+\n+void *\n+rte_thread_tls_value_get(rte_tls_key key)\n+{\n+\tvoid *output;\n+\n+\tif (!key) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Invalid TLS key.\\n\");\n+\t\trte_errno = EINVAL;\n+\t\treturn NULL;\n+\t}\n+\toutput = TlsGetValue(key->thread_index);\n+\tif (GetLastError() != ERROR_SUCCESS) {\n+\t\tRTE_LOG_WIN32_ERR(\"TlsGetValue()\");\n+\t\trte_errno = ENOEXEC;\n+\t\treturn NULL;\n+\t}\n+\treturn output;\n+}\n",
    "prefixes": [
        "v9",
        "2/2"
    ]
}