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,
ocardona@microsoft.com
Cc: bruce.richardson@intel.com, david.marchand@redhat.com,
pallavi.kadam@intel.com
Subject: [dpdk-dev] [PATCH 1/3] Add EAL threads API
Date: Wed, 17 Mar 2021 18:00:38 -0700 [thread overview]
Message-ID: <1616029240-26588-2-git-send-email-navasile@linux.microsoft.com> (raw)
In-Reply-To: <1616029240-26588-1-git-send-email-navasile@linux.microsoft.com>
From: Narcisa Vasile <navasile@microsoft.com>
EAL must hide the environment specifics from apps and libraries.
Add an EAL API for managing threads.
Signed-off-by: Narcisa Vasile <navasile@microsoft.com>
Signed-off-by: Dmitry Malloy <dmitrym@microsoft.com>
---
lib/librte_eal/common/eal_common_thread.c | 6 +-
lib/librte_eal/common/rte_thread.c | 346 ++++++++++++
lib/librte_eal/include/rte_thread.h | 323 ++++++++++-
lib/librte_eal/include/rte_thread_types.h | 20 +
lib/librte_eal/windows/eal_lcore.c | 167 ++++--
lib/librte_eal/windows/eal_windows.h | 10 +
.../include/rte_windows_thread_types.h | 19 +
lib/librte_eal/windows/rte_thread.c | 507 +++++++++++++++++-
8 files changed, 1338 insertions(+), 60 deletions(-)
create mode 100644 lib/librte_eal/common/rte_thread.c
create mode 100644 lib/librte_eal/include/rte_thread_types.h
create mode 100644 lib/librte_eal/windows/include/rte_windows_thread_types.h
diff --git a/lib/librte_eal/common/eal_common_thread.c b/lib/librte_eal/common/eal_common_thread.c
index 73a055902..5219e783e 100644
--- a/lib/librte_eal/common/eal_common_thread.c
+++ b/lib/librte_eal/common/eal_common_thread.c
@@ -84,7 +84,7 @@ thread_update_affinity(rte_cpuset_t *cpusetp)
}
int
-rte_thread_set_affinity(rte_cpuset_t *cpusetp)
+rte_thread_self_set_affinity(rte_cpuset_t *cpusetp)
{
if (pthread_setaffinity_np(pthread_self(), sizeof(rte_cpuset_t),
cpusetp) != 0) {
@@ -97,7 +97,7 @@ rte_thread_set_affinity(rte_cpuset_t *cpusetp)
}
void
-rte_thread_get_affinity(rte_cpuset_t *cpusetp)
+rte_thread_self_get_affinity(rte_cpuset_t *cpusetp)
{
assert(cpusetp);
memmove(cpusetp, &RTE_PER_LCORE(_cpuset),
@@ -140,7 +140,7 @@ eal_thread_dump_current_affinity(char *str, unsigned int size)
{
rte_cpuset_t cpuset;
- rte_thread_get_affinity(&cpuset);
+ rte_thread_self_get_affinity(&cpuset);
return eal_thread_dump_affinity(&cpuset, str, size);
}
diff --git a/lib/librte_eal/common/rte_thread.c b/lib/librte_eal/common/rte_thread.c
new file mode 100644
index 000000000..275876534
--- /dev/null
+++ b/lib/librte_eal/common/rte_thread.c
@@ -0,0 +1,346 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ * Copyright(c) 2021 Microsoft Corporation
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rte_common.h>
+#include <rte_errno.h>
+#include <rte_log.h>
+#include <rte_thread.h>
+
+struct eal_tls_key {
+ pthread_key_t thread_index;
+};
+
+rte_thread_t
+rte_thread_self(void)
+{
+ return pthread_self();
+}
+
+int
+rte_thread_equal(rte_thread_t t1, rte_thread_t t2)
+{
+ return pthread_equal(t1, t2);
+}
+
+int
+rte_thread_set_affinity(rte_thread_t thread_id, size_t cpuset_size,
+ const rte_cpuset_t *cpuset)
+{
+ return pthread_setaffinity_np(thread_id, cpuset_size, cpuset);
+}
+
+int rte_thread_get_affinity(rte_thread_t threadid, size_t cpuset_size,
+ rte_cpuset_t *cpuset)
+{
+ return pthread_getaffinity_np(threadid, cpuset_size, cpuset);
+}
+
+int
+rte_thread_set_priority(rte_thread_t thread_id,
+ enum rte_thread_priority priority)
+{
+ int policy;
+ struct sched_param param = {
+ .sched_priority = 0,
+ };
+
+
+ if (priority == RTE_THREAD_PRIORITY_REALTIME_CRITICAL) {
+ policy = SCHED_RR;
+ param.sched_priority = priority;
+ } else if (priority == RTE_THREAD_PRIORITY_NORMAL) {
+ policy = SCHED_OTHER;
+ param.sched_priority = priority;
+ } else {
+ RTE_LOG(DEBUG, EAL, "Invalid priority to set."
+ "Defaulting to priority 'normal'.\n");
+ policy = SCHED_OTHER;
+ }
+
+ return pthread_setschedparam(thread_id, policy, ¶m);
+}
+
+int
+rte_thread_attr_init(rte_thread_attr_t *attr)
+{
+ int ret = 0;
+ pthread_attr_t pthread_attr;
+
+ if (attr == NULL) {
+ RTE_LOG(DEBUG, EAL, "Invalid thread attributes parameter\n");
+ return -EINVAL;
+ }
+
+ ret = pthread_getattr_default_np(&pthread_attr);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_getattr_default_np failed\n");
+ return ret;
+ }
+
+ ret = pthread_attr_getaffinity_np(&pthread_attr, sizeof(attr->cpuset), &attr->cpuset);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_attr_getaffinity_np failed\n");
+ return ret;
+ }
+
+ attr->priority = RTE_THREAD_PRIORITY_NORMAL;
+
+ return 0;
+}
+
+int
+rte_thread_attr_set_affinity(rte_thread_attr_t *thread_attr, rte_cpuset_t *cpuset)
+{
+ if (thread_attr == NULL || cpuset == NULL) {
+ RTE_LOG(DEBUG, EAL, "Invalid thread attributes parameter\n");
+ return -EINVAL;
+ }
+ thread_attr->cpuset = *cpuset;
+ return 0;
+}
+
+int
+rte_thread_attr_get_affinity(rte_thread_attr_t *thread_attr, rte_cpuset_t *cpuset)
+{
+ if ((thread_attr == NULL) || (cpuset == NULL)) {
+ RTE_LOG(DEBUG, EAL, "Invalid thread attributes parameter\n");
+ return -EINVAL;
+ }
+
+ *cpuset = thread_attr->cpuset;
+ return 0;
+}
+
+int
+rte_thread_attr_set_priority(rte_thread_attr_t *thread_attr, enum rte_thread_priority priority)
+{
+ if (thread_attr == NULL) {
+ RTE_LOG(DEBUG, EAL,
+ "Unable to set priority attribute, invalid parameter\n");
+ return -EINVAL;
+ }
+
+ thread_attr->priority = priority;
+ return 0;
+}
+
+int
+rte_thread_create(rte_thread_t *thread_id,
+ const rte_thread_attr_t *thread_attr, void *(*thread_func) (void*),
+ void *args)
+{
+ int ret = 0;
+ pthread_attr_t attr;
+ pthread_attr_t *attrp = NULL;
+ struct sched_param param = {
+ .sched_priority = 0,
+ };
+ int policy = SCHED_OTHER;
+
+ if (thread_attr != NULL) {
+ ret = pthread_attr_init(&attr);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_attr_init failed\n");
+ goto cleanup;
+ }
+
+ attrp = &attr;
+
+ /* Set the inherit scheduler parameter to explicit,
+ * otherwise the priority attribute is ignored.
+ */
+ ret = pthread_attr_setinheritsched(attrp, PTHREAD_EXPLICIT_SCHED);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_attr_setinheritsched failed\n");
+ goto cleanup;
+ }
+
+ /* In case a realtime scheduling policy is requested, the sched_priority
+ * parameter is set to the value stored in thread_attr. Otherwise, for
+ * the default scheduling policy (SCHED_OTHER) sched_priority needs to
+ * be intialized to 0. */
+ if (thread_attr->priority == RTE_THREAD_PRIORITY_REALTIME_CRITICAL) {
+ policy = SCHED_RR;
+ param.sched_priority = thread_attr->priority;
+ }
+
+ ret = pthread_attr_setschedpolicy(attrp, policy);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_attr_setschedpolicy failed\n");
+ goto cleanup;
+ }
+
+ ret = pthread_attr_setschedparam(attrp, ¶m);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_attr_setschedparam failed\n");
+ goto cleanup;
+ }
+
+ ret = pthread_attr_setaffinity_np(attrp, sizeof(thread_attr->cpuset), &thread_attr->cpuset);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_attr_setaffinity_np failed\n");
+ goto cleanup;
+ }
+ }
+
+ ret = pthread_create(thread_id, attrp, thread_func, args);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_create failed\n");
+ goto cleanup;
+ }
+
+cleanup:
+ if (attrp != NULL) {
+ pthread_attr_destroy(&attr);
+ }
+ return ret;
+}
+
+int
+rte_thread_join(rte_thread_t thread_id, int *value_ptr)
+{
+ int ret = 0;
+ void *res = NULL;
+ void **pres = NULL;
+
+ if (value_ptr != NULL) {
+ pres = &res;
+ }
+
+ ret = pthread_join(thread_id, pres);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_join failed\n");
+ return ret;
+ }
+
+ if (pres != NULL) {
+ *value_ptr = *(int*)(*pres);
+ }
+ return 0;
+}
+
+int
+rte_thread_mutex_init(rte_thread_mutex_t *mutex)
+{
+ return pthread_mutex_init(mutex, NULL);
+}
+
+int
+rte_thread_mutex_lock(rte_thread_mutex_t *mutex)
+{
+ return pthread_mutex_lock(mutex);
+}
+
+int
+rte_thread_mutex_unlock(rte_thread_mutex_t *mutex)
+{
+ return pthread_mutex_unlock(mutex);
+}
+
+int
+rte_thread_mutex_destroy(rte_thread_mutex_t *mutex)
+{
+ return pthread_mutex_destroy(mutex);
+}
+
+int
+rte_thread_barrier_init(rte_thread_barrier_t *barrier, int count)
+{
+ return pthread_barrier_init(barrier, NULL, count);
+}
+
+int rte_thread_barrier_wait(rte_thread_barrier_t *barrier)
+{
+ return pthread_barrier_wait(barrier);
+}
+
+int rte_thread_barrier_destroy(rte_thread_barrier_t *barrier)
+{
+ return pthread_barrier_destroy(barrier);
+}
+
+int rte_thread_cancel(rte_thread_t thread_id)
+{
+ /*
+ * TODO: Behavior is different between POSIX and Windows threads.
+ * POSIX threads wait for a cancellation point.
+ * Current Windows emulation kills thread at any point.
+ */
+ return pthread_cancel(thread_id);
+}
+
+int
+rte_thread_tls_key_create(rte_tls_key *key, void (*destructor)(void *))
+{
+ int err;
+
+ *key = malloc(sizeof(**key));
+ if ((*key) == NULL) {
+ RTE_LOG(DEBUG, EAL, "Cannot allocate TLS key.\n");
+ return -EINVAL;
+ }
+ err = pthread_key_create(&((*key)->thread_index), destructor);
+ if (err != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_key_create failed: %s\n",
+ strerror(err));
+ free(*key);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+int
+rte_thread_tls_key_delete(rte_tls_key key)
+{
+ int err;
+
+ if (key == NULL) {
+ RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
+ return -EINVAL;
+ }
+ err = pthread_key_delete(key->thread_index);
+ if (err != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_key_delete failed: %s\n",
+ strerror(err));
+ free(key);
+ return -EINVAL;
+ }
+ free(key);
+ return 0;
+}
+
+int
+rte_thread_tls_value_set(rte_tls_key key, const void *value)
+{
+ int err;
+
+ if (key == NULL) {
+ RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
+ return -EINVAL;
+ }
+ err = pthread_setspecific(key->thread_index, value);
+ if (err != 0) {
+ RTE_LOG(DEBUG, EAL, "pthread_setspecific failed: %s\n",
+ strerror(err));
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+void *
+rte_thread_tls_value_get(rte_tls_key key)
+{
+ if (key == NULL) {
+ RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
+ rte_errno = EINVAL;
+ return NULL;
+ }
+ return pthread_getspecific(key->thread_index);
+}
diff --git a/lib/librte_eal/include/rte_thread.h b/lib/librte_eal/include/rte_thread.h
index e640ea185..66b112bc4 100644
--- a/lib/librte_eal/include/rte_thread.h
+++ b/lib/librte_eal/include/rte_thread.h
@@ -20,11 +20,330 @@
extern "C" {
#endif
+#include <sched.h>
+#if defined(RTE_USE_WINDOWS_THREAD_TYPES)
+#include <rte_windows_thread_types.h>
+#else
+#include <rte_thread_types.h>
+#endif
+
+enum rte_thread_priority
+{
+ RTE_THREAD_PRIORITY_NORMAL = EAL_THREAD_PRIORITY_NORMAL,
+ RTE_THREAD_PRIORITY_REALTIME_CRITICAL = EAL_THREAD_PRIORITY_REALTIME_CIRTICAL,
+ /*
+ * This enum can be extended to allow more priority levels.
+ */
+};
+
+typedef struct
+{
+ enum rte_thread_priority priority;
+ rte_cpuset_t cpuset;
+} rte_thread_attr_t;
+
/**
* TLS key type, an opaque pointer.
*/
typedef struct eal_tls_key *rte_tls_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);
+
+/**
+ * Set the affinity of thread 'thread_id' to the cpu set
+ * specified by 'cpuset'.
+ *
+ * @param thread_id
+ * Id of the thread for which to set the affinity.
+ *
+ * @param cpuset_size
+ *
+ * @param cpuset
+ * Pointer to CPU affinity to set.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return nonzero.
+ */
+__rte_experimental
+int rte_thread_set_affinity(rte_thread_t thread_id, size_t cpuset_size,
+ const rte_cpuset_t *cpuset);
+
+/**
+ * Get the affinity of thread 'thread_id' and store it
+ * in 'cpuset'.
+ *
+ * @param thread_id
+ * Id of the thread for which to get the affinity.
+ *
+ * @param cpuset_size
+ * Size of the cpu set.
+ *
+ * @param cpuset
+ * Pointer for storing the affinity value.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return nonzero.
+ */
+__rte_experimental
+int rte_thread_get_affinity(rte_thread_t thread_id, size_t cpuset_size,
+ rte_cpuset_t *cpuset);
+
+/**
+ * Set the priority of a thread.
+ *
+ * @param thread_id
+ * Id of the thread for which to set priority.
+ *
+ * @param priority
+ * Priority value to be set.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return nonzero.
+ */
+__rte_experimental
+int rte_thread_set_priority(rte_thread_t thread_id, enum rte_thread_priority priority);
+
+/**
+ * Initialize the attributes of a thread.
+ * These attributes can be passed to the rte_thread_create() function
+ * that will create a new thread and set its attributes according to attr;
+ *
+ * @param attr
+ * Thread attributes to initialize.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return nonzero.
+ */
+__rte_experimental
+int rte_thread_attr_init(rte_thread_attr_t *attr);
+
+/**
+ * Set the CPU affinity value in the thread attributes pointed to
+ * by 'thread_attr'.
+ *
+ * @param thread_attr
+ * Points to the thread attributes in which affinity will be updated.
+ *
+ * @param cpuset
+ * Points to the value of the affinity to be set.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return nonzero.
+ */
+__rte_experimental
+int rte_thread_attr_set_affinity(rte_thread_attr_t *thread_attr, rte_cpuset_t *cpuset);
+
+/**
+ * Get the value of CPU affinity that is set in the thread attributes pointed to
+ * by 'thread_attr'.
+ *
+ * @param thread_attr
+ * Points to the thread attributes from which affinity will be retrieved.
+ *
+ * @param cpuset
+ * Pointer to the memory that will store the affinity.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return nonzero.
+ */
+__rte_experimental
+int rte_thread_attr_get_affinity(rte_thread_attr_t *thread_attr, rte_cpuset_t *cpuset);
+
+/**
+ * Set the thread priority value in the thread attributes pointed to
+ * by 'thread_attr'.
+ *
+ * @param thread_attr
+ * Points to the thread attributes in which priority will be updated.
+ *
+ * @param cpuset
+ * Points to the value of the priority to be set.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return nonzero.
+ */
+__rte_experimental
+int rte_thread_attr_set_priority(rte_thread_attr_t *thread_attr, enum rte_thread_priority priority);
+
+/**
+ * Create a new thread that will invoke the 'thread_func' routine.
+ *
+ * @param thread_id
+ * A pointer that will store the id of the newly created thread.
+ *
+ * @param thread_attr
+ * Attributes that are used at the creation of the new thread.
+ *
+ * @param thread_func
+ * The routine that the new thread will invoke when starting execution.
+ *
+ * @param args
+ * Arguments to be passed to the 'thread_func' routine.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return an error number.
+ */
+__rte_experimental
+int rte_thread_create(rte_thread_t *thread_id,
+ const rte_thread_attr_t *thread_attr,
+ void *(*thread_func) (void*), void *args);
+
+/**
+ * Waits for the thread identified by 'thread_id' to terminate
+ *
+ * @param thread_id
+ * The identifier of the thread.
+ *
+ * @param value_ptr
+ * Stores the exit status of the thread.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return an error number.
+ */
+__rte_experimental
+int rte_thread_join(rte_thread_t thread_id, int *value_ptr);
+
+/**
+ * Initializes a mutex.
+ *
+ * @param mutex
+ * The mutex to be initialized.
+ *
+ * @param attr
+ * Attributes for initialization of the mutex.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return an error number.
+ */
+__rte_experimental
+int rte_thread_mutex_init(rte_thread_mutex_t *mutex);
+
+/**
+ * Locks a mutex.
+ *
+ * @param mutex
+ * The mutex to be locked.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return an error number.
+ */
+__rte_experimental
+int rte_thread_mutex_lock(rte_thread_mutex_t *mutex);
+
+/**
+ * Unlocks a mutex.
+ *
+ * @param mutex
+ * The mutex to be unlocked.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return an error number.
+ */
+__rte_experimental
+int rte_thread_mutex_unlock(rte_thread_mutex_t *mutex);
+
+/**
+ * Releases all resources associated with a mutex.
+ *
+ * @param mutex
+ * The mutex to be uninitialized.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return an error number.
+ */
+__rte_experimental
+int rte_thread_mutex_destroy(rte_thread_mutex_t *mutex);
+
+/**
+ * Initializes a synchronization barrier.
+ *
+ * @param barrier
+ * A pointer that references the newly created 'barrier' object.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return an error number.
+ */
+__rte_experimental
+int rte_thread_barrier_init(rte_thread_barrier_t *barrier, int count);
+
+/**
+ * Causes the calling thread to wait at the synchronization barrier 'barrier'.
+ *
+ * @param barrier
+ * The barrier used for synchronizing the threads.
+ *
+ * @return
+ * Return RTE_THREAD_BARRIER_SERIAL_THREAD for the thread synchronized at the barrier.
+ * Return 0 for all other threads.
+ * Return error number in case of error.
+ */
+__rte_experimental
+int rte_thread_barrier_wait(rte_thread_barrier_t *barrier);
+
+/**
+ * Releases all resources used by a synchronization barrier
+ * and uninitializes it.
+ *
+ * @param barrier
+ * The barrier to be uninitialized.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return an error number.
+ */
+__rte_experimental
+int rte_thread_barrier_destroy(rte_thread_barrier_t *barrier);
+
+/**
+ * Terminates a thread.
+ *
+ * @param thread_id
+ * The id of the thread to be terminated.
+ *
+ * @return
+ * On success, return 0.
+ * On failure, return nonzero.
+ */
+__rte_experimental
+int rte_thread_cancel(rte_thread_t thread_id);
+
/**
* Set core affinity of the current thread.
* Support both EAL and non-EAL thread and update TLS.
@@ -34,7 +353,7 @@ typedef struct eal_tls_key *rte_tls_key;
* @return
* On success, return 0; otherwise return -1;
*/
-int rte_thread_set_affinity(rte_cpuset_t *cpusetp);
+int rte_thread_self_set_affinity(rte_cpuset_t *cpusetp);
/**
* Get core affinity of the current thread.
@@ -44,7 +363,7 @@ int rte_thread_set_affinity(rte_cpuset_t *cpusetp);
* It presumes input is not NULL, otherwise it causes panic.
*
*/
-void rte_thread_get_affinity(rte_cpuset_t *cpusetp);
+void rte_thread_self_get_affinity(rte_cpuset_t *cpusetp);
/**
* Create a TLS data key visible to all threads in the process.
diff --git a/lib/librte_eal/include/rte_thread_types.h b/lib/librte_eal/include/rte_thread_types.h
new file mode 100644
index 000000000..b055bbf67
--- /dev/null
+++ b/lib/librte_eal/include/rte_thread_types.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Microsoft Corporation
+ */
+
+#ifndef _RTE_THREAD_TYPES_H_
+#define _RTE_THREAD_TYPES_H_
+
+#include <pthread.h>
+
+#define RTE_THREAD_BARRIER_SERIAL_THREAD PTHREAD_BARRIER_SERIAL_THREAD
+#define RTE_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+
+#define EAL_THREAD_PRIORITY_NORMAL 0
+#define EAL_THREAD_PRIORITY_REALTIME_CIRTICAL 99
+
+typedef pthread_t rte_thread_t;
+typedef pthread_mutex_t rte_thread_mutex_t;
+typedef pthread_barrier_t rte_thread_barrier_t;
+
+#endif /* _RTE_THREAD_TYPES_H_ */
diff --git a/lib/librte_eal/windows/eal_lcore.c b/lib/librte_eal/windows/eal_lcore.c
index a85149be9..3e63f9f70 100644
--- a/lib/librte_eal/windows/eal_lcore.c
+++ b/lib/librte_eal/windows/eal_lcore.c
@@ -2,7 +2,6 @@
* Copyright(c) 2019 Intel Corporation
*/
-#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
@@ -28,10 +27,12 @@ struct socket_map {
};
struct cpu_map {
- unsigned int socket_count;
unsigned int lcore_count;
+ unsigned int socket_count;
+ unsigned int cpu_count;
struct lcore_map lcores[RTE_MAX_LCORE];
struct socket_map sockets[RTE_MAX_NUMA_NODES];
+ GROUP_AFFINITY cpus[CPU_SETSIZE];
};
static struct cpu_map cpu_map = { 0 };
@@ -48,13 +49,110 @@ log_early(const char *format, ...)
va_end(va);
}
+static int
+eal_query_group_affinity(void)
+{
+ SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infos = NULL;
+ DWORD infos_size = 0;
+ int ret = 0;
+
+ if (!GetLogicalProcessorInformationEx(RelationGroup, NULL, &infos_size)) {
+ DWORD error = GetLastError();
+ if (error != ERROR_INSUFFICIENT_BUFFER) {
+ log_early("Cannot get group information size, error %lu\n",
+ error);
+ rte_errno = EINVAL;
+ ret = -1;
+ goto cleanup;
+ }
+ }
+
+ infos = malloc(infos_size);
+ if (infos == NULL) {
+ log_early("Cannot allocate memory for NUMA node information\n");
+ rte_errno = ENOMEM;
+ ret = -1;
+ goto cleanup;
+ }
+
+ if (!GetLogicalProcessorInformationEx(RelationGroup, infos, &infos_size)) {
+ log_early("Cannot get group information, error %lu\n", GetLastError());
+ rte_errno = EINVAL;
+ ret = -1;
+ goto cleanup;
+ }
+
+ cpu_map.cpu_count = 0;
+ USHORT group_count = infos->Group.ActiveGroupCount;
+ for (USHORT group_number = 0; group_number < group_count; group_number++) {
+ KAFFINITY affinity = infos->Group.GroupInfo[group_number].ActiveProcessorMask;
+
+ for (unsigned int i = 0; i < EAL_PROCESSOR_GROUP_SIZE; i++) {
+ if ((affinity & ((KAFFINITY)1 << i)) == 0)
+ continue;
+ cpu_map.cpus[cpu_map.cpu_count].Group = group_number;
+ cpu_map.cpus[cpu_map.cpu_count].Mask = (KAFFINITY)1 << i;
+ cpu_map.cpu_count++;
+ }
+ }
+
+cleanup:
+ free(infos);
+ return ret;
+}
+
+static bool
+eal_check_for_duplicate_numa(const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *info)
+{
+ const unsigned int node_id = info->NumaNode.NodeNumber;
+ const GROUP_AFFINITY *cores = &info->NumaNode.GroupMask;
+ struct lcore_map *lcore;
+ unsigned int socket_id;
+
+ /* NUMA node may be reported multiple times if it includes
+ * cores from different processor groups, e. g. 80 cores
+ * of a physical processor comprise one NUMA node, but two
+ * processor groups, because group size is limited by 32/64.
+ */
+ for (socket_id = 0; socket_id < cpu_map.socket_count; socket_id++) {
+ if (cpu_map.sockets[socket_id].node_id == node_id)
+ break;
+ }
+
+ if (socket_id == cpu_map.socket_count) {
+ if (socket_id == RTE_DIM(cpu_map.sockets)) {
+ return true;
+ }
+
+ cpu_map.sockets[socket_id].node_id = node_id;
+ cpu_map.socket_count++;
+ }
+
+ for (unsigned int i = 0; i < EAL_PROCESSOR_GROUP_SIZE; i++) {
+ if ((cores->Mask & ((KAFFINITY)1 << i)) == 0)
+ continue;
+
+ if (cpu_map.lcore_count == RTE_DIM(cpu_map.lcores)) {
+ return true;
+ }
+
+ lcore = &cpu_map.lcores[cpu_map.lcore_count];
+ lcore->socket_id = socket_id;
+ lcore->core_id = cores->Group * EAL_PROCESSOR_GROUP_SIZE + i;
+ cpu_map.lcore_count++;
+ }
+ return false;
+}
+
int
eal_create_cpu_map(void)
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infos, *info;
DWORD infos_size;
bool full = false;
+ int ret = 0;
+ infos = NULL;
infos_size = 0;
if (!GetLogicalProcessorInformationEx(
RelationNumaNode, NULL, &infos_size)) {
@@ -79,57 +177,27 @@ eal_create_cpu_map(void)
log_early("Cannot get NUMA node information, error %lu\n",
GetLastError());
rte_errno = EINVAL;
- return -1;
+ ret = -1;
+ goto exit;
}
info = infos;
while ((uint8_t *)info - (uint8_t *)infos < infos_size) {
- unsigned int node_id = info->NumaNode.NodeNumber;
- GROUP_AFFINITY *cores = &info->NumaNode.GroupMask;
- struct lcore_map *lcore;
- unsigned int i, socket_id;
-
- /* NUMA node may be reported multiple times if it includes
- * cores from different processor groups, e. g. 80 cores
- * of a physical processor comprise one NUMA node, but two
- * processor groups, because group size is limited by 32/64.
- */
- for (socket_id = 0; socket_id < cpu_map.socket_count;
- socket_id++) {
- if (cpu_map.sockets[socket_id].node_id == node_id)
- break;
- }
-
- if (socket_id == cpu_map.socket_count) {
- if (socket_id == RTE_DIM(cpu_map.sockets)) {
- full = true;
- goto exit;
- }
-
- cpu_map.sockets[socket_id].node_id = node_id;
- cpu_map.socket_count++;
- }
-
- for (i = 0; i < EAL_PROCESSOR_GROUP_SIZE; i++) {
- if ((cores->Mask & ((KAFFINITY)1 << i)) == 0)
- continue;
-
- if (cpu_map.lcore_count == RTE_DIM(cpu_map.lcores)) {
- full = true;
- goto exit;
- }
-
- lcore = &cpu_map.lcores[cpu_map.lcore_count];
- lcore->socket_id = socket_id;
- lcore->core_id =
- cores->Group * EAL_PROCESSOR_GROUP_SIZE + i;
- cpu_map.lcore_count++;
- }
+ if (eal_check_for_duplicate_numa(info))
+ break;
info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(
(uint8_t *)info + info->Size);
}
+ if (eal_query_group_affinity()) {
+ /*
+ * No need to set rte_errno here.
+ * It is set by eal_query_group_affinity().
+ */
+ ret = -1;
+ goto exit;
+ }
exit:
if (full) {
/* Not a fatal error, but important for troubleshooting. */
@@ -139,7 +207,7 @@ eal_create_cpu_map(void)
free(infos);
- return 0;
+ return ret;
}
int
@@ -165,3 +233,12 @@ eal_socket_numa_node(unsigned int socket_id)
{
return cpu_map.sockets[socket_id].node_id;
}
+
+PGROUP_AFFINITY
+eal_get_cpu_affinity(size_t cpu_index)
+{
+ if (cpu_index < CPU_SETSIZE)
+ return &cpu_map.cpus[cpu_index];
+
+ return NULL;
+}
diff --git a/lib/librte_eal/windows/eal_windows.h b/lib/librte_eal/windows/eal_windows.h
index 478accc1b..dc5dc8240 100644
--- a/lib/librte_eal/windows/eal_windows.h
+++ b/lib/librte_eal/windows/eal_windows.h
@@ -55,6 +55,16 @@ int eal_thread_create(pthread_t *thread);
*/
unsigned int eal_socket_numa_node(unsigned int socket_id);
+/**
+ * Get pointer to the group affinity for the cpu.
+ *
+ * @param cpu_index
+ * Index of the cpu, as it comes from rte_cpuset_t.
+ * @return
+ * Pointer to the group affinity for the cpu.
+ */
+PGROUP_AFFINITY eal_get_cpu_affinity(size_t cpu_index);
+
/**
* Schedule code for execution in the interrupt thread.
*
diff --git a/lib/librte_eal/windows/include/rte_windows_thread_types.h b/lib/librte_eal/windows/include/rte_windows_thread_types.h
new file mode 100644
index 000000000..b6209e6eb
--- /dev/null
+++ b/lib/librte_eal/windows/include/rte_windows_thread_types.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Microsoft Corporation
+ */
+
+#ifndef _RTE_THREAD_TYPES_H_
+#define _RTE_THREAD_TYPES_H_
+
+#include <rte_windows.h>
+
+#define RTE_THREAD_BARRIER_SERIAL_THREAD TRUE
+
+#define EAL_THREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL
+#define EAL_THREAD_PRIORITY_REALTIME_CIRTICAL THREAD_PRIORITY_TIME_CRITICAL
+
+typedef DWORD rte_thread_t;
+typedef CRITICAL_SECTION rte_thread_mutex_t;
+typedef SYNCHRONIZATION_BARRIER rte_thread_barrier_t;
+
+#endif /* _RTE_THREAD_TYPES_H_ */
diff --git a/lib/librte_eal/windows/rte_thread.c b/lib/librte_eal/windows/rte_thread.c
index 2e2ab2917..decb4b24d 100644
--- a/lib/librte_eal/windows/rte_thread.c
+++ b/lib/librte_eal/windows/rte_thread.c
@@ -1,16 +1,503 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright 2021 Mellanox Technologies, Ltd
+ * Copyright(c) 2021 Microsoft Corporation
*/
#include <rte_common.h>
-#include <rte_errno.h>
#include <rte_thread.h>
-#include <rte_windows.h>
+
+#include "eal_windows.h"
struct eal_tls_key {
DWORD thread_index;
};
+/* Translates the most common error codes related to threads */
+static int rte_thread_translate_win32_error(DWORD error)
+{
+ switch (error) {
+ case ERROR_SUCCESS:
+ return 0;
+
+ case ERROR_INVALID_PARAMETER:
+ return -EINVAL;
+
+ case ERROR_INVALID_HANDLE:
+ return -EFAULT;
+
+ case ERROR_NOT_ENOUGH_MEMORY:
+ /* FALLTHROUGH */
+ case ERROR_NO_SYSTEM_RESOURCES:
+ return -ENOMEM;
+
+ case ERROR_PRIVILEGE_NOT_HELD:
+ /* FALLTHROUGH */
+ case ERROR_ACCESS_DENIED:
+ return -EACCES;
+
+ case ERROR_ALREADY_EXISTS:
+ return -EEXIST;
+
+ case ERROR_POSSIBLE_DEADLOCK:
+ return -EDEADLK;
+
+ case ERROR_INVALID_FUNCTION:
+ /* FALLTHROUGH */
+ case ERROR_CALL_NOT_IMPLEMENTED:
+ return -ENOSYS;
+
+ default:
+ return -EINVAL;
+ }
+
+ return -EINVAL;
+}
+
+rte_thread_t
+rte_thread_self(void)
+{
+ return GetCurrentThreadId();
+}
+
+int
+rte_thread_equal(rte_thread_t t1, rte_thread_t t2)
+{
+ return t1 == t2 ? 1 : 0;
+}
+
+static int
+rte_convert_cpuset_to_affinity(const rte_cpuset_t *cpuset,
+ PGROUP_AFFINITY affinity)
+{
+ int ret = 0;
+ PGROUP_AFFINITY cpu_affinity = NULL;
+
+ memset(affinity, 0, sizeof(GROUP_AFFINITY));
+ affinity->Group = (USHORT)-1;
+
+ /* Check that all cpus of the set belong to the same processor group and
+ * accumulate thread affinity to be applied.
+ */
+ for (unsigned int cpu_idx = 0; cpu_idx < CPU_SETSIZE; cpu_idx++) {
+ if (!CPU_ISSET(cpu_idx, cpuset))
+ continue;
+
+ cpu_affinity = eal_get_cpu_affinity(cpu_idx);
+
+ if (affinity->Group == (USHORT)-1) {
+ affinity->Group = cpu_affinity->Group;
+ } else if (affinity->Group != cpu_affinity->Group) {
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ affinity->Mask |= cpu_affinity->Mask;
+ }
+
+ if (affinity->Mask == 0) {
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+cleanup:
+ return ret;
+}
+
+int rte_thread_set_affinity(rte_thread_t thread_id,
+ size_t cpuset_size,
+ const rte_cpuset_t *cpuset)
+{
+ int ret = 0;
+ GROUP_AFFINITY thread_affinity;
+ HANDLE thread_handle = NULL;
+
+ if (cpuset == NULL || cpuset_size < sizeof(*cpuset)) {
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ ret = rte_convert_cpuset_to_affinity(cpuset, &thread_affinity);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "Unable to convert cpuset to thread affinity\n");
+ goto cleanup;
+ }
+
+ thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id);
+ if (thread_handle == NULL) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("OpenThread()");
+ goto cleanup;
+ }
+
+ if (!SetThreadGroupAffinity(thread_handle, &thread_affinity, NULL)) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("SetThreadGroupAffinity()");
+ goto cleanup;
+ }
+
+cleanup:
+ if (thread_handle != NULL) {
+ CloseHandle(thread_handle);
+ thread_handle = NULL;
+ }
+
+ return ret;
+}
+
+int
+rte_thread_get_affinity(rte_thread_t thread_id, size_t cpuset_size,
+ rte_cpuset_t *cpuset)
+{
+ HANDLE thread_handle = NULL;
+ PGROUP_AFFINITY cpu_affinity;
+ GROUP_AFFINITY thread_affinity;
+ int ret = 0;
+
+ if (cpuset == NULL || cpuset_size < sizeof(*cpuset)) {
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id);
+ if (thread_handle == NULL) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("OpenThread()");
+ goto cleanup;
+ }
+
+ /* obtain previous thread affinity */
+ if (!GetThreadGroupAffinity(thread_handle, &thread_affinity)) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("GetThreadGroupAffinity()");
+ goto cleanup;
+ }
+
+ CPU_ZERO(cpuset);
+
+ /* Convert affinity to DPDK cpu set */
+ for (unsigned int cpu_idx = 0; cpu_idx < CPU_SETSIZE; cpu_idx++) {
+
+ cpu_affinity = eal_get_cpu_affinity(cpu_idx);
+
+ if ((cpu_affinity->Group == thread_affinity.Group) &&
+ ((cpu_affinity->Mask & thread_affinity.Mask) != 0)) {
+ CPU_SET(cpu_idx, cpuset);
+ }
+ }
+
+cleanup:
+ if (thread_handle != NULL) {
+ CloseHandle(thread_handle);
+ thread_handle = NULL;
+ }
+ return ret;
+}
+
+static HANDLE
+get_process_handle_from_thread_handle(HANDLE thread_handle)
+{
+ DWORD process_id = 0;
+
+ process_id = GetProcessIdOfThread(thread_handle);
+ if (process_id == 0) {
+ RTE_LOG_WIN32_ERR("GetProcessIdOfThread()");
+ return NULL;
+ }
+
+ return OpenProcess(PROCESS_SET_INFORMATION, FALSE, process_id);
+}
+
+int
+rte_thread_set_priority(rte_thread_t thread_id, enum rte_thread_priority priority)
+{
+ HANDLE thread_handle = NULL;
+ HANDLE process_handle = NULL;
+ DWORD priority_class = NORMAL_PRIORITY_CLASS;
+ int ret = 0;
+
+ thread_handle = OpenThread(THREAD_SET_INFORMATION |
+ THREAD_QUERY_INFORMATION, FALSE, thread_id);
+ if (thread_handle == NULL) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("OpenThread()");
+ goto cleanup;
+ }
+
+ switch (priority) {
+
+ case RTE_THREAD_PRIORITY_REALTIME_CRITICAL:
+ priority_class = REALTIME_PRIORITY_CLASS;
+ break;
+
+ case RTE_THREAD_PRIORITY_NORMAL:
+ /* FALLTHROUGH */
+ default:
+ priority_class = NORMAL_PRIORITY_CLASS;
+ priority = RTE_THREAD_PRIORITY_NORMAL;
+ break;
+ }
+
+ process_handle = get_process_handle_from_thread_handle(thread_handle);
+ if (process_handle == NULL) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("get_process_handle_from_thread_handle()");
+ goto cleanup;
+ }
+
+ if (!SetPriorityClass(process_handle, priority_class)) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("SetPriorityClass()");
+ goto cleanup;
+ }
+
+ if (!SetThreadPriority(thread_handle, priority)) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("SetThreadPriority()");
+ goto cleanup;
+ }
+
+cleanup:
+ if (thread_handle != NULL) {
+ CloseHandle(thread_handle);
+ thread_handle = NULL;
+ }
+ if (process_handle != NULL) {
+ CloseHandle(process_handle);
+ process_handle = NULL;
+ }
+ return ret;
+}
+
+int
+rte_thread_attr_init(rte_thread_attr_t *attr)
+{
+ if (attr == NULL) {
+ RTE_LOG(DEBUG, EAL,
+ "Unable to init thread attributes, invalid parameter\n");
+ return -EINVAL;
+ }
+
+ attr->priority = RTE_THREAD_PRIORITY_NORMAL;
+ CPU_ZERO(&attr->cpuset);
+ return 0;
+}
+
+int
+rte_thread_attr_set_affinity(rte_thread_attr_t *thread_attr, rte_cpuset_t *cpuset)
+{
+ if (thread_attr == NULL) {
+ RTE_LOG(DEBUG, EAL,
+ "Unable to set affinity attribute, invalid parameter\n");
+ return -EINVAL;
+ }
+
+ thread_attr->cpuset = *cpuset;
+ return 0;
+}
+
+int
+rte_thread_attr_get_affinity(rte_thread_attr_t *thread_attr, rte_cpuset_t *cpuset)
+{
+ if (thread_attr == NULL) {
+ RTE_LOG(DEBUG, EAL,
+ "Unable to set affinity attribute, invalid parameter\n");
+ return -EINVAL;
+ }
+
+ *cpuset = thread_attr->cpuset;
+ return 0;
+}
+
+int
+rte_thread_attr_set_priority(rte_thread_attr_t *thread_attr, enum rte_thread_priority priority)
+{
+ if (thread_attr == NULL) {
+ RTE_LOG(DEBUG, EAL,
+ "Unable to set priority attribute, invalid parameter\n");
+ return -EINVAL;
+ }
+
+ thread_attr->priority = priority;
+ return 0;
+}
+
+int
+rte_thread_create(rte_thread_t *thread_id,
+ const rte_thread_attr_t *thread_attr, void *(*thread_func) (void*),
+ void *args)
+{
+ int ret = 0;
+ HANDLE thread_handle = NULL;
+ GROUP_AFFINITY thread_affinity;
+
+ thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, args, 0, thread_id);
+ if (thread_handle == NULL) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("CreateThread()");
+ goto cleanup;
+ }
+
+ if (thread_attr != NULL) {
+ if (CPU_COUNT(&thread_attr->cpuset) > 0) {
+ ret = rte_convert_cpuset_to_affinity(&thread_attr->cpuset, &thread_affinity);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "Unable to convert cpuset to thread affinity\n");
+ goto cleanup;
+ }
+
+ if (!SetThreadGroupAffinity(thread_handle, &thread_affinity, NULL)) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("SetThreadGroupAffinity()");
+ goto cleanup;
+ }
+ }
+ ret = rte_thread_set_priority(*thread_id, thread_attr->priority);
+ if (ret != 0) {
+ RTE_LOG(DEBUG, EAL, "Unable to set thread priority\n");
+ goto cleanup;
+ }
+ }
+
+ return 0;
+
+cleanup:
+ if (thread_handle != NULL) {
+ CloseHandle(thread_handle);
+ thread_handle = NULL;
+ }
+ return ret;
+}
+
+int
+rte_thread_join(rte_thread_t thread_id, int *value_ptr)
+{
+ HANDLE thread_handle = NULL;
+ DWORD result = 0;
+ DWORD exit_code = 0;
+ BOOL err = 0;
+ int ret = 0;
+
+ thread_handle = OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id);
+ if (thread_handle == NULL) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("OpenThread()");
+ goto cleanup;
+ }
+
+ result = WaitForSingleObject(thread_handle, INFINITE);
+ if (result != WAIT_OBJECT_0) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("WaitForSingleObject()");
+ goto cleanup;
+ }
+
+ if (value_ptr != NULL) {
+ err = GetExitCodeThread(thread_handle, &exit_code);
+ if (err == 0) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("GetExitCodeThread()");
+ goto cleanup;
+ }
+ *value_ptr = exit_code;
+ }
+
+cleanup:
+ if (thread_handle != NULL) {
+ CloseHandle(thread_handle);
+ thread_handle = NULL;
+ }
+
+ return ret;
+}
+
+int
+rte_thread_mutex_init(rte_thread_mutex_t *mutex)
+{
+ InitializeCriticalSection(mutex);
+ return 0;
+}
+
+int
+rte_thread_mutex_lock(rte_thread_mutex_t *mutex)
+{
+ EnterCriticalSection(mutex);
+ return 0;
+}
+
+int
+rte_thread_mutex_unlock(rte_thread_mutex_t *mutex)
+{
+ LeaveCriticalSection(mutex);
+ return 0;
+}
+
+int
+rte_thread_mutex_destroy(rte_thread_mutex_t *mutex)
+{
+ DeleteCriticalSection(mutex);
+ return 0;
+}
+
+int
+rte_thread_barrier_init(rte_thread_barrier_t *barrier, int count)
+{
+ int ret = 0;
+
+ if (!InitializeSynchronizationBarrier(barrier, count, -1)) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("InitializeSynchronizationBarrier()");
+ return ret;
+ }
+ return 0;
+}
+
+int
+rte_thread_barrier_wait(rte_thread_barrier_t *barrier)
+{
+ return EnterSynchronizationBarrier(barrier,
+ SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY);
+}
+
+int
+rte_thread_barrier_destroy(rte_thread_barrier_t *barrier)
+{
+ DeleteSynchronizationBarrier(barrier);
+ return 0;
+}
+
+int
+rte_thread_cancel(rte_thread_t thread_id)
+{
+ int ret = 0;
+ HANDLE thread_handle = NULL;
+
+ thread_handle = OpenThread(THREAD_TERMINATE, FALSE, thread_id);
+ if (thread_handle == NULL) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("OpenThread()");
+ goto cleanup;
+ }
+
+ /*
+ * TODO: Behavior is different between POSIX and Windows threads.
+ * POSIX threads wait for a cancellation point.
+ * Current Windows emulation kills thread at any point.
+ */
+ ret = TerminateThread(thread_handle, 0);
+ if (ret != 0) {
+ ret = rte_thread_translate_win32_error(GetLastError());
+ RTE_LOG_WIN32_ERR("TerminateThread()");
+ goto cleanup;
+ }
+
+cleanup:
+ if (thread_handle != NULL) {
+ CloseHandle(thread_handle);
+ thread_handle = NULL;
+ }
+ return ret;
+}
+
int
rte_thread_tls_key_create(rte_tls_key *key,
__rte_unused void (*destructor)(void *))
@@ -18,13 +505,13 @@ rte_thread_tls_key_create(rte_tls_key *key,
*key = malloc(sizeof(**key));
if ((*key) == NULL) {
RTE_LOG(DEBUG, EAL, "Cannot allocate TLS key.\n");
- return -1;
+ return -ENOMEM;
}
(*key)->thread_index = TlsAlloc();
if ((*key)->thread_index == TLS_OUT_OF_INDEXES) {
RTE_LOG_WIN32_ERR("TlsAlloc()");
free(*key);
- return -1;
+ return rte_thread_translate_win32_error(GetLastError());;
}
return 0;
}
@@ -32,14 +519,14 @@ rte_thread_tls_key_create(rte_tls_key *key,
int
rte_thread_tls_key_delete(rte_tls_key key)
{
- if (!key) {
+ if (key == NULL) {
RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
- return -1;
+ return -EINVAL;
}
if (!TlsFree(key->thread_index)) {
RTE_LOG_WIN32_ERR("TlsFree()");
free(key);
- return -1;
+ return rte_thread_translate_win32_error(GetLastError());
}
free(key);
return 0;
@@ -50,7 +537,7 @@ rte_thread_tls_value_set(rte_tls_key key, const void *value)
{
char *p;
- if (!key) {
+ if (key == NULL) {
RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
return -1;
}
@@ -58,7 +545,7 @@ rte_thread_tls_value_set(rte_tls_key key, const void *value)
p = (char *) (uintptr_t) value;
if (!TlsSetValue(key->thread_index, p)) {
RTE_LOG_WIN32_ERR("TlsSetValue()");
- return -1;
+ return rte_thread_translate_win32_error(GetLastError());
}
return 0;
}
@@ -68,7 +555,7 @@ rte_thread_tls_value_get(rte_tls_key key)
{
void *output;
- if (!key) {
+ if (key == NULL) {
RTE_LOG(DEBUG, EAL, "Invalid TLS key.\n");
rte_errno = EINVAL;
return NULL;
--
2.30.0.vfs.0.2
next prev parent reply other threads:[~2021-03-18 1:01 UTC|newest]
Thread overview: 290+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-18 1:00 [dpdk-dev] [PATCH 0/3] eal: Add new API for threading Narcisa Ana Maria Vasile
2021-03-18 1:00 ` Narcisa Ana Maria Vasile [this message]
2021-03-18 14:48 ` [dpdk-dev] [PATCH 1/3] Add EAL threads API Tal Shnaiderman
2021-03-18 19:42 ` Narcisa Ana Maria Vasile
2021-03-18 20:04 ` Tyler Retzlaff
2021-03-18 15:48 ` David Marchand
2021-03-18 19:40 ` Narcisa Ana Maria Vasile
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 00/10] eal: Add new API for threading Narcisa Ana Maria Vasile
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 01/10] eal: add thread id and simple thread functions Narcisa Ana Maria Vasile
2021-03-23 2:54 ` Stephen Hemminger
2021-03-23 15:53 ` Tyler Retzlaff
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 03/10] windows/eal: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-03-23 0:20 ` [dpdk-dev] [PATCH v2 10/10] Enable the new EAL thread API Narcisa Ana Maria Vasile
2021-03-25 3:46 ` [dpdk-dev] [PATCH v3 00/10] eal: Add new API for threading Narcisa Ana Maria Vasile
2021-03-25 3:46 ` [dpdk-dev] [PATCH v3 01/10] eal: add thread id and simple thread functions Narcisa Ana Maria Vasile
2021-03-25 3:46 ` [dpdk-dev] [PATCH v3 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-03-25 3:46 ` [dpdk-dev] [PATCH v3 03/10] windows/eal: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-03-25 3:47 ` [dpdk-dev] [PATCH v3 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-03-25 3:47 ` [dpdk-dev] [PATCH v3 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-03-25 3:47 ` [dpdk-dev] [PATCH v3 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-03-25 3:47 ` [dpdk-dev] [PATCH v3 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-03-25 3:47 ` [dpdk-dev] [PATCH v3 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-03-25 3:47 ` [dpdk-dev] [PATCH v3 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-03-25 3:47 ` [dpdk-dev] [PATCH v3 10/10] Enable the new EAL thread API Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 00/10] eal: Add new API for threading Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 01/10] eal: add thread id and simple thread functions Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 03/10] windows/eal: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-03-27 16:04 ` Stephen Hemminger
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 00/10] eal: Add new API for threading Narcisa Ana Maria Vasile
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 01/10] eal: add thread id and simple thread functions Narcisa Ana Maria Vasile
2021-04-03 1:38 ` [dpdk-dev] [PATCH v6 00/10] eal: Add new API for threading Narcisa Ana Maria Vasile
2021-04-03 1:38 ` [dpdk-dev] [PATCH v6 01/10] eal: add thread id and simple thread functions Narcisa Ana Maria Vasile
2021-04-29 0:50 ` Dmitry Kozlyuk
2021-04-29 7:44 ` Thomas Monjalon
2021-04-29 12:05 ` Kinsella, Ray
2021-04-29 16:00 ` Tyler Retzlaff
2021-04-29 16:28 ` Dmitry Kozlyuk
2021-04-30 6:37 ` Narcisa Ana Maria Vasile
2021-04-03 1:39 ` [dpdk-dev] [PATCH v6 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-04-29 0:50 ` Dmitry Kozlyuk
2021-04-29 7:48 ` Thomas Monjalon
2021-04-29 15:52 ` [dpdk-dev] [EXTERNAL] " Tyler Retzlaff
2021-04-30 23:00 ` Dmitry Kozlyuk
2021-04-29 16:28 ` [dpdk-dev] " Dmitry Kozlyuk
2021-04-03 1:39 ` [dpdk-dev] [PATCH v6 03/10] windows/eal: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-04-29 0:50 ` Dmitry Kozlyuk
2021-04-30 2:39 ` Narcisa Ana Maria Vasile
2021-04-30 23:05 ` Dmitry Kozlyuk
2021-04-03 1:39 ` [dpdk-dev] [PATCH v6 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-05-02 0:41 ` Dmitry Kozlyuk
2021-04-03 1:39 ` [dpdk-dev] [PATCH v6 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-04-03 1:39 ` [dpdk-dev] [PATCH v6 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-04-29 20:44 ` Dmitry Kozlyuk
2021-04-29 21:31 ` [dpdk-dev] [EXTERNAL] " Dmitry Malloy
2021-04-30 17:22 ` Dmitry Kozlyuk
2021-04-30 17:51 ` Dmitry Kozlyuk
2021-04-03 1:39 ` [dpdk-dev] [PATCH v6 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-04-30 17:47 ` Dmitry Kozlyuk
2021-04-03 1:39 ` [dpdk-dev] [PATCH v6 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-04-30 18:06 ` Dmitry Kozlyuk
2021-04-03 1:39 ` [dpdk-dev] [PATCH v6 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-04-03 1:39 ` [dpdk-dev] [PATCH v6 10/10] Enable the new EAL thread API Narcisa Ana Maria Vasile
2021-04-12 7:56 ` [dpdk-dev] [PATCH v6 00/10] eal: Add new API for threading David Marchand
2021-04-16 20:30 ` Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 00/10] eal: Add EAL " Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 01/10] eal: add thread id and simple thread functions Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 03/10] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-06-01 20:55 ` [dpdk-dev] [PATCH v7 10/10] Enable the new EAL thread API Narcisa Ana Maria Vasile
2021-06-02 15:50 ` Tal Shnaiderman
2021-06-02 16:16 ` Narcisa Ana Maria Vasile
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 00/10] eal: Add EAL API for threading Narcisa Ana Maria Vasile
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 01/10] eal: add thread id and simple thread functions Narcisa Ana Maria Vasile
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 03/10] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-06-08 23:04 ` Dmitry Kozlyuk
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-06-04 23:38 ` [dpdk-dev] [PATCH v8 10/10] Enable the new EAL thread API Narcisa Ana Maria Vasile
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 00/10] eal: Add EAL API for threading Narcisa Ana Maria Vasile
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 01/10] eal: add thread id and simple thread functions Narcisa Ana Maria Vasile
2021-06-08 23:03 ` Dmitry Kozlyuk
2021-06-18 21:30 ` Narcisa Ana Maria Vasile
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-06-08 23:03 ` Dmitry Kozlyuk
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 03/10] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-06-08 23:03 ` Dmitry Kozlyuk
2021-06-18 21:44 ` Narcisa Ana Maria Vasile
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-06-08 23:04 ` Dmitry Kozlyuk
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-06-08 23:04 ` Dmitry Kozlyuk
2021-06-18 21:41 ` Narcisa Ana Maria Vasile
2021-06-18 22:48 ` Dmitry Kozlyuk
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-06-08 23:04 ` Dmitry Kozlyuk
2021-06-09 22:37 ` Dmitry Kozlyuk
2021-06-12 2:39 ` Narcisa Ana Maria Vasile
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-06-04 23:44 ` [dpdk-dev] [PATCH v9 10/10] Enable the new EAL thread API Narcisa Ana Maria Vasile
2021-06-08 5:50 ` Narcisa Ana Maria Vasile
2021-06-08 7:45 ` David Marchand
2021-06-18 21:53 ` Narcisa Ana Maria Vasile
2021-06-08 23:08 ` Dmitry Kozlyuk
2021-06-18 21:50 ` Narcisa Ana Maria Vasile
2021-06-18 21:26 ` [dpdk-dev] [PATCH v10 0/9] eal: Add EAL API for threading Narcisa Ana Maria Vasile
2021-06-18 21:26 ` [dpdk-dev] [PATCH v10 1/9] eal: add basic threading functions Narcisa Ana Maria Vasile
2021-06-18 21:26 ` [dpdk-dev] [PATCH v10 2/9] eal: add thread attributes Narcisa Ana Maria Vasile
2021-06-18 21:26 ` [dpdk-dev] [PATCH v10 3/9] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-06-18 21:26 ` [dpdk-dev] [PATCH v10 4/9] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-06-18 21:26 ` [dpdk-dev] [PATCH v10 5/9] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-06-18 21:26 ` [dpdk-dev] [PATCH v10 6/9] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-06-18 21:26 ` [dpdk-dev] [PATCH v10 7/9] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-06-18 21:26 ` [dpdk-dev] [PATCH v10 8/9] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-06-18 21:26 ` [dpdk-dev] [PATCH v10 9/9] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 00/10] eal: Add EAL API for threading Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 01/10] eal: add basic threading functions Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 03/10] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-07-30 22:31 ` [dpdk-dev] [PATCH v11 10/10] Add unit tests for thread API Narcisa Ana Maria Vasile
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 00/10] eal: Add EAL API for threading Narcisa Ana Maria Vasile
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 01/10] eal: add basic threading functions Narcisa Ana Maria Vasile
2021-08-02 21:08 ` Narcisa Ana Maria Vasile
2021-08-02 21:37 ` Dmitry Kozlyuk
2021-08-03 15:11 ` [dpdk-dev] [dpdk-ci] " Owen Hilyard
2021-08-03 15:38 ` Dmitry Kozlyuk
2021-08-03 15:57 ` Owen Hilyard
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 03/10] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-08-02 17:32 ` [dpdk-dev] [PATCH v12 10/10] Add unit tests for thread API Narcisa Ana Maria Vasile
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 00/10] eal: Add EAL API for threading Narcisa Ana Maria Vasile
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 01/10] eal: add basic threading functions Narcisa Ana Maria Vasile
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 03/10] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-08-15 19:56 ` Dmitry Kozlyuk
2021-08-18 21:28 ` Stephen Hemminger
2021-08-19 9:06 ` Bruce Richardson
2021-08-19 21:30 ` Narcisa Ana Maria Vasile
2021-08-19 21:33 ` Stephen Hemminger
2021-08-03 19:01 ` [dpdk-dev] [PATCH v13 10/10] Add unit tests for thread API Narcisa Ana Maria Vasile
2021-08-19 21:31 ` [dpdk-dev] [PATCH v14 0/9] eal: Add EAL API for threading Narcisa Ana Maria Vasile
2021-08-19 21:31 ` [dpdk-dev] [PATCH v14 1/9] eal: add basic threading functions Narcisa Ana Maria Vasile
2021-08-19 21:31 ` [dpdk-dev] [PATCH v14 2/9] eal: add thread attributes Narcisa Ana Maria Vasile
2021-08-19 21:31 ` [dpdk-dev] [PATCH v14 3/9] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-08-19 21:31 ` [dpdk-dev] [PATCH v14 4/9] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-08-19 21:31 ` [dpdk-dev] [PATCH v14 5/9] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-08-19 21:31 ` [dpdk-dev] [PATCH v14 6/9] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-08-19 21:31 ` [dpdk-dev] [PATCH v14 7/9] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-08-19 21:31 ` [dpdk-dev] [PATCH v14 8/9] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-08-19 21:31 ` [dpdk-dev] [PATCH v14 9/9] Add unit tests for thread API Narcisa Ana Maria Vasile
2021-08-20 16:10 ` Narcisa Ana Maria Vasile
2021-08-20 16:54 ` Dmitry Kozlyuk
2021-08-23 20:25 ` Dmitry Kozlyuk
2021-10-08 22:40 ` [dpdk-dev] [PATCH v15 0/9] eal: Add EAL API for threading Narcisa Ana Maria Vasile
2021-10-08 22:40 ` [dpdk-dev] [PATCH v15 1/9] eal: add basic threading functions Narcisa Ana Maria Vasile
2021-10-08 22:40 ` [dpdk-dev] [PATCH v15 2/9] eal: add thread attributes Narcisa Ana Maria Vasile
2021-10-08 22:40 ` [dpdk-dev] [PATCH v15 3/9] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-10-08 22:40 ` [dpdk-dev] [PATCH v15 4/9] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-10-08 22:40 ` [dpdk-dev] [PATCH v15 5/9] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-10-08 22:40 ` [dpdk-dev] [PATCH v15 6/9] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-10-08 22:40 ` [dpdk-dev] [PATCH v15 7/9] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-10-08 22:40 ` [dpdk-dev] [PATCH v15 8/9] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-10-08 22:40 ` [dpdk-dev] [PATCH v15 9/9] Add unit tests for thread API Narcisa Ana Maria Vasile
2021-10-09 7:41 ` [dpdk-dev] [PATCH v16 0/9] eal: Add EAL API for threading Narcisa Ana Maria Vasile
2021-10-09 7:41 ` [dpdk-dev] [PATCH v16 1/9] eal: add basic threading functions Narcisa Ana Maria Vasile
2021-10-12 16:09 ` Thomas Monjalon
2021-10-09 7:41 ` [dpdk-dev] [PATCH v16 2/9] eal: add thread attributes Narcisa Ana Maria Vasile
2021-10-12 16:12 ` Thomas Monjalon
2021-11-09 1:59 ` Narcisa Ana Maria Vasile
2021-11-09 8:27 ` Thomas Monjalon
2021-11-10 3:04 ` Narcisa Ana Maria Vasile
2021-11-10 3:59 ` Stephen Hemminger
2021-11-10 4:20 ` [EXTERNAL] " Tyler Retzlaff
2021-11-10 6:29 ` [dpdk-dev] [EXTERNAL] " Stephen Hemminger
2021-11-10 9:21 ` Bruce Richardson
2021-11-10 16:52 ` [EXTERNAL] Re: [dpdk-dev] " Tyler Retzlaff
2021-10-09 7:41 ` [dpdk-dev] [PATCH v16 3/9] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-10-12 16:16 ` Thomas Monjalon
2021-11-09 2:02 ` Narcisa Ana Maria Vasile
2021-11-09 8:21 ` Thomas Monjalon
2021-10-09 7:41 ` [dpdk-dev] [PATCH v16 4/9] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-10-12 16:20 ` Thomas Monjalon
2021-10-09 7:41 ` [dpdk-dev] [PATCH v16 5/9] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-10-09 7:41 ` [dpdk-dev] [PATCH v16 6/9] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-10-09 7:41 ` [dpdk-dev] [PATCH v16 7/9] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-10-12 16:28 ` Thomas Monjalon
2021-11-09 2:04 ` Narcisa Ana Maria Vasile
2021-10-09 7:41 ` [dpdk-dev] [PATCH v16 8/9] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-10-12 16:32 ` Thomas Monjalon
2021-11-09 2:07 ` Narcisa Ana Maria Vasile
2021-11-10 3:13 ` Narcisa Ana Maria Vasile
2021-10-09 7:41 ` [dpdk-dev] [PATCH v16 9/9] Add unit tests for thread API Narcisa Ana Maria Vasile
2021-10-12 16:33 ` Thomas Monjalon
2021-11-09 2:10 ` Narcisa Ana Maria Vasile
2021-11-09 8:32 ` Thomas Monjalon
2021-11-10 3:07 ` Narcisa Ana Maria Vasile
2021-10-12 16:07 ` [dpdk-dev] [PATCH v16 0/9] eal: Add EAL API for threading Thomas Monjalon
2021-11-09 1:55 ` Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 00/13] " Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 01/13] eal: add basic threading functions Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 02/13] eal: add thread attributes Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 03/13] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 04/13] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 05/13] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 06/13] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 07/13] app/test: add unit tests for rte_thread_self Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 08/13] app/test: add unit tests for thread attributes Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 09/13] app/test: add unit tests for thread lifetime management Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 10/13] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 11/13] app/test: add unit tests for barrier Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 12/13] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-11-10 3:01 ` [dpdk-dev] [PATCH v17 13/13] app/test: add unit tests for mutex Narcisa Ana Maria Vasile
2021-11-10 9:31 ` [dpdk-dev] [PATCH v17 00/13] eal: Add EAL API for threading Thomas Monjalon
2021-11-11 1:33 ` [PATCH v18 0/8] " Narcisa Ana Maria Vasile
2021-11-11 1:33 ` [PATCH v18 1/8] eal: add basic threading functions Narcisa Ana Maria Vasile
2022-04-12 18:00 ` Narcisa Ana Maria Vasile
2021-11-11 1:33 ` [PATCH v18 2/8] eal: add thread attributes Narcisa Ana Maria Vasile
2021-11-11 1:33 ` [PATCH v18 3/8] eal/windows: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-11-11 1:33 ` [PATCH v18 4/8] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-11-11 1:33 ` [PATCH v18 5/8] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-11-11 1:33 ` [PATCH v18 6/8] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-11-11 1:33 ` [PATCH v18 7/8] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-11-11 1:33 ` [PATCH v18 8/8] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-12-13 20:27 ` Narcisa Ana Maria Vasile
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 02/10] eal: add thread attributes Narcisa Ana Maria Vasile
2021-03-30 21:14 ` Stephen Hemminger
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 03/10] windows/eal: translate Windows errors to errno-style errors Narcisa Ana Maria Vasile
2021-03-31 13:56 ` Tal Shnaiderman
2021-03-31 21:19 ` Nick Connolly
2021-04-01 12:29 ` Tal Shnaiderman
2021-04-01 19:07 ` Narcisa Ana Maria Vasile
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 04/10] eal: implement functions for thread affinity management Narcisa Ana Maria Vasile
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 05/10] eal: implement thread priority management functions Narcisa Ana Maria Vasile
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 06/10] eal: add thread lifetime management Narcisa Ana Maria Vasile
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 07/10] eal: implement functions for mutex management Narcisa Ana Maria Vasile
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 08/10] eal: implement functions for thread barrier management Narcisa Ana Maria Vasile
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 09/10] eal: add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-03-30 21:11 ` Stephen Hemminger
2021-03-31 8:21 ` Tal Shnaiderman
2021-03-31 21:12 ` Dmitry Kozlyuk
2021-03-31 22:09 ` Stephen Hemminger
2021-03-31 22:42 ` [dpdk-dev] [EXTERNAL] " Dmitry Malloy
2021-03-29 22:40 ` [dpdk-dev] [PATCH v5 10/10] Enable the new EAL thread API Narcisa Ana Maria Vasile
2021-03-26 23:52 ` [dpdk-dev] [PATCH v4 " Narcisa Ana Maria Vasile
2021-03-18 1:00 ` [dpdk-dev] [PATCH 2/3] Add EAL argument for setting thread priority Narcisa Ana Maria Vasile
2021-03-18 1:00 ` [dpdk-dev] [PATCH 3/3] Enable the new EAL thread API and rename Narcisa Ana Maria Vasile
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=1616029240-26588-2-git-send-email-navasile@linux.microsoft.com \
--to=navasile@linux.microsoft.com \
--cc=bruce.richardson@intel.com \
--cc=david.marchand@redhat.com \
--cc=dev@dpdk.org \
--cc=dmitry.kozliuk@gmail.com \
--cc=dmitrym@microsoft.com \
--cc=khot@microsoft.com \
--cc=navasile@microsoft.com \
--cc=ocardona@microsoft.com \
--cc=pallavi.kadam@intel.com \
--cc=roretzla@microsoft.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).