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 EFA89A0A0F; Sat, 5 Jun 2021 01:39:23 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 50B2141120; Sat, 5 Jun 2021 01:39:03 +0200 (CEST) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mails.dpdk.org (Postfix) with ESMTP id 176A1410FE for ; Sat, 5 Jun 2021 01:38:58 +0200 (CEST) Received: by linux.microsoft.com (Postfix, from userid 1059) id 7A06720B800D; Fri, 4 Jun 2021 16:38:57 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 7A06720B800D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1622849937; bh=seQWra0TuyII/9wCkbzoTnOUUvIjtpUMbtuWx/mtsyk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=evG1kDIS/AZzJJm9Lw7qweuz9CfWnKVs5POmr0V39zhjJQHBVWJyBu+TQfhHwSZaV EFBG0RUgHWeYRapmw0w9Z+VN+49z4Dh7YxXgQHn5uwbQe2qY1efnp5ttDtA2nILg9O UxOml+lKUb9a7nfTplfpoqVQ4OB5KX56lB9uVmgs= 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, 4 Jun 2021 16:38:25 -0700 Message-Id: <1622849908-5710-8-git-send-email-navasile@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1622849908-5710-1-git-send-email-navasile@linux.microsoft.com> References: <1622580952-25169-1-git-send-email-navasile@linux.microsoft.com> <1622849908-5710-1-git-send-email-navasile@linux.microsoft.com> Subject: [dpdk-dev] [PATCH v8 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. On Linux, static initialization of a mutex is possible through PTHREAD_MUTEX_INITIALIZER. Windows does not have a static initializer. Initialization is only done through InitializeCriticalSection(). To simulate static initialization, a fake initializator has been added: The rte_mutex_lock() function will verify if the mutex has been initialized using this fake initializer and if so, it will perform additional initialization. --- lib/eal/common/rte_thread.c | 24 ++++++ lib/eal/include/rte_thread.h | 53 ++++++++++++ lib/eal/include/rte_thread_types.h | 4 + .../include/rte_windows_thread_types.h | 9 ++ lib/eal/windows/rte_thread.c | 83 ++++++++++++++++++- 5 files changed, 172 insertions(+), 1 deletion(-) diff --git a/lib/eal/common/rte_thread.c b/lib/eal/common/rte_thread.c index 84050d0f4c..4d7d9242a9 100644 --- a/lib/eal/common/rte_thread.c +++ b/lib/eal/common/rte_thread.c @@ -249,6 +249,30 @@ rte_thread_join(rte_thread_t thread_id, int *value_ptr) 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_cancel(rte_thread_t thread_id) { /* diff --git a/lib/eal/include/rte_thread.h b/lib/eal/include/rte_thread.h index 1d481b9ad5..db8ef20930 100644 --- a/lib/eal/include/rte_thread.h +++ b/lib/eal/include/rte_thread.h @@ -248,6 +248,58 @@ int rte_thread_create(rte_thread_t *thread_id, __rte_experimental int rte_thread_join(rte_thread_t thread_id, int *value_ptr); +/** + * 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_t *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_t *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_t *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_t *mutex); + /** * Terminates a thread. * @@ -283,6 +335,7 @@ int rte_thread_detach(rte_thread_t thread_id); * * @param cpusetp * Pointer to CPU affinity to set. + * * @return * On success, return 0; otherwise return -1; */ diff --git a/lib/eal/include/rte_thread_types.h b/lib/eal/include/rte_thread_types.h index d67b24a563..7bb0d2948c 100644 --- a/lib/eal/include/rte_thread_types.h +++ b/lib/eal/include/rte_thread_types.h @@ -7,4 +7,8 @@ #include +#define RTE_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +typedef pthread_mutex_t rte_thread_mutex_t; + #endif /* _RTE_THREAD_TYPES_H_ */ diff --git a/lib/eal/windows/include/rte_windows_thread_types.h b/lib/eal/windows/include/rte_windows_thread_types.h index 60e6d94553..c6c8502bfb 100644 --- a/lib/eal/windows/include/rte_windows_thread_types.h +++ b/lib/eal/windows/include/rte_windows_thread_types.h @@ -7,4 +7,13 @@ #include +#define WINDOWS_MUTEX_INITIALIZER (void*)-1 +#define RTE_THREAD_MUTEX_INITIALIZER {WINDOWS_MUTEX_INITIALIZER} + +struct thread_mutex_t { + void* mutex_id; +}; + +typedef struct thread_mutex_t rte_thread_mutex_t; + #endif /* _RTE_THREAD_TYPES_H_ */ diff --git a/lib/eal/windows/rte_thread.c b/lib/eal/windows/rte_thread.c index 5afdd54e15..239aa6be5d 100644 --- a/lib/eal/windows/rte_thread.c +++ b/lib/eal/windows/rte_thread.c @@ -470,6 +470,88 @@ rte_thread_join(rte_thread_t thread_id, int *value_ptr) return ret; } +int +rte_thread_mutex_init(rte_thread_mutex_t *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_t *mutex) +{ + int ret = 0; + void* id = 0; + rte_thread_mutex_t m; + + RTE_VERIFY(mutex != NULL); + + /* Check if mutex has been statically initialized */ + id = InterlockedCompareExchangePointer(&mutex->mutex_id, mutex->mutex_id, WINDOWS_MUTEX_INITIALIZER); + /* If mutex has been statically initialized */ + if (id == WINDOWS_MUTEX_INITIALIZER) { + ret = rte_thread_mutex_init(&m); + if (ret != 0) { + return ret; + } + + id = InterlockedCompareExchangePointer(&mutex->mutex_id, m.mutex_id, WINDOWS_MUTEX_INITIALIZER); + /* If meanwhile the mutex was initialized by a different thread, + * destroy the local initialization. + */ + if (id != WINDOWS_MUTEX_INITIALIZER) { + rte_thread_mutex_destroy(&m); + } + } + + EnterCriticalSection(mutex->mutex_id); + + return 0; +} + +int +rte_thread_mutex_unlock(rte_thread_mutex_t *mutex) +{ + RTE_VERIFY(mutex != NULL); + + LeaveCriticalSection(mutex->mutex_id); + return 0; +} + +int +rte_thread_mutex_destroy(rte_thread_mutex_t *mutex) +{ + RTE_VERIFY(mutex != NULL); + + if (mutex->mutex_id == WINDOWS_MUTEX_INITIALIZER) { + goto cleanup; + } + + DeleteCriticalSection(mutex->mutex_id); + free(mutex->mutex_id); + +cleanup: + mutex->mutex_id = NULL; + + return 0; +} + int rte_thread_cancel(rte_thread_t thread_id) { @@ -549,7 +631,6 @@ rte_thread_key_delete(rte_thread_key key) int rte_thread_value_set(rte_thread_key key, const void *value) { - int ret; char *p; if (key == NULL) { -- 2.31.0.vfs.0.1