From 906e865cc771eb9824a617f1445123abd9f32db7 Mon Sep 17 00:00:00 2001 From: zhangyuan21 Date: Mon, 6 Mar 2023 18:17:40 +0800 Subject: [PATCH 1/2] sched/mutex: Move nxmutex to sched 1. Move nxmutex to sched and directly depends on the nxsem; 2. Mutex is not cancellation point, delete cancellation point check; Signed-off-by: zhangyuan21 --- include/nuttx/mutex.h | 55 +- include/sys/syscall_lookup.h | 7 + libs/libc/Makefile | 1 + libs/libc/misc/Make.defs | 2 +- libs/libc/misc/lib_mutex.c | 765 ---------------------------- libs/libc/mutex/Make.defs | 31 ++ libs/libc/mutex/mutex_breaklock.c | 105 ++++ libs/libc/mutex/mutex_destroy.c | 56 ++ libs/libc/mutex/mutex_init.c | 86 ++++ libs/libc/mutex/mutex_is_hold.c | 50 ++ libs/libc/mutex/mutex_is_locked.c | 53 ++ libs/libc/mutex/mutex_lock.c | 68 +++ libs/libc/mutex/mutex_reset.c | 46 ++ libs/libc/mutex/mutex_restorelock.c | 85 ++++ libs/libc/mutex/mutex_timedlock.c | 74 +++ libs/libc/mutex/mutex_trylock.c | 72 +++ libs/libc/mutex/mutex_unlock.c | 70 +++ sched/Makefile | 1 + sched/mutex/Make.defs | 29 ++ sched/mutex/mutex_destroy.c | 55 ++ sched/mutex/mutex_lock.c | 77 +++ sched/mutex/mutex_reset.c | 46 ++ sched/mutex/mutex_timedlock.c | 75 +++ sched/mutex/mutex_trylock.c | 69 +++ sched/mutex/mutex_unlock.c | 74 +++ syscall/syscall.csv | 6 + 26 files changed, 1277 insertions(+), 781 deletions(-) delete mode 100644 libs/libc/misc/lib_mutex.c create mode 100644 libs/libc/mutex/Make.defs create mode 100644 libs/libc/mutex/mutex_breaklock.c create mode 100644 libs/libc/mutex/mutex_destroy.c create mode 100644 libs/libc/mutex/mutex_init.c create mode 100644 libs/libc/mutex/mutex_is_hold.c create mode 100644 libs/libc/mutex/mutex_is_locked.c create mode 100644 libs/libc/mutex/mutex_lock.c create mode 100644 libs/libc/mutex/mutex_reset.c create mode 100644 libs/libc/mutex/mutex_restorelock.c create mode 100644 libs/libc/mutex/mutex_timedlock.c create mode 100644 libs/libc/mutex/mutex_trylock.c create mode 100644 libs/libc/mutex/mutex_unlock.c create mode 100644 sched/mutex/Make.defs create mode 100644 sched/mutex/mutex_destroy.c create mode 100644 sched/mutex/mutex_lock.c create mode 100644 sched/mutex/mutex_reset.c create mode 100644 sched/mutex/mutex_timedlock.c create mode 100644 sched/mutex/mutex_trylock.c create mode 100644 sched/mutex/mutex_unlock.c diff --git a/include/nuttx/mutex.h b/include/nuttx/mutex.h index f92a9d344bf7c..9ac668ef28e26 100644 --- a/include/nuttx/mutex.h +++ b/include/nuttx/mutex.h @@ -34,13 +34,17 @@ * Pre-processor Definitions ****************************************************************************/ -#define NXMUTEX_NO_HOLDER ((pid_t)-1) -#define NXMUTEX_INITIALIZER {NXSEM_INITIALIZER(1, SEM_TYPE_MUTEX | \ - SEM_PRIO_INHERIT), NXMUTEX_NO_HOLDER} -#define NXRMUTEX_INITIALIZER {NXMUTEX_INITIALIZER, 0} +#define NXMUTEX_NO_HOLDER ((pid_t)-1) +#define NXMUTEX_RESET ((pid_t)-2) + +#define NXMUTEX_INITIALIZER {NXSEM_INITIALIZER(1, SEM_TYPE_MUTEX | \ + SEM_PRIO_INHERIT), NXMUTEX_NO_HOLDER} +#define NXRMUTEX_INITIALIZER {NXMUTEX_INITIALIZER, 0} + +#define NXMUTEX_HOLDER(m) ((m)->holder) /**************************************************************************** - * Public Type Definitions + * Public Type Declarations ****************************************************************************/ struct mutex_s @@ -126,11 +130,28 @@ int nxmutex_destroy(FAR mutex_t *mutex); * mutex - mutex descriptor. * * Return Value: + * Return true if mutex is hold by current thread. * ****************************************************************************/ bool nxmutex_is_hold(FAR mutex_t *mutex); +/**************************************************************************** + * Name: nxmutex_is_reset + * + * Description: + * This function check whether the mutex is be reset + * + * Parameters: + * mutex - mutex descriptor. + * + * Return Value: + * Return true if mutex is be reset. + * + ****************************************************************************/ + +#define nxmutex_is_reset(mutex) (NXMUTEX_HOLDER(mutex) == NXMUTEX_RESET) + /**************************************************************************** * Name: nxmutex_is_locked * @@ -141,6 +162,7 @@ bool nxmutex_is_hold(FAR mutex_t *mutex); * mutex - mutex descriptor. * * Return Value: + * Return true if mutex is locked. * ****************************************************************************/ @@ -195,7 +217,7 @@ int nxmutex_trylock(FAR mutex_t *mutex); * Name: nxmutex_timedlock * * Description: - * This function attempts to lock the mutex . If the mutex value + * This function attempts to lock the mutex. If the mutex value * is (<=) zero,then the calling task will not return until it * successfully acquires the lock or timed out * @@ -250,9 +272,7 @@ int nxmutex_unlock(FAR mutex_t *mutex); * ****************************************************************************/ -#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) void nxmutex_reset(FAR mutex_t *mutex); -#endif /**************************************************************************** * Name: nxmutex_breaklock @@ -260,8 +280,10 @@ void nxmutex_reset(FAR mutex_t *mutex); * Description: * This function attempts to break the mutex * - * Parameters: + * Input Parameters: * mutex - Mutex descriptor. + * + * Output Parameters: * locked - Is the mutex break success * * Return Value: @@ -347,7 +369,7 @@ int nxrmutex_destroy(FAR rmutex_t *rmutex); * ****************************************************************************/ -bool nxrmutex_is_hold(FAR rmutex_t *rmutex); +#define nxrmutex_is_hold(rmutex) nxmutex_is_hold(&(rmutex)->mutex) /**************************************************************************** * Name: nxrmutex_is_locked @@ -363,7 +385,7 @@ bool nxrmutex_is_hold(FAR rmutex_t *rmutex); * ****************************************************************************/ -bool nxrmutex_is_locked(FAR rmutex_t *rmutex); +#define nxrmutex_is_locked(rmutex) nxmutex_is_locked(&(rmutex)->mutex) /**************************************************************************** * Name: nrxmutex_lock @@ -415,7 +437,7 @@ int nxrmutex_trylock(FAR rmutex_t *rmutex); * Name: nxrmutex_timedlock * * Description: - * This function attempts to lock the mutex . If the mutex value + * This function attempts to lock the mutex. If the mutex value * is (<=) zero,then the calling task will not return until it * successfully acquires the lock or timed out * @@ -471,9 +493,8 @@ int nxrmutex_unlock(FAR rmutex_t *rmutex); * rmutex - rmutex descriptor. * ****************************************************************************/ -#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) + void nxrmutex_reset(FAR rmutex_t *rmutex); -#endif /**************************************************************************** * Name: nrxmutex_breaklock @@ -481,9 +502,12 @@ void nxrmutex_reset(FAR rmutex_t *rmutex); * Description: * This function attempts to break the recursive mutex * - * Parameters: + * Input Parameters: * rmutex - Recursive mutex descriptor. * + * Output Parameters: + * count - Return the count value before break. + * * Return Value: * This is an internal OS interface and should not be used by applications. * It follows the NuttX internal error return policy: Zero (OK) is @@ -502,6 +526,7 @@ int nxrmutex_breaklock(FAR rmutex_t *rmutex, FAR unsigned int *count); * * Parameters: * rmutex - Recursive mutex descriptor. + * count - Count after restore. * * Return Value: * This is an internal OS interface and should not be used by applications. diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h index 69446104d6797..402684b1d7f25 100644 --- a/include/sys/syscall_lookup.h +++ b/include/sys/syscall_lookup.h @@ -380,3 +380,10 @@ SYSCALL_LOOKUP(munmap, 2) #ifdef CONFIG_CRYPTO_RANDOM_POOL SYSCALL_LOOKUP(arc4random_buf, 2) #endif + +SYSCALL_LOOKUP(nxmutex_breaklock, 2) +SYSCALL_LOOKUP(nxmutex_destroy, 1) +SYSCALL_LOOKUP(nxmutex_lock, 1) +SYSCALL_LOOKUP(nxmutex_timedlock, 2) +SYSCALL_LOOKUP(nxmutex_trylock, 1) +SYSCALL_LOOKUP(nxmutex_unlock, 1) diff --git a/libs/libc/Makefile b/libs/libc/Makefile index 6f0d14abb3da6..ffbff0465bd80 100644 --- a/libs/libc/Makefile +++ b/libs/libc/Makefile @@ -39,6 +39,7 @@ include lzf/Make.defs include machine/Make.defs include misc/Make.defs include modlib/Make.defs +include mutex/Make.defs include net/Make.defs include netdb/Make.defs include obstack/Make.defs diff --git a/libs/libc/misc/Make.defs b/libs/libc/misc/Make.defs index 3a52b25b11903..e0e817a3983e7 100644 --- a/libs/libc/misc/Make.defs +++ b/libs/libc/misc/Make.defs @@ -22,7 +22,7 @@ CSRCS += lib_mknod.c lib_umask.c lib_utsname.c lib_getrandom.c CSRCS += lib_xorshift128.c lib_tea_encrypt.c lib_tea_decrypt.c -CSRCS += lib_cxx_initialize.c lib_impure.c lib_memfd.c lib_mutex.c +CSRCS += lib_cxx_initialize.c lib_impure.c lib_memfd.c CSRCS += lib_fchmodat.c lib_fstatat.c lib_getfullpath.c lib_openat.c CSRCS += lib_mkdirat.c lib_utimensat.c diff --git a/libs/libc/misc/lib_mutex.c b/libs/libc/misc/lib_mutex.c deleted file mode 100644 index 4e8f53d484ca2..0000000000000 --- a/libs/libc/misc/lib_mutex.c +++ /dev/null @@ -1,765 +0,0 @@ -/**************************************************************************** - * libs/libc/misc/lib_mutex.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define NXMUTEX_RESET ((pid_t)-2) - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nxmutex_is_reset - * - * Description: - * This function check whether the mutex is reset - * - * Parameters: - * mutex - mutex descriptor. - * - * Return Value: - * - ****************************************************************************/ - -static bool nxmutex_is_reset(FAR mutex_t *mutex) -{ - return mutex->holder == NXMUTEX_RESET; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nxmutex_init - * - * Description: - * This function initializes the UNNAMED mutex. Following a - * successful call to nxmutex_init(), the mutex may be used in subsequent - * calls to nxmutex_lock(), nxmutex_unlock(), and nxmutex_trylock(). The - * mutex remains usable until it is destroyed. - * - * Parameters: - * mutex - Semaphore to be initialized - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * - ****************************************************************************/ - -int nxmutex_init(FAR mutex_t *mutex) -{ - int ret = _SEM_INIT(&mutex->sem, 0, 1); - - if (ret < 0) - { - return _SEM_ERRVAL(ret); - } - - mutex->holder = NXMUTEX_NO_HOLDER; - _SEM_SETPROTOCOL(&mutex->sem, SEM_TYPE_MUTEX | SEM_PRIO_INHERIT); - return ret; -} - -/**************************************************************************** - * Name: nxmutex_destroy - * - * Description: - * This function initializes the UNNAMED mutex. Following a - * successful call to nxmutex_init(), the mutex may be used in subsequent - * calls to nxmutex_lock(), nxmutex_unlock(), and nxmutex_trylock(). The - * mutex remains usable until it is destroyed. - * - * Parameters: - * mutex - Semaphore to be destroyed - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * - ****************************************************************************/ - -int nxmutex_destroy(FAR mutex_t *mutex) -{ - int ret = _SEM_DESTROY(&mutex->sem); - - if (ret < 0) - { - return _SEM_ERRVAL(ret); - } - - mutex->holder = NXMUTEX_NO_HOLDER; - return ret; -} - -/**************************************************************************** - * Name: nxmutex_is_hold - * - * Description: - * This function check whether the caller hold the mutex - * referenced by 'mutex'. - * - * Parameters: - * mutex - mutex descriptor. - * - * Return Value: - * - ****************************************************************************/ - -bool nxmutex_is_hold(FAR mutex_t *mutex) -{ - return mutex->holder == _SCHED_GETTID(); -} - -/**************************************************************************** - * Name: nxmutex_is_locked - * - * Description: - * This function get the lock state the mutex referenced by 'mutex'. - * - * Parameters: - * mutex - mutex descriptor. - * - * Return Value: - * - ****************************************************************************/ - -bool nxmutex_is_locked(FAR mutex_t *mutex) -{ - int cnt; - int ret; - - ret = _SEM_GETVALUE(&mutex->sem, &cnt); - - return ret >= 0 && cnt < 1; -} - -/**************************************************************************** - * Name: nxmutex_lock - * - * Description: - * This function attempts to lock the mutex referenced by 'mutex'. The - * mutex is implemented with a semaphore, so if the semaphore value is - * (<=) zero, then the calling task will not return until it successfully - * acquires the lock. - * - * Parameters: - * mutex - mutex descriptor. - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * Possible returned errors: - * - ****************************************************************************/ - -int nxmutex_lock(FAR mutex_t *mutex) -{ - int ret; - - DEBUGASSERT(!nxmutex_is_hold(mutex)); - for (; ; ) - { - /* Take the semaphore (perhaps waiting) */ - - ret = _SEM_WAIT(&mutex->sem); - if (ret >= 0) - { - mutex->holder = _SCHED_GETTID(); - break; - } - - ret = _SEM_ERRVAL(ret); - if (ret != -EINTR && ret != -ECANCELED) - { - break; - } - } - - return ret; -} - -/**************************************************************************** - * Name: nxmutex_trylock - * - * Description: - * This function locks the mutex only if the mutex is currently not locked. - * If the mutex has been locked already, the call returns without blocking. - * - * Parameters: - * mutex - mutex descriptor. - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * Possible returned errors: - * - * -EINVAL - Invalid attempt to lock the mutex - * -EAGAIN - The mutex is not available. - * - ****************************************************************************/ - -int nxmutex_trylock(FAR mutex_t *mutex) -{ - int ret; - - DEBUGASSERT(!nxmutex_is_hold(mutex)); - ret = _SEM_TRYWAIT(&mutex->sem); - if (ret < 0) - { - return _SEM_ERRVAL(ret); - } - - mutex->holder = _SCHED_GETTID(); - return ret; -} - -/**************************************************************************** - * Name: nxmutex_timedlock - * - * Description: - * This function attempts to lock the mutex . If the mutex value - * is (<=) zero,then the calling task will not return until it - * successfully acquires the lock or timed out - * - * Input Parameters: - * mutex - Mutex object - * timeout - The time when mutex lock timed out - * - * Returned Value: - * OK The mutex successfully acquires - * EINVAL The mutex argument does not refer to a valid mutex. Or the - * thread would have blocked, and the abstime parameter specified - * a nanoseconds field value less than zero or greater than or - * equal to 1000 million. - * ETIMEDOUT The mutex could not be locked before the specified timeout - * expired. - * EDEADLK A deadlock condition was detected. - * - ****************************************************************************/ - -int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout) -{ - int ret; - struct timespec now; - struct timespec delay; - struct timespec rqtp; - - clock_gettime(CLOCK_MONOTONIC, &now); - clock_ticks2time(MSEC2TICK(timeout), &delay); - clock_timespec_add(&now, &delay, &rqtp); - - /* Wait until we get the lock or until the timeout expires */ - - do - { - ret = _SEM_CLOCKWAIT(&mutex->sem, CLOCK_MONOTONIC, &rqtp); - if (ret < 0) - { - ret = _SEM_ERRVAL(ret); - } - } - while (ret == -EINTR || ret == -ECANCELED); - - if (ret >= 0) - { - mutex->holder = _SCHED_GETTID(); - } - - return ret; -} - -/**************************************************************************** - * Name: nxmutex_unlock - * - * Description: - * This function attempts to unlock the mutex referenced by 'mutex'. - * - * Parameters: - * mutex - mutex descriptor. - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * Possible returned errors: - * - * Assumptions: - * This function may be called from an interrupt handler. - * - ****************************************************************************/ - -int nxmutex_unlock(FAR mutex_t *mutex) -{ - int ret; - - if (nxmutex_is_reset(mutex)) - { - return OK; - } - - DEBUGASSERT(nxmutex_is_hold(mutex)); - - mutex->holder = NXMUTEX_NO_HOLDER; - - ret = _SEM_POST(&mutex->sem); - if (ret < 0) - { - mutex->holder = _SCHED_GETTID(); - ret = _SEM_ERRVAL(ret); - } - - return ret; -} - -/**************************************************************************** - * Name: nxmutex_reset - * - * Description: - * This function reset lock state. - * - * Parameters: - * mutex - mutex descriptor. - * - ****************************************************************************/ - -#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) -void nxmutex_reset(FAR mutex_t *mutex) -{ - mutex->holder = NXMUTEX_RESET; - - nxsem_reset(&mutex->sem, 1); -} -#endif - -/**************************************************************************** - * Name: nxmutex_breaklock - * - * Description: - * This function attempts to break the mutex - * - * Parameters: - * mutex - Mutex descriptor. - * locked - Is the mutex break success - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * Possible returned errors: - * - ****************************************************************************/ - -int nxmutex_breaklock(FAR mutex_t *mutex, FAR bool *locked) -{ - int ret = OK; - - *locked = false; - if (nxmutex_is_hold(mutex)) - { - ret = nxmutex_unlock(mutex); - if (ret >= 0) - { - *locked = true; - } - } - - return ret; -} - -/**************************************************************************** - * Name: nxmutex_restorelock - * - * Description: - * This function attempts to restore the mutex. - * - * Parameters: - * mutex - mutex descriptor. - * locked - true: it's mean that the mutex is broke success - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure - * - ****************************************************************************/ - -int nxmutex_restorelock(FAR mutex_t *mutex, bool locked) -{ - return locked ? nxmutex_lock(mutex) : OK; -} - -/**************************************************************************** - * Name: nxrmutex_init - * - * Description: - * This function initializes the UNNAMED recursive mutex. Following a - * successful call to nxrmutex_init(), the recursive mutex may be used in - * subsequent calls to nxrmutex_lock(), nxrmutex_unlock(), - * and nxrmutex_trylock(). The recursive mutex remains usable - * until it is destroyed. - * - * Parameters: - * rmutex - Recursive mutex to be initialized - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * - ****************************************************************************/ - -int nxrmutex_init(FAR rmutex_t *rmutex) -{ - rmutex->count = 0; - return nxmutex_init(&rmutex->mutex); -} - -/**************************************************************************** - * Name: nxrmutex_destroy - * - * Description: - * This function destroy the UNNAMED recursive mutex. - * - * Parameters: - * rmutex - Recursive mutex to be destroyed - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * - ****************************************************************************/ - -int nxrmutex_destroy(FAR rmutex_t *rmutex) -{ - int ret = nxmutex_destroy(&rmutex->mutex); - - if (ret >= 0) - { - rmutex->count = 0; - } - - return ret; -} - -/**************************************************************************** - * Name: nxrmutex_is_hold - * - * Description: - * This function check whether the caller hold the recursive mutex - * referenced by 'rmutex'. - * - * Parameters: - * rmutex - Recursive mutex descriptor. - * - * Return Value: - * - ****************************************************************************/ - -bool nxrmutex_is_hold(FAR rmutex_t *rmutex) -{ - return nxmutex_is_hold(&rmutex->mutex); -} - -/**************************************************************************** - * Name: nxrmutex_is_locked - * - * Description: - * This function get the lock state the recursive mutex - * referenced by 'rmutex'. - * - * Parameters: - * rmutex - Recursive mutex descriptor. - * - * Return Value: - * - ****************************************************************************/ - -bool nxrmutex_is_locked(FAR rmutex_t *rmutex) -{ - return nxmutex_is_locked(&rmutex->mutex); -} - -/**************************************************************************** - * Name: nrxmutex_lock - * - * Description: - * This function attempts to lock the recursive mutex referenced by - * 'rmutex'.The recursive mutex can be locked multiple times in the same - * thread. - * - * Parameters: - * rmutex - Recursive mutex descriptor. - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * Possible returned errors: - * - ****************************************************************************/ - -int nxrmutex_lock(FAR rmutex_t *rmutex) -{ - int ret = OK; - - if (!nxrmutex_is_hold(rmutex)) - { - ret = nxmutex_lock(&rmutex->mutex); - } - - if (ret >= 0) - { - DEBUGASSERT(rmutex->count < UINT_MAX); - ++rmutex->count; - } - - return ret; -} - -/**************************************************************************** - * Name: nxrmutex_trylock - * - * Description: - * This function locks the recursive mutex if the recursive mutex is - * currently not locked or the same thread call. - * If the recursive mutex is locked and other thread call it, - * the call returns without blocking. - * - * Parameters: - * rmutex - Recursive mutex descriptor. - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * Possible returned errors: - * - * -EINVAL - Invalid attempt to lock the recursive mutex - * -EAGAIN - The recursive mutex is not available. - * - ****************************************************************************/ - -int nxrmutex_trylock(FAR rmutex_t *rmutex) -{ - int ret = OK; - - if (!nxrmutex_is_hold(rmutex)) - { - ret = nxmutex_trylock(&rmutex->mutex); - } - - if (ret >= 0) - { - DEBUGASSERT(rmutex->count < UINT_MAX); - ++rmutex->count; - } - - return ret; -} - -/**************************************************************************** - * Name: nxrmutex_timedlock - * - * Description: - * This function attempts to lock the mutex . If the mutex value - * is (<=) zero,then the calling task will not return until it - * successfully acquires the lock or timed out - * - * Input Parameters: - * rmutex - Rmutex object - * timeout - The time when mutex lock timed out - * - * Returned Value: - * OK The mutex successfully acquires - * EINVAL The mutex argument does not refer to a valid mutex. Or the - * thread would have blocked, and the abstime parameter specified - * a nanoseconds field value less than zero or greater than or - * equal to 1000 million. - * ETIMEDOUT The mutex could not be locked before the specified timeout - * expired. - * EDEADLK A deadlock condition was detected. - * ECANCELED May be returned if the thread is canceled while waiting. - * - ****************************************************************************/ - -int nxrmutex_timedlock(FAR rmutex_t *rmutex, unsigned int timeout) -{ - int ret = OK; - - if (!nxrmutex_is_hold(rmutex)) - { - ret = nxmutex_timedlock(&rmutex->mutex, timeout); - } - - if (ret >= 0) - { - DEBUGASSERT(rmutex->count < UINT_MAX); - ++rmutex->count; - } - - return ret; -} - -/**************************************************************************** - * Name: nxrmutex_unlock - * - * Description: - * This function attempts to unlock the recursive mutex - * referenced by 'rmutex'. - * - * Parameters: - * rmutex - Recursive mutex descriptor. - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * Possible returned errors: - * - * Assumptions: - * This function may be called from an interrupt handler. - * - ****************************************************************************/ - -int nxrmutex_unlock(FAR rmutex_t *rmutex) -{ - int ret = OK; - - DEBUGASSERT(rmutex->count > 0); - - if (--rmutex->count == 0) - { - ret = nxmutex_unlock(&rmutex->mutex); - if (ret < 0) - { - ++rmutex->count; - } - } - - return ret; -} - -/**************************************************************************** - * Name: nxrmutex_reset - * - * Description: - * This function reset lock state. - * - * Parameters: - * rmutex - rmutex descriptor. - * - ****************************************************************************/ - -#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) -void nxrmutex_reset(FAR rmutex_t *rmutex) -{ - rmutex->count = 0; - nxmutex_reset(&rmutex->mutex); -} -#endif - -/**************************************************************************** - * Name: nrxmutex_breaklock - * - * Description: - * This function attempts to break the recursive mutex - * - * Parameters: - * rmutex - Recursive mutex descriptor. - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * Possible returned errors: - * - ****************************************************************************/ - -int nxrmutex_breaklock(FAR rmutex_t *rmutex, FAR unsigned int *count) -{ - int ret = OK; - - *count = 0; - if (nxrmutex_is_hold(rmutex)) - { - *count = rmutex->count; - rmutex->count = 0; - ret = nxmutex_unlock(&rmutex->mutex); - if (ret < 0) - { - rmutex->count = *count; - } - } - - return ret; -} - -/**************************************************************************** - * Name: nxrmutex_restorelock - * - * Description: - * This function attempts to restore the recursive mutex. - * - * Parameters: - * rmutex - Recursive mutex descriptor. - * - * Return Value: - * This is an internal OS interface and should not be used by applications. - * It follows the NuttX internal error return policy: Zero (OK) is - * returned on success. A negated errno value is returned on failure. - * Possible returned errors: - * - ****************************************************************************/ - -int nxrmutex_restorelock(FAR rmutex_t *rmutex, unsigned int count) -{ - int ret = OK; - - if (count != 0) - { - ret = nxmutex_lock(&rmutex->mutex); - if (ret >= 0) - { - rmutex->count = count; - } - } - - return ret; -} diff --git a/libs/libc/mutex/Make.defs b/libs/libc/mutex/Make.defs new file mode 100644 index 0000000000000..f5fa295f74643 --- /dev/null +++ b/libs/libc/mutex/Make.defs @@ -0,0 +1,31 @@ +############################################################################ +# libs/libc/mutex/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +# Add the mutex C files to the build + +CSRCS += mutex_breaklock.c mutex_destroy.c mutex_init.c +CSRCS += mutex_is_locked.c mutex_is_hold.c mutex_lock.c +CSRCS += mutex_reset.c mutex_restorelock.c mutex_timedlock.c +CSRCS += mutex_trylock.c mutex_unlock.c + +# Add the mutex directory to the build + +DEPPATH += --dep-path mutex +VPATH += :mutex diff --git a/libs/libc/mutex/mutex_breaklock.c b/libs/libc/mutex/mutex_breaklock.c new file mode 100644 index 0000000000000..eb3c850c9fbd8 --- /dev/null +++ b/libs/libc/mutex/mutex_breaklock.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_breaklock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_breaklock + * + * Description: + * This function attempts to break the mutex + * + * Input Parameters: + * mutex - Mutex descriptor. + * + * Output Parameters: + * locked - Is the mutex break success + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * Possible returned errors: + * + ****************************************************************************/ + +int nxmutex_breaklock(FAR mutex_t *mutex, FAR bool *locked) +{ + int ret = OK; + + *locked = false; + if (nxmutex_is_hold(mutex)) + { + ret = nxmutex_unlock(mutex); + if (ret >= 0) + { + *locked = true; + } + } + + return ret; +} + +/**************************************************************************** + * Name: nxrmutex_breaklock + * + * Description: + * This function attempts to break the recursive mutex + * + * Input Parameters: + * rmutex - Recursive mutex descriptor. + * + * Output Parameters: + * count - Return the count value before break. + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * Possible returned errors: + * + ****************************************************************************/ + +int nxrmutex_breaklock(FAR rmutex_t *rmutex, FAR unsigned int *count) +{ + int ret = OK; + + *count = 0; + if (nxrmutex_is_hold(rmutex)) + { + *count = rmutex->count; + rmutex->count = 0; + ret = nxmutex_unlock(&rmutex->mutex); + if (ret < 0) + { + rmutex->count = *count; + } + } + + return ret; +} diff --git a/libs/libc/mutex/mutex_destroy.c b/libs/libc/mutex/mutex_destroy.c new file mode 100644 index 0000000000000..88d5794965f1d --- /dev/null +++ b/libs/libc/mutex/mutex_destroy.c @@ -0,0 +1,56 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_destroy.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxrmutex_destroy + * + * Description: + * This function destroy the UNNAMED recursive mutex. + * + * Parameters: + * rmutex - Recursive mutex to be destroyed + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + ****************************************************************************/ + +int nxrmutex_destroy(FAR rmutex_t *rmutex) +{ + int ret = nxmutex_destroy(&rmutex->mutex); + if (ret >= 0) + { + rmutex->count = 0; + } + + return ret; +} diff --git a/libs/libc/mutex/mutex_init.c b/libs/libc/mutex/mutex_init.c new file mode 100644 index 0000000000000..02d366f61b657 --- /dev/null +++ b/libs/libc/mutex/mutex_init.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_init.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_init + * + * Description: + * This function initializes the UNNAMED mutex. Following a + * successful call to nxmutex_init(), the mutex may be used in subsequent + * calls to nxmutex_lock(), nxmutex_unlock(), and nxmutex_trylock(). The + * mutex remains usable until it is destroyed. + * + * Parameters: + * mutex - Semaphore to be initialized + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + ****************************************************************************/ + +int nxmutex_init(FAR mutex_t *mutex) +{ + int ret = nxsem_init(&mutex->sem, 0, 1); + if (ret >= 0) + { + mutex->holder = NXMUTEX_NO_HOLDER; + nxsem_set_protocol(&mutex->sem, SEM_TYPE_MUTEX | SEM_PRIO_INHERIT); + } + + return ret; +} + +/**************************************************************************** + * Name: nxrmutex_init + * + * Description: + * This function initializes the UNNAMED recursive mutex. Following a + * successful call to nxrmutex_init(), the recursive mutex may be used in + * subsequent calls to nxrmutex_lock(), nxrmutex_unlock(), + * and nxrmutex_trylock(). The recursive mutex remains usable + * until it is destroyed. + * + * Parameters: + * rmutex - Recursive mutex to be initialized + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + ****************************************************************************/ + +int nxrmutex_init(FAR rmutex_t *rmutex) +{ + rmutex->count = 0; + return nxmutex_init(&rmutex->mutex); +} diff --git a/libs/libc/mutex/mutex_is_hold.c b/libs/libc/mutex/mutex_is_hold.c new file mode 100644 index 0000000000000..b0afdc2252106 --- /dev/null +++ b/libs/libc/mutex/mutex_is_hold.c @@ -0,0 +1,50 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_is_hold.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_is_hold + * + * Description: + * This function check whether the caller hold the mutex + * referenced by 'mutex'. + * + * Parameters: + * mutex - mutex descriptor. + * + * Return Value: + * Return true if mutex is hold by current thread. + * + ****************************************************************************/ + +bool nxmutex_is_hold(FAR mutex_t *mutex) +{ + return mutex->holder == _SCHED_GETTID(); +} diff --git a/libs/libc/mutex/mutex_is_locked.c b/libs/libc/mutex/mutex_is_locked.c new file mode 100644 index 0000000000000..552a55b1110cb --- /dev/null +++ b/libs/libc/mutex/mutex_is_locked.c @@ -0,0 +1,53 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_is_locked.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_is_locked + * + * Description: + * This function get the lock state the mutex referenced by 'mutex'. + * + * Parameters: + * mutex - mutex descriptor. + * + * Return Value: + * Return true if mutex is locked. + * + ****************************************************************************/ + +bool nxmutex_is_locked(FAR mutex_t *mutex) +{ + int cnt; + int ret; + + ret = nxsem_get_value(&mutex->sem, &cnt); + + return ret >= 0 && cnt < 1; +} diff --git a/libs/libc/mutex/mutex_lock.c b/libs/libc/mutex/mutex_lock.c new file mode 100644 index 0000000000000..17ae0d2cb7432 --- /dev/null +++ b/libs/libc/mutex/mutex_lock.c @@ -0,0 +1,68 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_lock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxrmutex_lock + * + * Description: + * This function attempts to lock the recursive mutex referenced by + * 'rmutex'.The recursive mutex can be locked multiple times in the same + * thread. + * + * Parameters: + * rmutex - Recursive mutex descriptor. + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * Possible returned errors: + * + ****************************************************************************/ + +int nxrmutex_lock(FAR rmutex_t *rmutex) +{ + int ret = OK; + + if (!nxrmutex_is_hold(rmutex)) + { + ret = nxmutex_lock(&rmutex->mutex); + } + + if (ret >= 0) + { + DEBUGASSERT(rmutex->count < UINT_MAX); + ++rmutex->count; + } + + return ret; +} diff --git a/libs/libc/mutex/mutex_reset.c b/libs/libc/mutex/mutex_reset.c new file mode 100644 index 0000000000000..26f5801ec2767 --- /dev/null +++ b/libs/libc/mutex/mutex_reset.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_reset.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxrmutex_reset + * + * Description: + * This function reset lock state. + * + * Parameters: + * rmutex - rmutex descriptor. + * + ****************************************************************************/ + +void nxrmutex_reset(FAR rmutex_t *rmutex) +{ + rmutex->count = 0; + nxmutex_reset(&rmutex->mutex); +} diff --git a/libs/libc/mutex/mutex_restorelock.c b/libs/libc/mutex/mutex_restorelock.c new file mode 100644 index 0000000000000..df9afda9f8972 --- /dev/null +++ b/libs/libc/mutex/mutex_restorelock.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_restorelock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_restorelock + * + * Description: + * This function attempts to restore the mutex. + * + * Parameters: + * mutex - mutex descriptor. + * locked - true: it's mean that the mutex is broke success + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure + * + ****************************************************************************/ + +int nxmutex_restorelock(FAR mutex_t *mutex, bool locked) +{ + return locked ? nxmutex_lock(mutex) : OK; +} + +/**************************************************************************** + * Name: nxrmutex_restorelock + * + * Description: + * This function attempts to restore the recursive mutex. + * + * Parameters: + * rmutex - Recursive mutex descriptor. + * count - Count after restore. + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * Possible returned errors: + * + ****************************************************************************/ + +int nxrmutex_restorelock(FAR rmutex_t *rmutex, unsigned int count) +{ + int ret = OK; + + if (count != 0) + { + ret = nxmutex_lock(&rmutex->mutex); + if (ret >= 0) + { + rmutex->count = count; + } + } + + return ret; +} diff --git a/libs/libc/mutex/mutex_timedlock.c b/libs/libc/mutex/mutex_timedlock.c new file mode 100644 index 0000000000000..395db5e80d383 --- /dev/null +++ b/libs/libc/mutex/mutex_timedlock.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_timedlock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxrmutex_timedlock + * + * Description: + * This function attempts to lock the mutex . If the mutex value + * is (<=) zero,then the calling task will not return until it + * successfully acquires the lock or timed out + * + * Input Parameters: + * rmutex - Rmutex object + * timeout - The time when mutex lock timed out + * + * Returned Value: + * OK The mutex successfully acquires + * EINVAL The mutex argument does not refer to a valid mutex. Or the + * thread would have blocked, and the abstime parameter specified + * a nanoseconds field value less than zero or greater than or + * equal to 1000 million. + * ETIMEDOUT The mutex could not be locked before the specified timeout + * expired. + * EDEADLK A deadlock condition was detected. + * ECANCELED May be returned if the thread is canceled while waiting. + * + ****************************************************************************/ + +int nxrmutex_timedlock(FAR rmutex_t *rmutex, unsigned int timeout) +{ + int ret = OK; + + if (!nxrmutex_is_hold(rmutex)) + { + ret = nxmutex_timedlock(&rmutex->mutex, timeout); + } + + if (ret >= 0) + { + DEBUGASSERT(rmutex->count < UINT_MAX); + ++rmutex->count; + } + + return ret; +} diff --git a/libs/libc/mutex/mutex_trylock.c b/libs/libc/mutex/mutex_trylock.c new file mode 100644 index 0000000000000..6c941c5197ce8 --- /dev/null +++ b/libs/libc/mutex/mutex_trylock.c @@ -0,0 +1,72 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_trylock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxrmutex_trylock + * + * Description: + * This function locks the recursive mutex if the recursive mutex is + * currently not locked or the same thread call. + * If the recursive mutex is locked and other thread call it, + * the call returns without blocking. + * + * Parameters: + * rmutex - Recursive mutex descriptor. + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * Possible returned errors: + * + * -EINVAL - Invalid attempt to lock the recursive mutex + * -EAGAIN - The recursive mutex is not available. + * + ****************************************************************************/ + +int nxrmutex_trylock(FAR rmutex_t *rmutex) +{ + int ret = OK; + + if (!nxrmutex_is_hold(rmutex)) + { + ret = nxmutex_trylock(&rmutex->mutex); + } + + if (ret >= 0) + { + DEBUGASSERT(rmutex->count < UINT_MAX); + ++rmutex->count; + } + + return ret; +} diff --git a/libs/libc/mutex/mutex_unlock.c b/libs/libc/mutex/mutex_unlock.c new file mode 100644 index 0000000000000..97736bb571526 --- /dev/null +++ b/libs/libc/mutex/mutex_unlock.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_unlock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxrmutex_unlock + * + * Description: + * This function attempts to unlock the recursive mutex + * referenced by 'rmutex'. + * + * Parameters: + * rmutex - Recursive mutex descriptor. + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * Possible returned errors: + * + * Assumptions: + * This function may be called from an interrupt handler. + * + ****************************************************************************/ + +int nxrmutex_unlock(FAR rmutex_t *rmutex) +{ + int ret = OK; + + DEBUGASSERT(rmutex->count > 0); + + if (--rmutex->count == 0) + { + ret = nxmutex_unlock(&rmutex->mutex); + if (ret < 0) + { + ++rmutex->count; + } + } + + return ret; +} diff --git a/sched/Makefile b/sched/Makefile index ccd723f9d6cf5..757864b0869de 100644 --- a/sched/Makefile +++ b/sched/Makefile @@ -29,6 +29,7 @@ include irq/Make.defs include misc/Make.defs include mqueue/Make.defs include module/Make.defs +include mutex/Make.defs include paging/Make.defs include pthread/Make.defs include sched/Make.defs diff --git a/sched/mutex/Make.defs b/sched/mutex/Make.defs new file mode 100644 index 0000000000000..4028558b0bfb8 --- /dev/null +++ b/sched/mutex/Make.defs @@ -0,0 +1,29 @@ +############################################################################ +# sched/mutex/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +# Add mutex-related files to the build + +CSRCS += mutex_destroy.c mutex_lock.c mutex_reset.c +CSRCS += mutex_timedlock.c mutex_trylock.c mutex_unlock.c + +# Include mutex build support + +DEPPATH += --dep-path mutex +VPATH += :mutex diff --git a/sched/mutex/mutex_destroy.c b/sched/mutex/mutex_destroy.c new file mode 100644 index 0000000000000..6c92b213de71a --- /dev/null +++ b/sched/mutex/mutex_destroy.c @@ -0,0 +1,55 @@ +/**************************************************************************** + * sched/mutex/mutex_destroy.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_destroy + * + * Description: + * This function initializes the UNNAMED mutex. Following a + * successful call to nxmutex_init(), the mutex may be used in subsequent + * calls to nxmutex_lock(), nxmutex_unlock(), and nxmutex_trylock(). The + * mutex remains usable until it is destroyed. + * + * Parameters: + * mutex - Semaphore to be destroyed + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + ****************************************************************************/ + +int nxmutex_destroy(FAR mutex_t *mutex) +{ + int ret = nxsem_destroy(&mutex->sem); + mutex->holder = NXMUTEX_NO_HOLDER; + return ret; +} diff --git a/sched/mutex/mutex_lock.c b/sched/mutex/mutex_lock.c new file mode 100644 index 0000000000000..4a933f5178e3a --- /dev/null +++ b/sched/mutex/mutex_lock.c @@ -0,0 +1,77 @@ +/**************************************************************************** + * sched/mutex/mutex_lock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_lock + * + * Description: + * This function attempts to lock the mutex referenced by 'mutex'. The + * mutex is implemented with a semaphore, so if the semaphore value is + * (<=) zero, then the calling task will not return until it successfully + * acquires the lock. + * + * Parameters: + * mutex - mutex descriptor. + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * Possible returned errors: + * + ****************************************************************************/ + +int nxmutex_lock(FAR mutex_t *mutex) +{ + int ret; + + DEBUGASSERT(!nxmutex_is_hold(mutex)); + for (; ; ) + { + /* Take the semaphore (perhaps waiting) */ + + ret = nxsem_wait(&mutex->sem); + if (ret >= 0) + { + mutex->holder = nxsched_gettid(); + break; + } + + if (ret != -EINTR) + { + break; + } + } + + return ret; +} diff --git a/sched/mutex/mutex_reset.c b/sched/mutex/mutex_reset.c new file mode 100644 index 0000000000000..f2086cdf5bfaa --- /dev/null +++ b/sched/mutex/mutex_reset.c @@ -0,0 +1,46 @@ +/**************************************************************************** + * sched/mutex/mutex_reset.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_reset + * + * Description: + * This function reset lock state. + * + * Parameters: + * mutex - mutex descriptor. + * + ****************************************************************************/ + +void nxmutex_reset(FAR mutex_t *mutex) +{ + mutex->holder = NXMUTEX_RESET; + nxsem_reset(&mutex->sem, 1); +} diff --git a/sched/mutex/mutex_timedlock.c b/sched/mutex/mutex_timedlock.c new file mode 100644 index 0000000000000..2b69510c07bf7 --- /dev/null +++ b/sched/mutex/mutex_timedlock.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * sched/mutex/mutex_timedlock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_timedlock + * + * Description: + * This function attempts to lock the mutex . If the mutex value + * is (<=) zero,then the calling task will not return until it + * successfully acquires the lock or timed out + * + * Input Parameters: + * mutex - Mutex object + * timeout - The time when mutex lock timed out + * + * Returned Value: + * OK The mutex successfully acquires + * EINVAL The mutex argument does not refer to a valid mutex. Or the + * thread would have blocked, and the abstime parameter specified + * a nanoseconds field value less than zero or greater than or + * equal to 1000 million. + * ETIMEDOUT The mutex could not be locked before the specified timeout + * expired. + * EDEADLK A deadlock condition was detected. + * + ****************************************************************************/ + +int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout) +{ + int ret; + + /* Wait until we get the lock or until the timeout expires */ + + do + { + ret = nxsem_tickwait(&mutex->sem, MSEC2TICK(timeout)); + } + while (ret == -EINTR); + + if (ret >= 0) + { + mutex->holder = nxsched_gettid(); + } + + return ret; +} diff --git a/sched/mutex/mutex_trylock.c b/sched/mutex/mutex_trylock.c new file mode 100644 index 0000000000000..742d4a0dafafe --- /dev/null +++ b/sched/mutex/mutex_trylock.c @@ -0,0 +1,69 @@ +/**************************************************************************** + * sched/mutex/mutex_trylock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_trylock + * + * Description: + * This function locks the mutex only if the mutex is currently not locked. + * If the mutex has been locked already, the call returns without blocking. + * + * Parameters: + * mutex - mutex descriptor. + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * Possible returned errors: + * + * -EINVAL - Invalid attempt to lock the mutex + * -EAGAIN - The mutex is not available. + * + ****************************************************************************/ + +int nxmutex_trylock(FAR mutex_t *mutex) +{ + int ret; + + if (nxmutex_is_hold(mutex)) + { + return -EDEADLK; + } + + ret = nxsem_trywait(&mutex->sem); + if (ret >= 0) + { + mutex->holder = nxsched_gettid(); + } + + return ret; +} diff --git a/sched/mutex/mutex_unlock.c b/sched/mutex/mutex_unlock.c new file mode 100644 index 0000000000000..d7c76cd0208d9 --- /dev/null +++ b/sched/mutex/mutex_unlock.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * sched/mutex/mutex_unlock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_unlock + * + * Description: + * This function attempts to unlock the mutex referenced by 'mutex'. + * + * Parameters: + * mutex - mutex descriptor. + * + * Return Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * Possible returned errors: + * + * Assumptions: + * This function may be called from an interrupt handler. + * + ****************************************************************************/ + +int nxmutex_unlock(FAR mutex_t *mutex) +{ + int ret; + + if (nxmutex_is_reset(mutex)) + { + return OK; + } + + DEBUGASSERT(nxmutex_is_hold(mutex)); + + mutex->holder = NXMUTEX_NO_HOLDER; + + ret = nxsem_post(&mutex->sem); + if (ret < 0) + { + mutex->holder = nxsched_gettid(); + } + + return ret; +} diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 5759e61901b62..a2e7c1c04dbbf 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -74,6 +74,12 @@ "nx_pthread_create","nuttx/pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_trampoline_t","FAR pthread_t *","FAR const pthread_attr_t *","pthread_startroutine_t","pthread_addr_t" "nx_pthread_exit","nuttx/pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","noreturn","pthread_addr_t" "nx_vsyslog","nuttx/syslog/syslog.h","","int","int","FAR const IPTR char *","FAR va_list *" +"nxmutex_breaklock","nuttx/mutex.h","","int","FAR mutex_t *","FAR bool *" +"nxmutex_destroy","nuttx/mutex.h","","int","FAR mutex_t *" +"nxmutex_lock","nuttx/mutex.h","","int","FAR mutex_t *" +"nxmutex_timedlock","nuttx/mutex.h","","int","FAR mutex_t *","unsigned int" +"nxmutex_trylock","nuttx/mutex.h","","int","FAR mutex_t *" +"nxmutex_unlock","nuttx/mutex.h","","int","FAR mutex_t *" "nxsched_get_stackinfo","nuttx/sched.h","","int","pid_t","FAR struct stackinfo_s *" "open","fcntl.h","","int","FAR const char *","int","...","mode_t" "pgalloc", "nuttx/arch.h", "defined(CONFIG_BUILD_KERNEL)", "uintptr_t", "uintptr_t", "unsigned int" From 9d89ffb47e9eb3aae2911eec0bdc77d63c612a0b Mon Sep 17 00:00:00 2001 From: zhangyuan21 Date: Mon, 6 Mar 2023 18:19:56 +0800 Subject: [PATCH 2/2] sched/mutex: Add more mutex interface add nxmutex_clocklock, nxmutex_set_protocol and nxmutex_get_protocol interface Signed-off-by: zhangyuan21 --- include/nuttx/mutex.h | 138 ++++++++++++++++++++++++++ include/semaphore.h | 2 +- include/sys/syscall_lookup.h | 2 + libs/libc/mutex/Make.defs | 7 +- libs/libc/mutex/mutex_clocklock.c | 75 ++++++++++++++ libs/libc/mutex/mutex_get_protocol.c | 53 ++++++++++ libs/libc/semaphore/sem_getprotocol.c | 2 +- sched/mutex/Make.defs | 5 +- sched/mutex/mutex_clocklock.c | 79 +++++++++++++++ sched/mutex/mutex_set_protocol.c | 52 ++++++++++ sched/semaphore/sem_setprotocol.c | 6 +- syscall/syscall.csv | 2 + 12 files changed, 414 insertions(+), 9 deletions(-) create mode 100644 libs/libc/mutex/mutex_clocklock.c create mode 100644 libs/libc/mutex/mutex_get_protocol.c create mode 100644 sched/mutex/mutex_clocklock.c create mode 100644 sched/mutex/mutex_set_protocol.c diff --git a/include/nuttx/mutex.h b/include/nuttx/mutex.h index 9ac668ef28e26..fbe4f20235747 100644 --- a/include/nuttx/mutex.h +++ b/include/nuttx/mutex.h @@ -239,6 +239,34 @@ int nxmutex_trylock(FAR mutex_t *mutex); int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout); +/**************************************************************************** + * Name: nxmutex_clocklock + * + * Description: + * This function attempts to lock the mutex. If the mutex value + * is (<=) zero,then the calling task will not return until it + * successfully acquires the lock or timed out + * + * Input Parameters: + * mutex - Mutex object + * clockid - The timing source to use in the conversion + * abs_timeout - The abs time when mutex lock timed out + * + * Returned Value: + * OK The mutex successfully acquires + * EINVAL The mutex argument does not refer to a valid mutex. Or the + * thread would have blocked, and the abstime parameter specified + * a nanoseconds field value less than zero or greater than or + * equal to 1000 million. + * ETIMEDOUT The mutex could not be locked before the specified timeout + * expired. + * EDEADLK A deadlock condition was detected. + * + ****************************************************************************/ + +int nxmutex_clocklock(FAR mutex_t *mutex, clockid_t clockid, + FAR const struct timespec *abs_timeout); + /**************************************************************************** * Name: nxmutex_unlock * @@ -315,6 +343,47 @@ int nxmutex_breaklock(FAR mutex_t *mutex, FAR bool *locked); int nxmutex_restorelock(FAR mutex_t *mutex, bool locked); +/**************************************************************************** + * Name: nxmutex_set_protocol + * + * Description: + * Set mutex protocol attribute. + * + * Input Parameters: + * mutex - A pointer to the mutex whose attributes are to be + * modified + * protocol - The new protocol to use + * + * Returned Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + ****************************************************************************/ + +int nxmutex_set_protocol(FAR mutex_t *mutex, int protocol); + +/**************************************************************************** + * Name: nxmutex_get_protocol + * + * Description: + * Return the value of the mutex protocol attribute. + * + * Input Parameters: + * mutex - A pointer to the mutex whose attributes are to be + * queried. + * protocol - The user provided location in which to store the protocol + * value. + * + * Returned Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + ****************************************************************************/ + +int nxmutex_get_protocol(FAR mutex_t *mutex, FAR int *protocol); + /**************************************************************************** * Name: nxrmutex_init * @@ -460,6 +529,34 @@ int nxrmutex_trylock(FAR rmutex_t *rmutex); int nxrmutex_timedlock(FAR rmutex_t *rmutex, unsigned int timeout); +/**************************************************************************** + * Name: nxrmutex_clocklock + * + * Description: + * This function attempts to lock the mutex. If the mutex value + * is (<=) zero,then the calling task will not return until it + * successfully acquires the lock or timed out + * + * Input Parameters: + * rmutex - Rmutex object + * clockid - The timing source to use in the conversion + * abs_timeout - The abs time when mutex lock timed out + * + * Returned Value: + * OK The mutex successfully acquires + * EINVAL The mutex argument does not refer to a valid mutex. Or the + * thread would have blocked, and the abstime parameter specified + * a nanoseconds field value less than zero or greater than or + * equal to 1000 million. + * ETIMEDOUT The mutex could not be locked before the specified timeout + * expired. + * EDEADLK A deadlock condition was detected. + * + ****************************************************************************/ + +int nxrmutex_clocklock(FAR rmutex_t *rmutex, clockid_t clockid, + FAR const struct timespec *abs_timeout); + /**************************************************************************** * Name: nxrmutex_unlock * @@ -538,6 +635,47 @@ int nxrmutex_breaklock(FAR rmutex_t *rmutex, FAR unsigned int *count); int nxrmutex_restorelock(FAR rmutex_t *rmutex, unsigned int count); +/**************************************************************************** + * Name: nxrmutex_set_protocol + * + * Description: + * Set mutex protocol attribute. + * + * Input Parameters: + * rmutex - Recursive mutex descriptor. + * protocol - The new protocol to use + * + * Returned Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + ****************************************************************************/ + +#define nxrmutex_set_protocol(rmutex, protocol) \ + nxmutex_set_protocol(&(rmutex)->mutex, protocol) + +/**************************************************************************** + * Name: nxrmutex_get_protocol + * + * Description: + * Return the value of the mutex protocol attribute. + * + * Input Parameters: + * rmutex - Recursive mutex descriptor. + * protocol - The user provided location in which to store the protocol + * value. + * + * Returned Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + ****************************************************************************/ + +#define nxrmutex_get_protocol(rmutex, protocol) \ + nxmutex_get_protocol(&(rmutex)->mutex, protocol) + #undef EXTERN #ifdef __cplusplus } diff --git a/include/semaphore.h b/include/semaphore.h index f3f1087972096..4bdfa9cbbb479 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -141,7 +141,7 @@ typedef struct sem_s sem_t; {(c), 0, SEM_WAITLIST_INITIALIZER} #endif -# define SEM_WAITLIST(sem) (&((sem)->waitlist)) +#define SEM_WAITLIST(sem) (&((sem)->waitlist)) /**************************************************************************** * Public Data diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h index 402684b1d7f25..4571200360fd4 100644 --- a/include/sys/syscall_lookup.h +++ b/include/sys/syscall_lookup.h @@ -382,8 +382,10 @@ SYSCALL_LOOKUP(munmap, 2) #endif SYSCALL_LOOKUP(nxmutex_breaklock, 2) +SYSCALL_LOOKUP(nxmutex_clocklock, 3) SYSCALL_LOOKUP(nxmutex_destroy, 1) SYSCALL_LOOKUP(nxmutex_lock, 1) +SYSCALL_LOOKUP(nxmutex_set_protocol, 2) SYSCALL_LOOKUP(nxmutex_timedlock, 2) SYSCALL_LOOKUP(nxmutex_trylock, 1) SYSCALL_LOOKUP(nxmutex_unlock, 1) diff --git a/libs/libc/mutex/Make.defs b/libs/libc/mutex/Make.defs index f5fa295f74643..757f8337034a7 100644 --- a/libs/libc/mutex/Make.defs +++ b/libs/libc/mutex/Make.defs @@ -20,9 +20,10 @@ # Add the mutex C files to the build -CSRCS += mutex_breaklock.c mutex_destroy.c mutex_init.c -CSRCS += mutex_is_locked.c mutex_is_hold.c mutex_lock.c -CSRCS += mutex_reset.c mutex_restorelock.c mutex_timedlock.c +CSRCS += mutex_breaklock.c mutex_clocklock.c mutex_destroy.c +CSRCS += mutex_get_protocol.c mutex_init.c mutex_is_hold.c +CSRCS += mutex_is_locked.c mutex_lock.c mutex_reset.c +CSRCS += mutex_restorelock.c mutex_timedlock.c CSRCS += mutex_trylock.c mutex_unlock.c # Add the mutex directory to the build diff --git a/libs/libc/mutex/mutex_clocklock.c b/libs/libc/mutex/mutex_clocklock.c new file mode 100644 index 0000000000000..353a0f225cbb4 --- /dev/null +++ b/libs/libc/mutex/mutex_clocklock.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_clocklock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxrmutex_clocklock + * + * Description: + * This function attempts to lock the mutex . If the mutex value + * is (<=) zero,then the calling task will not return until it + * successfully acquires the lock or timed out + * + * Input Parameters: + * rmutex - Rmutex object + * clockid - The timing source to use in the conversion + * abs_timeout - The abs time when mutex lock timed out + * + * Returned Value: + * OK The mutex successfully acquires + * EINVAL The mutex argument does not refer to a valid mutex. Or the + * thread would have blocked, and the abstime parameter specified + * a nanoseconds field value less than zero or greater than or + * equal to 1000 million. + * ETIMEDOUT The mutex could not be locked before the specified timeout + * expired. + * EDEADLK A deadlock condition was detected. + * + ****************************************************************************/ + +int nxrmutex_clocklock(FAR rmutex_t *rmutex, clockid_t clockid, + FAR const struct timespec *abs_timeout) +{ + int ret = OK; + + if (!nxrmutex_is_hold(rmutex)) + { + ret = nxmutex_clocklock(&rmutex->mutex, clockid, abs_timeout); + } + + if (ret >= 0) + { + DEBUGASSERT(rmutex->count < UINT_MAX); + ++rmutex->count; + } + + return ret; +} diff --git a/libs/libc/mutex/mutex_get_protocol.c b/libs/libc/mutex/mutex_get_protocol.c new file mode 100644 index 0000000000000..e3f6e40bbdd07 --- /dev/null +++ b/libs/libc/mutex/mutex_get_protocol.c @@ -0,0 +1,53 @@ +/**************************************************************************** + * libs/libc/mutex/mutex_get_protocol.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_get_protocol + * + * Description: + * Return the value of the mutex protocol attribute. + * + * Input Parameters: + * mutex - A pointer to the mutex whose attributes are to be + * queried. + * protocol - The user provided location in which to store the protocol + * value. + * + * Returned Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + ****************************************************************************/ + +int nxmutex_get_protocol(FAR mutex_t *mutex, FAR int *protocol) +{ + return nxsem_get_protocol(&mutex->sem, protocol); +} diff --git a/libs/libc/semaphore/sem_getprotocol.c b/libs/libc/semaphore/sem_getprotocol.c index 38dbd172e75c3..ad7f3a2ef6cb6 100644 --- a/libs/libc/semaphore/sem_getprotocol.c +++ b/libs/libc/semaphore/sem_getprotocol.c @@ -54,6 +54,6 @@ int sem_getprotocol(FAR sem_t *sem, FAR int *protocol) { DEBUGASSERT(sem != NULL && protocol != NULL); - *protocol = sem->flags; + *protocol = sem->flags & SEM_PRIO_MASK; return OK; } diff --git a/sched/mutex/Make.defs b/sched/mutex/Make.defs index 4028558b0bfb8..f8000b61e228f 100644 --- a/sched/mutex/Make.defs +++ b/sched/mutex/Make.defs @@ -20,8 +20,9 @@ # Add mutex-related files to the build -CSRCS += mutex_destroy.c mutex_lock.c mutex_reset.c -CSRCS += mutex_timedlock.c mutex_trylock.c mutex_unlock.c +CSRCS += mutex_clocklock.c mutex_destroy.c mutex_lock.c +CSRCS += mutex_reset.c mutex_set_protocol.c mutex_timedlock.c +CSRCS += mutex_trylock.c mutex_unlock.c # Include mutex build support diff --git a/sched/mutex/mutex_clocklock.c b/sched/mutex/mutex_clocklock.c new file mode 100644 index 0000000000000..0c582605a843b --- /dev/null +++ b/sched/mutex/mutex_clocklock.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * sched/mutex/mutex_clocklock.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_clocklock + * + * Description: + * This function attempts to lock the mutex . If the mutex value + * is (<=) zero,then the calling task will not return until it + * successfully acquires the lock or timed out + * + * Input Parameters: + * mutex - Mutex object + * clockid - The timing source to use in the conversion + * abs_timeout - The abs time when mutex lock timed out + * + * Returned Value: + * OK The mutex successfully acquires + * EINVAL The mutex argument does not refer to a valid mutex. Or the + * thread would have blocked, and the abstime parameter specified + * a nanoseconds field value less than zero or greater than or + * equal to 1000 million. + * ETIMEDOUT The mutex could not be locked before the specified timeout + * expired. + * EDEADLK A deadlock condition was detected. + * + ****************************************************************************/ + +int nxmutex_clocklock(FAR mutex_t *mutex, clockid_t clockid, + FAR const struct timespec *abs_timeout) +{ + int ret; + + /* Wait until we get the lock or until the timeout expires */ + + do + { + ret = nxsem_clockwait(&mutex->sem, clockid, abs_timeout); + } + while (ret == -EINTR); + + if (ret >= 0) + { + mutex->holder = nxsched_gettid(); + } + + return ret; +} diff --git a/sched/mutex/mutex_set_protocol.c b/sched/mutex/mutex_set_protocol.c new file mode 100644 index 0000000000000..29708de6013b6 --- /dev/null +++ b/sched/mutex/mutex_set_protocol.c @@ -0,0 +1,52 @@ +/**************************************************************************** + * sched/mutex/mutex_set_protocol.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxmutex_set_protocol + * + * Description: + * Set mutex protocol attribute. + * + * Input Parameters: + * mutex - A pointer to the mutex whose attributes are to be + * modified + * protocol - The new protocol to use + * + * Returned Value: + * This is an internal OS interface and should not be used by applications. + * It follows the NuttX internal error return policy: Zero (OK) is + * returned on success. A negated errno value is returned on failure. + * + ****************************************************************************/ + +int nxmutex_set_protocol(FAR mutex_t *mutex, int protocol) +{ + return nxsem_set_protocol(&mutex->sem, protocol); +} diff --git a/sched/semaphore/sem_setprotocol.c b/sched/semaphore/sem_setprotocol.c index 74f864bcc97e3..099c030affa31 100644 --- a/sched/semaphore/sem_setprotocol.c +++ b/sched/semaphore/sem_setprotocol.c @@ -76,7 +76,8 @@ int nxsem_set_protocol(FAR sem_t *sem, int protocol) { DEBUGASSERT(sem != NULL); - switch (protocol & SEM_PRIO_MASK) + protocol &= SEM_PRIO_MASK; + switch (protocol) { case SEM_PRIO_NONE: @@ -99,7 +100,8 @@ int nxsem_set_protocol(FAR sem_t *sem, int protocol) return -EINVAL; } - sem->flags = protocol; + sem->flags &= ~SEM_PRIO_MASK; + sem->flags |= protocol; return OK; } diff --git a/syscall/syscall.csv b/syscall/syscall.csv index a2e7c1c04dbbf..36745689e6c5f 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -75,8 +75,10 @@ "nx_pthread_exit","nuttx/pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","noreturn","pthread_addr_t" "nx_vsyslog","nuttx/syslog/syslog.h","","int","int","FAR const IPTR char *","FAR va_list *" "nxmutex_breaklock","nuttx/mutex.h","","int","FAR mutex_t *","FAR bool *" +"nxmutex_clocklock","nuttx/mutex.h","","int","FAR mutex_t *","clockid_t","FAR const struct timespec *" "nxmutex_destroy","nuttx/mutex.h","","int","FAR mutex_t *" "nxmutex_lock","nuttx/mutex.h","","int","FAR mutex_t *" +"nxmutex_set_protocol","nuttx/mutex.h","","int","FAR mutex_t *","int" "nxmutex_timedlock","nuttx/mutex.h","","int","FAR mutex_t *","unsigned int" "nxmutex_trylock","nuttx/mutex.h","","int","FAR mutex_t *" "nxmutex_unlock","nuttx/mutex.h","","int","FAR mutex_t *"