sched/semaphore: Move cancel point and errno handling to libc / user-space
This moves all the public POSIX semaphore functions into libc and with this most of the user-space logic is also moved; namely cancel point and errno handling. This also removes the need for the _SEM_XX macros used to differentiate which API is used per user-/kernel mode. Such macros are henceforth unnecessary.
This commit is contained in:
parent
34afef5cfb
commit
c9bdadd541
@ -75,17 +75,15 @@ SYSCALL_LOOKUP(sethostname, 2)
|
||||
|
||||
/* Semaphores */
|
||||
|
||||
SYSCALL_LOOKUP(nxsem_destroy, 1)
|
||||
SYSCALL_LOOKUP(nxsem_post, 1)
|
||||
SYSCALL_LOOKUP(nxsem_clockwait, 3)
|
||||
SYSCALL_LOOKUP(nxsem_timedwait, 2)
|
||||
SYSCALL_LOOKUP(nxsem_trywait, 1)
|
||||
SYSCALL_LOOKUP(nxsem_wait, 1)
|
||||
|
||||
SYSCALL_LOOKUP(sem_destroy, 1)
|
||||
SYSCALL_LOOKUP(sem_post, 1)
|
||||
SYSCALL_LOOKUP(sem_clockwait, 3)
|
||||
SYSCALL_LOOKUP(sem_timedwait, 2)
|
||||
SYSCALL_LOOKUP(sem_trywait, 1)
|
||||
SYSCALL_LOOKUP(sem_wait, 1)
|
||||
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
SYSCALL_LOOKUP(sem_setprotocol, 2)
|
||||
SYSCALL_LOOKUP(nxsem_set_protocol, 2)
|
||||
#endif
|
||||
|
||||
/* Named semaphores */
|
||||
|
@ -82,18 +82,18 @@ static bool nxmutex_is_reset(FAR mutex_t *mutex)
|
||||
|
||||
int nxmutex_init(FAR mutex_t *mutex)
|
||||
{
|
||||
int ret = _SEM_INIT(&mutex->sem, 0, 1);
|
||||
int ret = nxsem_init(&mutex->sem, 0, 1);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return _SEM_ERRVAL(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex->holder = NXMUTEX_NO_HOLDER;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
_SEM_SETPROTOCOL(&mutex->sem, SEM_TYPE_MUTEX | SEM_PRIO_INHERIT);
|
||||
nxsem_set_protocol(&mutex->sem, SEM_TYPE_MUTEX | SEM_PRIO_INHERIT);
|
||||
#else
|
||||
_SEM_SETPROTOCOL(&mutex->sem, SEM_TYPE_MUTEX);
|
||||
nxsem_set_protocol(&mutex->sem, SEM_TYPE_MUTEX);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@ -119,11 +119,11 @@ int nxmutex_init(FAR mutex_t *mutex)
|
||||
|
||||
int nxmutex_destroy(FAR mutex_t *mutex)
|
||||
{
|
||||
int ret = _SEM_DESTROY(&mutex->sem);
|
||||
int ret = nxsem_destroy(&mutex->sem);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return _SEM_ERRVAL(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex->holder = NXMUTEX_NO_HOLDER;
|
||||
@ -167,7 +167,7 @@ bool nxmutex_is_locked(FAR mutex_t *mutex)
|
||||
int cnt;
|
||||
int ret;
|
||||
|
||||
ret = _SEM_GETVALUE(&mutex->sem, &cnt);
|
||||
ret = nxsem_get_value(&mutex->sem, &cnt);
|
||||
|
||||
return ret >= 0 && cnt < 1;
|
||||
}
|
||||
@ -242,10 +242,10 @@ int nxmutex_trylock(FAR mutex_t *mutex)
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(!nxmutex_is_hold(mutex));
|
||||
ret = _SEM_TRYWAIT(&mutex->sem);
|
||||
ret = nxsem_trywait(&mutex->sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return _SEM_ERRVAL(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex->holder = _SCHED_GETTID();
|
||||
@ -291,11 +291,7 @@ int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout)
|
||||
|
||||
do
|
||||
{
|
||||
ret = _SEM_CLOCKWAIT(&mutex->sem, CLOCK_MONOTONIC, &rqtp);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = _SEM_ERRVAL(ret);
|
||||
}
|
||||
ret = nxsem_clockwait(&mutex->sem, CLOCK_MONOTONIC, &rqtp);
|
||||
}
|
||||
while (ret == -EINTR || ret == -ECANCELED);
|
||||
|
||||
@ -340,11 +336,10 @@ int nxmutex_unlock(FAR mutex_t *mutex)
|
||||
|
||||
mutex->holder = NXMUTEX_NO_HOLDER;
|
||||
|
||||
ret = _SEM_POST(&mutex->sem);
|
||||
ret = nxsem_post(&mutex->sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
mutex->holder = _SCHED_GETTID();
|
||||
ret = _SEM_ERRVAL(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -18,10 +18,16 @@
|
||||
#
|
||||
# ##############################################################################
|
||||
|
||||
set(SRCS sem_init.c sem_getprotocol.c sem_getvalue.c)
|
||||
|
||||
if(NOT CONFIG_PRIORITY_INHERITANCE)
|
||||
list(APPEND SRCS sem_setprotocol.c)
|
||||
endif()
|
||||
set(SRCS
|
||||
sem_init.c
|
||||
sem_setprotocol.c
|
||||
sem_getprotocol.c
|
||||
sem_getvalue.c
|
||||
sem_destroy.c
|
||||
sem_wait.c
|
||||
sem_trywait.c
|
||||
sem_timedwait.c
|
||||
sem_clockwait.c
|
||||
sem_post.c)
|
||||
|
||||
target_sources(c PRIVATE ${SRCS})
|
||||
|
@ -20,11 +20,9 @@
|
||||
|
||||
# Add the semaphore C files to the build
|
||||
|
||||
CSRCS += sem_init.c sem_getprotocol.c sem_getvalue.c
|
||||
|
||||
ifneq ($(CONFIG_PRIORITY_INHERITANCE),y)
|
||||
CSRCS += sem_setprotocol.c
|
||||
endif
|
||||
CSRCS += sem_init.c sem_setprotocol.c sem_getprotocol.c sem_getvalue.c
|
||||
CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_timedwait.c
|
||||
CSRCS += sem_clockwait.c sem_post.c
|
||||
|
||||
# Add the semaphore directory to the build
|
||||
|
||||
|
104
libs/libc/semaphore/sem_clockwait.c
Normal file
104
libs/libc/semaphore/sem_clockwait.c
Normal file
@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/semaphore/sem_clockwait.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 <nuttx/config.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/cancelpt.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_clockwait
|
||||
*
|
||||
* Description:
|
||||
* This function will lock the semaphore referenced by sem as in the
|
||||
* sem_wait() function. However, if the semaphore cannot be locked without
|
||||
* waiting for another process or thread to unlock the semaphore by
|
||||
* performing a sem_post() function, this wait will be terminated when the
|
||||
* specified timeout expires.
|
||||
*
|
||||
* The timeout will expire when the absolute time specified by abstime
|
||||
* passes, as measured by the clock on which timeouts are based (that is,
|
||||
* when the value of that clock equals or exceeds abstime), or if the
|
||||
* absolute time specified by abstime has already been passed at the
|
||||
* time of the call.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - Semaphore object
|
||||
* clockid - The timing source to use in the conversion
|
||||
* abstime - The absolute time to wait until a timeout is declared.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. On failure, -1 (ERROR) is returned
|
||||
* and the errno is set appropriately:
|
||||
*
|
||||
* EINVAL The sem argument does not refer to a valid semaphore. 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 semaphore could not be locked before the specified timeout
|
||||
* expired.
|
||||
* EDEADLK A deadlock condition was detected.
|
||||
* EINTR A signal interrupted this function.
|
||||
* ECANCELED May be returned if the thread is canceled while waiting.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_clockwait(FAR sem_t *sem, clockid_t clockid,
|
||||
FAR const struct timespec *abstime)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Verify the input parameters and, in case of an error, set
|
||||
* errno appropriately.
|
||||
*/
|
||||
|
||||
if (sem == NULL || abstime == NULL)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* sem_timedwait() is a cancellation point */
|
||||
|
||||
enter_cancellation_point();
|
||||
|
||||
/* Let nxsem_timedout() do the work */
|
||||
|
||||
ret = nxsem_clockwait(sem, clockid, abstime);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
leave_cancellation_point();
|
||||
return ret;
|
||||
}
|
79
libs/libc/semaphore/sem_destroy.c
Normal file
79
libs/libc/semaphore/sem_destroy.c
Normal file
@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/semaphore/sem_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 <nuttx/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_destroy
|
||||
*
|
||||
* Description:
|
||||
* This function is used to destroy the un-named semaphore indicated by
|
||||
* 'sem'. Only a semaphore that was created using nxsem_init() may be
|
||||
* destroyed using sem_destroy(); the effect of calling sem_destroy() with
|
||||
* a named semaphore is undefined. The effect of subsequent use of the
|
||||
* semaphore sem is undefined until sem is re-initialized by another call
|
||||
* to nxsem_init().
|
||||
*
|
||||
* The effect of destroying a semaphore upon which other processes are
|
||||
* currently blocked is undefined.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - Semaphore to be destroyed.
|
||||
*
|
||||
* Returned Value:
|
||||
* This function is a application interface. It returns zero (OK) if
|
||||
* successful. Otherwise, -1 (ERROR) is returned and the errno value is
|
||||
* set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_destroy(FAR sem_t *sem)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Assure a valid semaphore is specified */
|
||||
|
||||
if (sem == NULL)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = nxsem_destroy(sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
|
84
libs/libc/semaphore/sem_post.c
Normal file
84
libs/libc/semaphore/sem_post.c
Normal file
@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/semaphore/sem_post.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 <nuttx/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_post
|
||||
*
|
||||
* Description:
|
||||
* When a task has finished with a semaphore, it will call sem_post().
|
||||
* This function unlocks the semaphore referenced by sem by performing the
|
||||
* semaphore unlock operation on that semaphore.
|
||||
*
|
||||
* If the semaphore value resulting from this operation is positive, then
|
||||
* no tasks were blocked waiting for the semaphore to become unlocked; the
|
||||
* semaphore is simply incremented.
|
||||
*
|
||||
* If the value of the semaphore resulting from this operation is zero,
|
||||
* then one of the tasks blocked waiting for the semaphore shall be
|
||||
* allowed to return successfully from its call to nxsem_wait().
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - Semaphore descriptor
|
||||
*
|
||||
* Returned Value:
|
||||
* This function is a standard, POSIX application interface. It will
|
||||
* return zero (OK) if successful. Otherwise, -1 (ERROR) is returned and
|
||||
* the errno value is set appropriately.
|
||||
*
|
||||
* Assumptions:
|
||||
* This function may be called from an interrupt handler.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_post(FAR sem_t *sem)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Make sure we were supplied with a valid semaphore. */
|
||||
|
||||
if (sem == NULL)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = nxsem_post(sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -94,6 +94,8 @@ int nxsem_set_protocol(FAR sem_t *sem, int protocol)
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_PRIORITY_INHERITANCE */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_setprotocol
|
||||
*
|
||||
@ -144,5 +146,3 @@ int sem_setprotocol(FAR sem_t *sem, int protocol)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_PRIORITY_INHERITANCE */
|
||||
|
72
libs/libc/semaphore/sem_timedwait.c
Normal file
72
libs/libc/semaphore/sem_timedwait.c
Normal file
@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/semaphore/sem_timedwait.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 <assert.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_timedwait
|
||||
*
|
||||
* Description:
|
||||
* This function will lock the semaphore referenced by sem as in the
|
||||
* sem_wait() function. However, if the semaphore cannot be locked without
|
||||
* waiting for another process or thread to unlock the semaphore by
|
||||
* performing a sem_post() function, this wait will be terminated when the
|
||||
* specified timeout expires.
|
||||
*
|
||||
* The timeout will expire when the absolute time specified by abstime
|
||||
* passes, as measured by the clock on which timeouts are based (that is,
|
||||
* when the value of that clock equals or exceeds abstime), or if the
|
||||
* absolute time specified by abstime has already been passed at the
|
||||
* time of the call.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - Semaphore object
|
||||
* abstime - The absolute time to wait until a timeout is declared.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. On failure, -1 (ERROR) is returned
|
||||
* and the errno is set appropriately:
|
||||
*
|
||||
* EINVAL The sem argument does not refer to a valid semaphore. 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 semaphore could not be locked before the specified timeout
|
||||
* expired.
|
||||
* EDEADLK A deadlock condition was detected.
|
||||
* EINTR A signal interrupted this function.
|
||||
* ECANCELED May be returned if the thread is canceled while waiting.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
|
||||
{
|
||||
return sem_clockwait(sem, CLOCK_REALTIME, abstime);
|
||||
}
|
76
libs/libc/semaphore/sem_trywait.c
Normal file
76
libs/libc/semaphore/sem_trywait.c
Normal file
@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/semaphore/sem_trywait.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 <nuttx/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_trywait
|
||||
*
|
||||
* Description:
|
||||
* This function locks the specified semaphore only if the semaphore is
|
||||
* currently not locked. In either case, the call returns without
|
||||
* blocking.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - the semaphore descriptor
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success or -1 (ERROR) if unsuccessful. If this function
|
||||
* returns -1(ERROR), then the cause of the failure will be reported in
|
||||
* errno variable as:
|
||||
*
|
||||
* EINVAL - Invalid attempt to get the semaphore
|
||||
* EAGAIN - The semaphore is not available.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_trywait(FAR sem_t *sem)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sem == NULL)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Let nxsem_trywait do the real work */
|
||||
|
||||
ret = nxsem_trywait(sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
98
libs/libc/semaphore/sem_wait.c
Normal file
98
libs/libc/semaphore/sem_wait.c
Normal file
@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/semaphore/sem_wait.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 <nuttx/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/cancelpt.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_wait
|
||||
*
|
||||
* Description:
|
||||
* This function attempts to lock the semaphore referenced by 'sem'. If
|
||||
* the semaphore value is (<=) zero, then the calling task will not return
|
||||
* until it successfully acquires the lock.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - Semaphore descriptor.
|
||||
*
|
||||
* Returned Value:
|
||||
* This function is a standard, POSIX application interface. It returns
|
||||
* zero (OK) if successful. Otherwise, -1 (ERROR) is returned and
|
||||
* the errno value is set appropriately. Possible errno values include:
|
||||
*
|
||||
* - EINVAL: Invalid attempt to get the semaphore
|
||||
* - EINTR: The wait was interrupted by the receipt of a signal.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_wait(FAR sem_t *sem)
|
||||
{
|
||||
int errcode;
|
||||
int ret;
|
||||
|
||||
if (sem == NULL)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* sem_wait() is a cancellation point */
|
||||
|
||||
if (enter_cancellation_point())
|
||||
{
|
||||
#ifdef CONFIG_CANCELLATION_POINTS
|
||||
/* If there is a pending cancellation, then do not perform
|
||||
* the wait. Exit now with ECANCELED.
|
||||
*/
|
||||
|
||||
errcode = ECANCELED;
|
||||
goto errout_with_cancelpt;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Let nxsem_wait() do the real work */
|
||||
|
||||
ret = nxsem_wait(sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_cancelpt;
|
||||
}
|
||||
|
||||
leave_cancellation_point();
|
||||
return OK;
|
||||
|
||||
errout_with_cancelpt:
|
||||
set_errno(errcode);
|
||||
leave_cancellation_point();
|
||||
return ERROR;
|
||||
}
|
@ -34,7 +34,6 @@
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/cancelpt.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "clock/clock.h"
|
||||
@ -217,72 +216,3 @@ int nxsem_clockwait_uninterruptible(FAR sem_t *sem, clockid_t clockid,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_clockwait
|
||||
*
|
||||
* Description:
|
||||
* This function will lock the semaphore referenced by sem as in the
|
||||
* sem_wait() function. However, if the semaphore cannot be locked without
|
||||
* waiting for another process or thread to unlock the semaphore by
|
||||
* performing a sem_post() function, this wait will be terminated when the
|
||||
* specified timeout expires.
|
||||
*
|
||||
* The timeout will expire when the absolute time specified by abstime
|
||||
* passes, as measured by the clock on which timeouts are based (that is,
|
||||
* when the value of that clock equals or exceeds abstime), or if the
|
||||
* absolute time specified by abstime has already been passed at the
|
||||
* time of the call.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - Semaphore object
|
||||
* clockid - The timing source to use in the conversion
|
||||
* abstime - The absolute time to wait until a timeout is declared.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. On failure, -1 (ERROR) is returned
|
||||
* and the errno is set appropriately:
|
||||
*
|
||||
* EINVAL The sem argument does not refer to a valid semaphore. 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 semaphore could not be locked before the specified timeout
|
||||
* expired.
|
||||
* EDEADLK A deadlock condition was detected.
|
||||
* EINTR A signal interrupted this function.
|
||||
* ECANCELED May be returned if the thread is canceled while waiting.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_clockwait(FAR sem_t *sem, clockid_t clockid,
|
||||
FAR const struct timespec *abstime)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Verify the input parameters and, in case of an error, set
|
||||
* errno appropriately.
|
||||
*/
|
||||
|
||||
if (sem == NULL || abstime == NULL)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* sem_timedwait() is a cancellation point */
|
||||
|
||||
enter_cancellation_point();
|
||||
|
||||
/* Let nxsem_timedout() do the work */
|
||||
|
||||
ret = nxsem_clockwait(sem, clockid, abstime);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
leave_cancellation_point();
|
||||
return ret;
|
||||
}
|
||||
|
@ -80,49 +80,3 @@ int nxsem_destroy(FAR sem_t *sem)
|
||||
nxsem_destroyholder(sem);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_destroy
|
||||
*
|
||||
* Description:
|
||||
* This function is used to destroy the un-named semaphore indicated by
|
||||
* 'sem'. Only a semaphore that was created using nxsem_init() may be
|
||||
* destroyed using sem_destroy(); the effect of calling sem_destroy() with
|
||||
* a named semaphore is undefined. The effect of subsequent use of the
|
||||
* semaphore sem is undefined until sem is re-initialized by another call
|
||||
* to nxsem_init().
|
||||
*
|
||||
* The effect of destroying a semaphore upon which other processes are
|
||||
* currently blocked is undefined.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - Semaphore to be destroyed.
|
||||
*
|
||||
* Returned Value:
|
||||
* This function is a application interface. It returns zero (OK) if
|
||||
* successful. Otherwise, -1 (ERROR) is returned and the errno value is
|
||||
* set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_destroy(FAR sem_t *sem)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Assure a valid semaphore is specified */
|
||||
|
||||
if (sem == NULL)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = nxsem_destroy(sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -205,54 +205,3 @@ int nxsem_post(FAR sem_t *sem)
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_post
|
||||
*
|
||||
* Description:
|
||||
* When a task has finished with a semaphore, it will call sem_post().
|
||||
* This function unlocks the semaphore referenced by sem by performing the
|
||||
* semaphore unlock operation on that semaphore.
|
||||
*
|
||||
* If the semaphore value resulting from this operation is positive, then
|
||||
* no tasks were blocked waiting for the semaphore to become unlocked; the
|
||||
* semaphore is simply incremented.
|
||||
*
|
||||
* If the value of the semaphore resulting from this operation is zero,
|
||||
* then one of the tasks blocked waiting for the semaphore shall be
|
||||
* allowed to return successfully from its call to nxsem_wait().
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - Semaphore descriptor
|
||||
*
|
||||
* Returned Value:
|
||||
* This function is a standard, POSIX application interface. It will
|
||||
* return zero (OK) if successful. Otherwise, -1 (ERROR) is returned and
|
||||
* the errno value is set appropriately.
|
||||
*
|
||||
* Assumptions:
|
||||
* This function may be called from an interrupt handler.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_post(FAR sem_t *sem)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Make sure we were supplied with a valid semaphore. */
|
||||
|
||||
if (sem == NULL)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = nxsem_post(sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -103,55 +103,4 @@ int nxsem_set_protocol(FAR sem_t *sem, int protocol)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_setprotocol
|
||||
*
|
||||
* Description:
|
||||
* Set semaphore protocol attribute.
|
||||
*
|
||||
* One particularly important use of this function is when a semaphore
|
||||
* is used for inter-task communication like:
|
||||
*
|
||||
* TASK A TASK B
|
||||
* sem_init(sem, 0, 0);
|
||||
* nxsem_wait(sem);
|
||||
* sem_post(sem);
|
||||
* Awakens as holder
|
||||
*
|
||||
* In this case priority inheritance can interfere with the operation of
|
||||
* the semaphore. The problem is that when TASK A is restarted it is a
|
||||
* holder of the semaphore. However, it never calls sem_post(sem) so it
|
||||
* becomes *permanently* a holder of the semaphore and may have its
|
||||
* priority boosted when any other task tries to acquire the semaphore.
|
||||
*
|
||||
* The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately after
|
||||
* the sem_init() call so that there will be no priority inheritance
|
||||
* operations on this semaphore.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - A pointer to the semaphore whose attributes are to be
|
||||
* modified
|
||||
* protocol - The new protocol to use
|
||||
*
|
||||
* Returned Value:
|
||||
* This function is exposed as a non-standard application interface. It
|
||||
* returns zero (OK) if successful. Otherwise, -1 (ERROR) is returned and
|
||||
* the errno value is set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_setprotocol(FAR sem_t *sem, int protocol)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = nxsem_set_protocol(sem, protocol);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PRIORITY_INHERITANCE */
|
||||
|
@ -106,44 +106,3 @@ int nxsem_timedwait_uninterruptible(FAR sem_t *sem,
|
||||
{
|
||||
return nxsem_clockwait_uninterruptible(sem, CLOCK_REALTIME, abstime);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_timedwait
|
||||
*
|
||||
* Description:
|
||||
* This function will lock the semaphore referenced by sem as in the
|
||||
* sem_wait() function. However, if the semaphore cannot be locked without
|
||||
* waiting for another process or thread to unlock the semaphore by
|
||||
* performing a sem_post() function, this wait will be terminated when the
|
||||
* specified timeout expires.
|
||||
*
|
||||
* The timeout will expire when the absolute time specified by abstime
|
||||
* passes, as measured by the clock on which timeouts are based (that is,
|
||||
* when the value of that clock equals or exceeds abstime), or if the
|
||||
* absolute time specified by abstime has already been passed at the
|
||||
* time of the call.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - Semaphore object
|
||||
* abstime - The absolute time to wait until a timeout is declared.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. On failure, -1 (ERROR) is returned
|
||||
* and the errno is set appropriately:
|
||||
*
|
||||
* EINVAL The sem argument does not refer to a valid semaphore. 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 semaphore could not be locked before the specified timeout
|
||||
* expired.
|
||||
* EDEADLK A deadlock condition was detected.
|
||||
* EINTR A signal interrupted this function.
|
||||
* ECANCELED May be returned if the thread is canceled while waiting.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
|
||||
{
|
||||
return sem_clockwait(sem, CLOCK_REALTIME, abstime);
|
||||
}
|
||||
|
@ -105,46 +105,3 @@ int nxsem_trywait(FAR sem_t *sem)
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_trywait
|
||||
*
|
||||
* Description:
|
||||
* This function locks the specified semaphore only if the semaphore is
|
||||
* currently not locked. In either case, the call returns without
|
||||
* blocking.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - the semaphore descriptor
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success or -1 (ERROR) if unsuccessful. If this function
|
||||
* returns -1(ERROR), then the cause of the failure will be reported in
|
||||
* errno variable as:
|
||||
*
|
||||
* EINVAL - Invalid attempt to get the semaphore
|
||||
* EAGAIN - The semaphore is not available.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_trywait(FAR sem_t *sem)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sem == NULL)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Let nxsem_trywait do the real work */
|
||||
|
||||
ret = nxsem_trywait(sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <nuttx/init.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/cancelpt.h>
|
||||
|
||||
#include "sched/sched.h"
|
||||
#include "semaphore/semaphore.h"
|
||||
@ -251,67 +250,3 @@ int nxsem_wait_uninterruptible(FAR sem_t *sem)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_wait
|
||||
*
|
||||
* Description:
|
||||
* This function attempts to lock the semaphore referenced by 'sem'. If
|
||||
* the semaphore value is (<=) zero, then the calling task will not return
|
||||
* until it successfully acquires the lock.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sem - Semaphore descriptor.
|
||||
*
|
||||
* Returned Value:
|
||||
* This function is a standard, POSIX application interface. It returns
|
||||
* zero (OK) if successful. Otherwise, -1 (ERROR) is returned and
|
||||
* the errno value is set appropriately. Possible errno values include:
|
||||
*
|
||||
* - EINVAL: Invalid attempt to get the semaphore
|
||||
* - EINTR: The wait was interrupted by the receipt of a signal.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sem_wait(FAR sem_t *sem)
|
||||
{
|
||||
int errcode;
|
||||
int ret;
|
||||
|
||||
if (sem == NULL)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* sem_wait() is a cancellation point */
|
||||
|
||||
if (enter_cancellation_point())
|
||||
{
|
||||
#ifdef CONFIG_CANCELLATION_POINTS
|
||||
/* If there is a pending cancellation, then do not perform
|
||||
* the wait. Exit now with ECANCELED.
|
||||
*/
|
||||
|
||||
errcode = ECANCELED;
|
||||
goto errout_with_cancelpt;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Let nxsem_wait() do the real work */
|
||||
|
||||
ret = nxsem_wait(sem);
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_cancelpt;
|
||||
}
|
||||
|
||||
leave_cancellation_point();
|
||||
return OK;
|
||||
|
||||
errout_with_cancelpt:
|
||||
set_errno(errcode);
|
||||
leave_cancellation_point();
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -81,6 +81,12 @@
|
||||
"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 *"
|
||||
"nxsched_get_stackinfo","nuttx/sched.h","","int","pid_t","FAR struct stackinfo_s *"
|
||||
"nxsem_clockwait","nuttx/semaphore.h","","int","FAR sem_t *","clockid_t","FAR const struct timespec *"
|
||||
"nxsem_destroy","nuttx/semaphore.h","","int","FAR sem_t *"
|
||||
"nxsem_post","nuttx/semaphore.h","","int","FAR sem_t *"
|
||||
"nxsem_set_protocol","nuttx/semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t *","int"
|
||||
"nxsem_timedwait","nuttx/semaphore.h","","int","FAR sem_t *","FAR const struct timespec *"
|
||||
"nxsem_trywait","nuttx/semaphore.h","","int","FAR sem_t *"
|
||||
"nxsem_wait","nuttx/semaphore.h","","int","FAR sem_t *"
|
||||
"open","fcntl.h","","int","FAR const char *","int","...","mode_t"
|
||||
"pgalloc", "nuttx/arch.h", "defined(CONFIG_BUILD_KERNEL)", "uintptr_t", "uintptr_t", "unsigned int"
|
||||
@ -135,16 +141,9 @@
|
||||
"sched_unlock","sched.h","","int"
|
||||
"sched_yield","sched.h","","int"
|
||||
"select","sys/select.h","","int","int","FAR fd_set *","FAR fd_set *","FAR fd_set *","FAR struct timeval *"
|
||||
"sem_clockwait","semaphore.h","","int","FAR sem_t *","clockid_t","FAR const struct timespec *"
|
||||
"sem_close","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR sem_t *"
|
||||
"sem_destroy","semaphore.h","","int","FAR sem_t *"
|
||||
"sem_open","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","FAR sem_t *","FAR const char *","int","...","mode_t","unsigned int"
|
||||
"sem_post","semaphore.h","","int","FAR sem_t *"
|
||||
"sem_setprotocol","nuttx/semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t *","int"
|
||||
"sem_timedwait","semaphore.h","","int","FAR sem_t *","FAR const struct timespec *"
|
||||
"sem_trywait","semaphore.h","","int","FAR sem_t *"
|
||||
"sem_unlink","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR const char *"
|
||||
"sem_wait","semaphore.h","","int","FAR sem_t *"
|
||||
"send","sys/socket.h","defined(CONFIG_NET)","ssize_t","int","FAR const void *","size_t","int"
|
||||
"sendfile","sys/sendfile.h","","ssize_t","int","int","FAR off_t *","size_t"
|
||||
"sendmsg","sys/socket.h","defined(CONFIG_NET)","ssize_t","int","FAR struct msghdr *","int"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
Loading…
x
Reference in New Issue
Block a user