From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9C2B0A034F; Wed, 10 Nov 2021 04:03:03 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6017B41158; Wed, 10 Nov 2021 04:02:01 +0100 (CET) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mails.dpdk.org (Postfix) with ESMTP id C0023410EF for ; Wed, 10 Nov 2021 04:01:47 +0100 (CET) Received: by linux.microsoft.com (Postfix, from userid 1059) id 8FC4520C3561; Tue, 9 Nov 2021 19:01:46 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8FC4520C3561 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1636513306; bh=taJMkznpuNAPaTITy+ZnedizcEWded0CO/uk4n/YmDo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Nto74KlzumhkVx8FP/99s2DytpSVHxhPtIHhGmGdtgXXakkFcdEOjqE4TwlUOFAj6 ih62RANVfqvNgb4bsNPvqj3WhwGlFVOFifKVHmZMQ7WrpRS+eLm8vuz7BoTd+1+XW/ 3ACXDx/YI1293VefCMBRdO0Lb6HmWXhX/P9jJWDU= 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: Tue, 9 Nov 2021 19:01:41 -0800 Message-Id: <1636513302-7359-13-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 12/13] 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, trylock. Windows does not have a static initializer. Initialization is only done through InitializeCriticalSection(). To overcome this, RTE_INIT_MUTEX macro is added to replace static initialization of mutexes. The macro calls rte_thread_mutex_init(). Signed-off-by: Narcisa Vasile --- lib/eal/common/rte_thread.c | 69 +++++++++++++++++++++++++++++ lib/eal/include/rte_thread.h | 85 ++++++++++++++++++++++++++++++++++++ lib/eal/version.map | 5 +++ lib/eal/windows/rte_thread.c | 64 +++++++++++++++++++++++++++ 4 files changed, 223 insertions(+) diff --git a/lib/eal/common/rte_thread.c b/lib/eal/common/rte_thread.c index 30e2ca79d1..580448d8bf 100644 --- a/lib/eal/common/rte_thread.c +++ b/lib/eal/common/rte_thread.c @@ -295,6 +295,75 @@ 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_try_lock(rte_thread_mutex *mutex) +{ + RTE_VERIFY(mutex != NULL); + + return pthread_mutex_trylock((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_barrier_init(rte_thread_barrier *barrier, int count) { diff --git a/lib/eal/include/rte_thread.h b/lib/eal/include/rte_thread.h index 7c84e32988..09a5fd8add 100644 --- a/lib/eal/include/rte_thread.h +++ b/lib/eal/include/rte_thread.h @@ -54,6 +54,25 @@ 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_INIT_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; + /** * Returned by rte_thread_barrier_wait() when call is successful. */ @@ -314,6 +333,72 @@ __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); + +/** + * Tries to lock a mutex.If the mutex is already held by a different thread, + * the function returns without blocking. + * + * @param mutex + * The mutex that will be acquired, if not already locked. + * + * @return + * On success, if the mutex is acquired, return 0. + * On failure, return a positive errno-style error number. + */ +__rte_experimental +int rte_thread_mutex_try_lock(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); + /** * Initializes a synchronization barrier. * diff --git a/lib/eal/version.map b/lib/eal/version.map index 06e5f82da2..e80eea4316 100644 --- a/lib/eal/version.map +++ b/lib/eal/version.map @@ -431,6 +431,11 @@ EXPERIMENTAL { rte_thread_barrier_wait; rte_thread_barrier_destroy; rte_thread_get_affinity_by_id; + rte_thread_mutex_init; + rte_thread_mutex_lock; + rte_thread_mutex_unlock; + rte_thread_mutex_try_lock; + rte_thread_mutex_destroy; rte_thread_set_affinity_by_id; rte_thread_get_priority; rte_thread_set_priority; diff --git a/lib/eal/windows/rte_thread.c b/lib/eal/windows/rte_thread.c index 3f72bbf716..11b4863fe8 100644 --- a/lib/eal/windows/rte_thread.c +++ b/lib/eal/windows/rte_thread.c @@ -504,6 +504,70 @@ 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_try_lock(rte_thread_mutex *mutex) +{ + RTE_VERIFY(mutex != NULL); + + if (TryEnterCriticalSection(mutex->mutex_id) != 0) + return 0; + + return EBUSY; +} + +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_barrier_init(rte_thread_barrier *barrier, int count) { -- 2.31.0.vfs.0.1