From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 6BC54A034F;
	Wed, 10 Nov 2021 04:01:55 +0100 (CET)
Received: from [217.70.189.124] (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id A3F8D410EF;
	Wed, 10 Nov 2021 04:01:49 +0100 (CET)
Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182])
 by mails.dpdk.org (Postfix) with ESMTP id C48CF40683
 for <dev@dpdk.org>; Wed, 10 Nov 2021 04:01:46 +0100 (CET)
Received: by linux.microsoft.com (Postfix, from userid 1059)
 id 10BA520C3536; Tue,  9 Nov 2021 19:01:46 -0800 (PST)
DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 10BA520C3536
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com;
 s=default; t=1636513306;
 bh=16avzK0eNxHXYlRLFto/kA9fgfC8kIHCPDnG+3s8vzw=;
 h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
 b=NBBTQwR/+agL3ml82y1Lvvf3RSThONCOMIlQrhwpo1r4r6AqwFKBCekfUhDHBQggi
 OydNbm/j3avrRR3G45m7vgd16r3wikSypk0zNMUY3PxK/yLzcSeQUiiwSJfN9aKG5r
 HZxcBmc5T6r1GgiPxVGo6JDLE06n+UCb1wtoDgNs=
From: Narcisa Ana Maria Vasile <navasile@linux.microsoft.com>
To: dev@dpdk.org, thomas@monjalon.net, dmitry.kozliuk@gmail.com,
 khot@microsoft.com, navasile@microsoft.com, dmitrym@microsoft.com,
 roretzla@microsoft.com, talshn@nvidia.com, ocardona@microsoft.com
Cc: bruce.richardson@intel.com, david.marchand@redhat.com,
 pallavi.kadam@intel.com
Date: Tue,  9 Nov 2021 19:01:30 -0800
Message-Id: <1636513302-7359-2-git-send-email-navasile@linux.microsoft.com>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1636513302-7359-1-git-send-email-navasile@linux.microsoft.com>
References: <1633765318-28356-1-git-send-email-navasile@linux.microsoft.com>
 <1636513302-7359-1-git-send-email-navasile@linux.microsoft.com>
Subject: [dpdk-dev] [PATCH v17 01/13] eal: add basic threading 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>,
 <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>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org
Sender: "dev" <dev-bounces@dpdk.org>

From: Narcisa Vasile <navasile@microsoft.com>

Use a portable, type-safe representation for the thread identifier.
Add functions for comparing thread ids and obtaining the thread id
for the current thread.

Signed-off-by: Narcisa Vasile <navasile@microsoft.com>
---
 lib/eal/common/meson.build            |  1 +
 lib/eal/{unix => common}/rte_thread.c | 57 ++++++++++++++++----------
 lib/eal/include/rte_thread.h          | 53 ++++++++++++++++++------
 lib/eal/unix/meson.build              |  1 -
 lib/eal/version.map                   |  3 ++
 lib/eal/windows/rte_thread.c          | 58 +++++++++++++++++----------
 6 files changed, 117 insertions(+), 56 deletions(-)
 rename lib/eal/{unix => common}/rte_thread.c (66%)

diff --git a/lib/eal/common/meson.build b/lib/eal/common/meson.build
index 917758cc65..6bdc9cd854 100644
--- a/lib/eal/common/meson.build
+++ b/lib/eal/common/meson.build
@@ -52,5 +52,6 @@ if not is_windows
             'hotplug_mp.c',
             'malloc_mp.c',
             'rte_keepalive.c',
+            'rte_thread.c'
     )
 endif
diff --git a/lib/eal/unix/rte_thread.c b/lib/eal/common/rte_thread.c
similarity index 66%
rename from lib/eal/unix/rte_thread.c
rename to lib/eal/common/rte_thread.c
index c72d619ec1..92a7451b0a 100644
--- a/lib/eal/unix/rte_thread.c
+++ b/lib/eal/common/rte_thread.c
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright 2021 Mellanox Technologies, Ltd
+ * Copyright(c) 2021 Microsoft Corporation
  */
 
 #include <errno.h>
@@ -16,25 +17,41 @@ struct eal_tls_key {
 	pthread_key_t thread_index;
 };
 
+rte_thread_t
+rte_thread_self(void)
+{
+	rte_thread_t thread_id;
+
+	thread_id.opaque_id = (uintptr_t)pthread_self();
+
+	return thread_id;
+}
+
+int
+rte_thread_equal(rte_thread_t t1, rte_thread_t t2)
+{
+	return pthread_equal((pthread_t)t1.opaque_id, (pthread_t)t2.opaque_id);
+}
+
 int
 rte_thread_key_create(rte_thread_key *key, void (*destructor)(void *))
 {
 	int err;
+	rte_thread_key k;
 
-	*key = malloc(sizeof(**key));
-	if ((*key) == NULL) {
+	k = malloc(sizeof(*k));
+	if (k == NULL) {
 		RTE_LOG(DEBUG, EAL, "Cannot allocate TLS key.\n");
-		rte_errno = ENOMEM;
-		return -1;
+		return EINVAL;
 	}
-	err = pthread_key_create(&((*key)->thread_index), destructor);
-	if (err) {
+	err = pthread_key_create(&(k->thread_index), destructor);
+	if (err != 0) {
 		RTE_LOG(DEBUG, EAL, "pthread_key_create failed: %s\n",
 			 strerror(err));
-		free(*key);
-		rte_errno = ENOEXEC;
-		return -1;
+		free(k);
+		return err;
 	}
+	*key = k;
 	return 0;
 }
 
@@ -43,18 +60,16 @@ rte_thread_key_delete(rte_thread_key key)
 {
 	int err;
 
-	if (!key) {
+	if (key == NULL) {
 		RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
-		rte_errno = EINVAL;
-		return -1;
+		return EINVAL;
 	}
 	err = pthread_key_delete(key->thread_index);
-	if (err) {
+	if (err != 0) {
 		RTE_LOG(DEBUG, EAL, "pthread_key_delete failed: %s\n",
 			 strerror(err));
 		free(key);
-		rte_errno = ENOEXEC;
-		return -1;
+		return err;
 	}
 	free(key);
 	return 0;
@@ -65,17 +80,15 @@ rte_thread_value_set(rte_thread_key key, const void *value)
 {
 	int err;
 
-	if (!key) {
+	if (key == NULL) {
 		RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
-		rte_errno = EINVAL;
-		return -1;
+		return EINVAL;
 	}
 	err = pthread_setspecific(key->thread_index, value);
-	if (err) {
+	if (err != 0) {
 		RTE_LOG(DEBUG, EAL, "pthread_setspecific failed: %s\n",
 			strerror(err));
-		rte_errno = ENOEXEC;
-		return -1;
+		return err;
 	}
 	return 0;
 }
@@ -83,7 +96,7 @@ rte_thread_value_set(rte_thread_key key, const void *value)
 void *
 rte_thread_value_get(rte_thread_key key)
 {
-	if (!key) {
+	if (key == NULL) {
 		RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
 		rte_errno = EINVAL;
 		return NULL;
diff --git a/lib/eal/include/rte_thread.h b/lib/eal/include/rte_thread.h
index 8be8ed8f36..c9cdeb07aa 100644
--- a/lib/eal/include/rte_thread.h
+++ b/lib/eal/include/rte_thread.h
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2021 Mellanox Technologies, Ltd
+ * Copyright(c) 2021 Microsoft Corporation
  */
+#include <stdint.h>
 
 #include <rte_os.h>
 #include <rte_compat.h>
@@ -20,11 +22,45 @@
 extern "C" {
 #endif
 
+#include <sched.h>
+
+/**
+ * Thread id descriptor.
+ */
+typedef struct rte_thread_tag {
+	uintptr_t opaque_id; /**< thread identifier */
+} rte_thread_t;
+
 /**
  * TLS key type, an opaque pointer.
  */
 typedef struct eal_tls_key *rte_thread_key;
 
+/**
+ * Get the id of the calling thread.
+ *
+ * @return
+ *   Return the thread id of the calling thread.
+ */
+__rte_experimental
+rte_thread_t rte_thread_self(void);
+
+/**
+ * Check if 2 thread ids are equal.
+ *
+ * @param t1
+ *   First thread id.
+ *
+ * @param t2
+ *   Second thread id.
+ *
+ * @return
+ *   If the ids are equal, return nonzero.
+ *   Otherwise, return 0.
+ */
+__rte_experimental
+int rte_thread_equal(rte_thread_t t1, rte_thread_t t2);
+
 #ifdef RTE_HAS_CPUSET
 
 /**
@@ -63,9 +99,7 @@ void rte_thread_get_affinity(rte_cpuset_t *cpusetp);
  *
  * @return
  *   On success, zero.
- *   On failure, a negative number and an error number is set in rte_errno.
- *   rte_errno can be: ENOMEM  - Memory allocation error.
- *                     ENOEXEC - Specific OS error.
+ *   On failure, return a positive errno-style error number.
  */
 
 __rte_experimental
@@ -80,9 +114,7 @@ int rte_thread_key_create(rte_thread_key *key,
  *
  * @return
  *   On success, zero.
- *   On failure, a negative number and an error number is set in rte_errno.
- *   rte_errno can be: EINVAL  - Invalid parameter passed.
- *                     ENOEXEC - Specific OS error.
+ *   On failure, return a positive errno-style error number.
  */
 __rte_experimental
 int rte_thread_key_delete(rte_thread_key key);
@@ -97,9 +129,7 @@ int rte_thread_key_delete(rte_thread_key key);
  *
  * @return
  *   On success, zero.
- *   On failure, a negative number and an error number is set in rte_errno.
- *   rte_errno can be: EINVAL  - Invalid parameter passed.
- *                     ENOEXEC - Specific OS error.
+ *   On failure, return a positive errno-style error number.
  */
 __rte_experimental
 int rte_thread_value_set(rte_thread_key key, const void *value);
@@ -112,9 +142,8 @@ int rte_thread_value_set(rte_thread_key key, const void *value);
  *
  * @return
  *   On success, value data pointer (can also be NULL).
- *   On failure, NULL and an error number is set in rte_errno.
- *   rte_errno can be: EINVAL  - Invalid parameter passed.
- *                     ENOEXEC - Specific OS error.
+ *   On failure, NULL and a positive error number is set in rte_errno.
+ *
  */
 __rte_experimental
 void *rte_thread_value_get(rte_thread_key key);
diff --git a/lib/eal/unix/meson.build b/lib/eal/unix/meson.build
index e3ecd3e956..cb6d233721 100644
--- a/lib/eal/unix/meson.build
+++ b/lib/eal/unix/meson.build
@@ -6,5 +6,4 @@ sources += files(
         'eal_unix_memory.c',
         'eal_unix_timer.c',
         'eal_firmware.c',
-        'rte_thread.c',
 )
diff --git a/lib/eal/version.map b/lib/eal/version.map
index ab28c22791..24e9747795 100644
--- a/lib/eal/version.map
+++ b/lib/eal/version.map
@@ -420,6 +420,9 @@ EXPERIMENTAL {
 	rte_intr_instance_free;
 	rte_intr_type_get;
 	rte_intr_type_set;
+
+	rte_thread_self;
+	rte_thread_equal;
 };
 
 INTERNAL {
diff --git a/lib/eal/windows/rte_thread.c b/lib/eal/windows/rte_thread.c
index 667287c387..26c8dd4ebe 100644
--- a/lib/eal/windows/rte_thread.c
+++ b/lib/eal/windows/rte_thread.c
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright 2021 Mellanox Technologies, Ltd
+ * Copyright(c) 2021 Microsoft Corporation
  */
 
 #include <rte_common.h>
@@ -11,22 +12,38 @@ struct eal_tls_key {
 	DWORD thread_index;
 };
 
+rte_thread_t
+rte_thread_self(void)
+{
+	rte_thread_t thread_id;
+
+	thread_id.opaque_id = GetCurrentThreadId();
+
+	return thread_id;
+}
+
+int
+rte_thread_equal(rte_thread_t t1, rte_thread_t t2)
+{
+	return t1.opaque_id == t2.opaque_id;
+}
+
 int
 rte_thread_key_create(rte_thread_key *key,
 		__rte_unused void (*destructor)(void *))
 {
+	int ret;
+
 	*key = malloc(sizeof(**key));
 	if ((*key) == NULL) {
 		RTE_LOG(DEBUG, EAL, "Cannot allocate TLS key.\n");
-		rte_errno = ENOMEM;
-		return -1;
+		return ENOMEM;
 	}
 	(*key)->thread_index = TlsAlloc();
 	if ((*key)->thread_index == TLS_OUT_OF_INDEXES) {
-		RTE_LOG_WIN32_ERR("TlsAlloc()");
+		ret = thread_log_last_error("TlsAlloc()");
 		free(*key);
-		rte_errno = ENOEXEC;
-		return -1;
+		return ret;
 	}
 	return 0;
 }
@@ -34,16 +51,16 @@ rte_thread_key_create(rte_thread_key *key,
 int
 rte_thread_key_delete(rte_thread_key key)
 {
-	if (!key) {
+	int ret;
+
+	if (key == NULL) {
 		RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
-		rte_errno = EINVAL;
-		return -1;
+		return EINVAL;
 	}
 	if (!TlsFree(key->thread_index)) {
-		RTE_LOG_WIN32_ERR("TlsFree()");
+		ret = thread_log_last_error("TlsFree()");
 		free(key);
-		rte_errno = ENOEXEC;
-		return -1;
+		return ret;
 	}
 	free(key);
 	return 0;
@@ -54,17 +71,14 @@ rte_thread_value_set(rte_thread_key key, const void *value)
 {
 	char *p;
 
-	if (!key) {
+	if (key == NULL) {
 		RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
-		rte_errno = EINVAL;
-		return -1;
+		return EINVAL;
 	}
 	/* discard const qualifier */
 	p = (char *) (uintptr_t) value;
 	if (!TlsSetValue(key->thread_index, p)) {
-		RTE_LOG_WIN32_ERR("TlsSetValue()");
-		rte_errno = ENOEXEC;
-		return -1;
+		return thread_log_last_error("TlsSetValue()");
 	}
 	return 0;
 }
@@ -73,16 +87,18 @@ void *
 rte_thread_value_get(rte_thread_key key)
 {
 	void *output;
+	DWORD ret = 0;
 
-	if (!key) {
+	if (key == NULL) {
 		RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
 		rte_errno = EINVAL;
 		return NULL;
 	}
 	output = TlsGetValue(key->thread_index);
-	if (GetLastError() != ERROR_SUCCESS) {
-		RTE_LOG_WIN32_ERR("TlsGetValue()");
-		rte_errno = ENOEXEC;
+	ret = GetLastError();
+	if (ret != 0) {
+		RTE_LOG(DEBUG, EAL, "GetLastError()=%lu: TlsGetValue()\n", ret);
+		rte_errno = thread_translate_win32_error(ret);
 		return NULL;
 	}
 	return output;
-- 
2.31.0.vfs.0.1