From patchwork Fri Jul 30 22:31:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Narcisa Ana Maria Vasile X-Patchwork-Id: 96486 Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 71879A0C40; Sat, 31 Jul 2021 00:32:38 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C966E41147; Sat, 31 Jul 2021 00:32:07 +0200 (CEST) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mails.dpdk.org (Postfix) with ESMTP id 77AED40E28 for ; Sat, 31 Jul 2021 00:32:00 +0200 (CEST) Received: by linux.microsoft.com (Postfix, from userid 1059) id 2464E20B26FD; Fri, 30 Jul 2021 15:31:58 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 2464E20B26FD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1627684319; bh=NYhOGcODzwpc4td2qryoZNmEL57zhuuK3mKCpPNyP7s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ahzfuyq/GDDTE44CjTiyLRBuJgLtOafcuho7267kJ+6BHKwgX9aNpb4PpKbXUT/2G ns+rfydaLrEVRDs85GgTWQjUDQklluufg76cVmTCRLaXa3s0V6JYZpaBlljJVvSLuD /feqmoYVPdd1l0Pz9U1dxYVlyfEUW57Kah409ow4= From: Narcisa Ana Maria Vasile 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: Fri, 30 Jul 2021 15:31:49 -0700 Message-Id: <1627684312-28630-8-git-send-email-navasile@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1627684312-28630-1-git-send-email-navasile@linux.microsoft.com> References: <1624051606-26779-1-git-send-email-navasile@linux.microsoft.com> <1627684312-28630-1-git-send-email-navasile@linux.microsoft.com> Subject: [dpdk-dev] [PATCH v11 07/10] eal: implement functions for mutex management X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Narcisa Vasile Add functions for mutex init, destroy, lock, unlock. Add RTE_STATIC_MUTEX macro to replace static initialization of mutexes. Windows does not have a static initializer. Initialization is only done through InitializeCriticalSection(). The RTE_STATIC_MUTEX calls into the rte_thread_mutex_init() function that performs the actual mutex initialization. Signed-off-by: Narcisa Vasile --- lib/eal/common/rte_thread.c | 61 +++++++++++++++++++++++ lib/eal/include/rte_thread.h | 94 ++++++++++++++++++++++++++++++++++++ lib/eal/version.map | 4 ++ lib/eal/windows/rte_thread.c | 53 ++++++++++++++++++++ 4 files changed, 212 insertions(+) diff --git a/lib/eal/common/rte_thread.c b/lib/eal/common/rte_thread.c index a0a51bc190..ebae4a8af1 100644 --- a/lib/eal/common/rte_thread.c +++ b/lib/eal/common/rte_thread.c @@ -251,6 +251,67 @@ rte_thread_detach(rte_thread_t thread_id) return pthread_detach((pthread_t)thread_id.opaque_id); } +int +rte_thread_mutex_init(rte_thread_mutex *mutex) +{ + int ret = 0; + pthread_mutex_t *m = NULL; + + RTE_VERIFY(mutex != NULL); + + m = calloc(1, sizeof(*m)); + if (m == NULL) { + RTE_LOG(DEBUG, EAL, "Unable to initialize mutex. Insufficient memory!\n"); + ret = ENOMEM; + goto cleanup; + } + + ret = pthread_mutex_init(m, NULL); + if (ret != 0) { + RTE_LOG(DEBUG, EAL, "Failed to init mutex. ret = %d\n", ret); + goto cleanup; + } + + mutex->mutex_id = m; + m = NULL; + +cleanup: + free(m); + return ret; +} + +int +rte_thread_mutex_lock(rte_thread_mutex *mutex) +{ + RTE_VERIFY(mutex != NULL); + + return pthread_mutex_lock((pthread_mutex_t *)mutex->mutex_id); +} + +int +rte_thread_mutex_unlock(rte_thread_mutex *mutex) +{ + RTE_VERIFY(mutex != NULL); + + return pthread_mutex_unlock((pthread_mutex_t *)mutex->mutex_id); +} + +int +rte_thread_mutex_destroy(rte_thread_mutex *mutex) +{ + int ret = 0; + RTE_VERIFY(mutex != NULL); + + ret = pthread_mutex_destroy((pthread_mutex_t *)mutex->mutex_id); + if (ret != 0) + RTE_LOG(DEBUG, EAL, "Unable to destroy mutex, ret = %d\n", ret); + + free(mutex->mutex_id); + mutex->mutex_id = NULL; + + return ret; +} + int rte_thread_key_create(rte_thread_key *key, void (*destructor)(void *)) { diff --git a/lib/eal/include/rte_thread.h b/lib/eal/include/rte_thread.h index 098c3ba343..7e813b573d 100644 --- a/lib/eal/include/rte_thread.h +++ b/lib/eal/include/rte_thread.h @@ -56,6 +56,26 @@ typedef struct { #endif /* RTE_HAS_CPUSET */ +#define RTE_DECLARE_MUTEX(private_lock) rte_thread_mutex private_lock + +#define RTE_DEFINE_MUTEX(private_lock)\ +RTE_INIT(__rte_ ## private_lock ## _init)\ +{\ + RTE_VERIFY(rte_thread_mutex_init(&private_lock) == 0);\ +} + +#define RTE_STATIC_MUTEX(private_lock)\ +static RTE_DECLARE_MUTEX(private_lock);\ +RTE_DEFINE_MUTEX(private_lock) + + +/** + * Thread mutex representation. + */ +typedef struct rte_thread_mutex_tag { + void *mutex_id; /**< mutex identifier */ +} rte_thread_mutex; + /** * TLS key type, an opaque pointer. */ @@ -268,6 +288,28 @@ int rte_thread_join(rte_thread_t thread_id, unsigned long *value_ptr); __rte_experimental int rte_thread_detach(rte_thread_t thread_id); +/** + * Set core affinity of the current thread. + * Support both EAL and non-EAL thread and update TLS. + * + * @param cpusetp + * Pointer to CPU affinity to set. + * + * @return + * On success, return 0; otherwise return -1; + */ +int rte_thread_set_affinity(rte_cpuset_t *cpusetp); + +/** + * Get core affinity of the current thread. + * + * @param cpusetp + * Pointer to CPU affinity of current thread. + * It presumes input is not NULL, otherwise it causes panic. + * + */ +void rte_thread_get_affinity(rte_cpuset_t *cpusetp); + #endif /* RTE_HAS_CPUSET */ /** @@ -287,6 +329,58 @@ __rte_experimental int rte_thread_set_priority(rte_thread_t thread_id, enum rte_thread_priority priority); +/** + * Initializes a mutex. + * + * @param mutex + * The mutex to be initialized. + * + * @return + * On success, return 0. + * On failure, return a positive errno-style error number. + */ +__rte_experimental +int rte_thread_mutex_init(rte_thread_mutex *mutex); + +/** + * Locks a mutex. + * + * @param mutex + * The mutex to be locked. + * + * @return + * On success, return 0. + * On failure, return a positive errno-style error number. + */ +__rte_experimental +int rte_thread_mutex_lock(rte_thread_mutex *mutex); + +/** + * Unlocks a mutex. + * + * @param mutex + * The mutex to be unlocked. + * + * @return + * On success, return 0. + * On failure, return a positive errno-style error number. + */ +__rte_experimental +int rte_thread_mutex_unlock(rte_thread_mutex *mutex); + +/** + * Releases all resources associated with a mutex. + * + * @param mutex + * The mutex to be uninitialized. + * + * @return + * On success, return 0. + * On failure, return a positive errno-style error number. + */ +__rte_experimental +int rte_thread_mutex_destroy(rte_thread_mutex *mutex); + /** * Create a TLS data key visible to all threads in the process. * the created key is later used to get/set a value. diff --git a/lib/eal/version.map b/lib/eal/version.map index 02994dd3fb..a1c7a8e87d 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -439,6 +439,10 @@ EXPERIMENTAL { rte_thread_create; rte_thread_join; rte_thread_detach; + rte_thread_mutex_init; + rte_thread_mutex_lock; + rte_thread_mutex_unlock; + rte_thread_mutex_destroy; }; INTERNAL { diff --git a/lib/eal/windows/rte_thread.c b/lib/eal/windows/rte_thread.c index e5e420fadd..23f00cfba2 100644 --- a/lib/eal/windows/rte_thread.c +++ b/lib/eal/windows/rte_thread.c @@ -447,6 +447,59 @@ rte_thread_detach(rte_thread_t thread_id) return 0; } +int +rte_thread_mutex_init(rte_thread_mutex *mutex) +{ + int ret = 0; + CRITICAL_SECTION *m = NULL; + + RTE_VERIFY(mutex != NULL); + + m = calloc(1, sizeof(*m)); + if (m == NULL) { + RTE_LOG(DEBUG, EAL, "Unable to initialize mutex. Insufficient memory!\n"); + ret = ENOMEM; + goto cleanup; + } + + InitializeCriticalSection(m); + mutex->mutex_id = m; + m = NULL; + +cleanup: + return ret; +} + +int +rte_thread_mutex_lock(rte_thread_mutex *mutex) +{ + RTE_VERIFY(mutex != NULL); + + EnterCriticalSection(mutex->mutex_id); + return 0; +} + +int +rte_thread_mutex_unlock(rte_thread_mutex *mutex) +{ + RTE_VERIFY(mutex != NULL); + + LeaveCriticalSection(mutex->mutex_id); + return 0; +} + +int +rte_thread_mutex_destroy(rte_thread_mutex *mutex) +{ + RTE_VERIFY(mutex != NULL); + + DeleteCriticalSection(mutex->mutex_id); + free(mutex->mutex_id); + mutex->mutex_id = NULL; + + return 0; +} + int rte_thread_key_create(rte_thread_key *key, __rte_unused void (*destructor)(void *))