1
0
Fork 0
forked from nuttx/nuttx-update

sched/semaphore: Move named semaphores to user space

This commit is contained in:
Ville Juven 2023-11-17 14:06:48 +02:00 committed by Xiang Xiao
parent c9bdadd541
commit 5f36a43609
11 changed files with 393 additions and 53 deletions

View file

@ -41,7 +41,7 @@
****************************************************************************/
/****************************************************************************
* Name: sem_close
* Name: nxsem_close
*
* Description:
* This function is called to indicate that the calling task is finished
@ -57,7 +57,7 @@
* sem - semaphore descriptor
*
* Returned Value:
* 0 (OK), or -1 (ERROR) if unsuccessful.
* 0 (OK), or negated errno if unsuccessful.
*
* Assumptions:
* - Care must be taken to avoid risking the deletion of a semaphore that
@ -66,7 +66,7 @@
*
****************************************************************************/
int sem_close(FAR sem_t *sem)
int nxsem_close(FAR sem_t *sem)
{
FAR struct nsem_inode_s *nsem;
struct inode *inode;

View file

@ -49,7 +49,7 @@
****************************************************************************/
/****************************************************************************
* Name: sem_open
* Name: nxsem_open
*
* Description:
* This function establishes a connection between named semaphores and a
@ -81,43 +81,23 @@
* SEM_VALUE_MAX.
*
* Returned Value:
* A pointer to sem_t or SEM_FAILED if unsuccessful.
* A pointer to sem_t or negated errno if unsuccessful.
*
* Assumptions:
*
****************************************************************************/
FAR sem_t *sem_open(FAR const char *name, int oflags, ...)
FAR sem_t *nxsem_open(FAR const char *name, int oflags, ...)
{
FAR struct inode *inode;
FAR struct nsem_inode_s *nsem;
FAR sem_t *sem = (FAR sem_t *)ERROR;
FAR sem_t *sem;
struct inode_search_s desc;
char fullpath[MAX_SEMPATH];
mode_t mode;
unsigned value;
int errcode;
int ret;
/* Make sure that a non-NULL name is supplied */
DEBUGASSERT(name != NULL);
if (name[0] == '/')
{
if (strlen(name) >= PATH_MAX)
{
set_errno(ENAMETOOLONG);
return SEM_FAILED;
}
if (strlen(strrchr(name, '/') + 1) >= NAME_MAX)
{
set_errno(ENAMETOOLONG);
return SEM_FAILED;
}
}
/* Get the full path to the semaphore */
snprintf(fullpath, MAX_SEMPATH,
@ -141,7 +121,7 @@ FAR sem_t *sem_open(FAR const char *name, int oflags, ...)
if (!INODE_IS_NAMEDSEM(inode))
{
errcode = ENXIO;
ret = -ENXIO;
goto errout_with_inode;
}
@ -151,7 +131,7 @@ FAR sem_t *sem_open(FAR const char *name, int oflags, ...)
if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
{
errcode = EEXIST;
ret = -EEXIST;
goto errout_with_inode;
}
@ -171,7 +151,7 @@ FAR sem_t *sem_open(FAR const char *name, int oflags, ...)
{
/* The semaphore does not exist and O_CREAT is not set */
errcode = ENOENT;
ret = -ENOENT;
goto errout_with_lock;
}
@ -189,7 +169,7 @@ FAR sem_t *sem_open(FAR const char *name, int oflags, ...)
if (value > SEM_VALUE_MAX)
{
errcode = EINVAL;
ret = -EINVAL;
goto errout_with_lock;
}
@ -200,7 +180,6 @@ FAR sem_t *sem_open(FAR const char *name, int oflags, ...)
ret = inode_lock();
if (ret < 0)
{
errcode = -ret;
goto errout_with_lock;
}
@ -209,7 +188,6 @@ FAR sem_t *sem_open(FAR const char *name, int oflags, ...)
if (ret < 0)
{
errcode = -ret;
goto errout_with_lock;
}
@ -220,7 +198,7 @@ FAR sem_t *sem_open(FAR const char *name, int oflags, ...)
nsem = group_malloc(NULL, sizeof(struct nsem_inode_s));
if (!nsem)
{
errcode = ENOMEM;
ret = -ENOMEM;
goto errout_with_inode;
}
@ -251,8 +229,7 @@ errout_with_inode:
errout_with_lock:
RELEASE_SEARCH(&desc);
set_errno(errcode);
return SEM_FAILED;
return (FAR sem_t *)(intptr_t)ret;
}
#endif /* CONFIG_FS_NAMED_SEMAPHORES */

View file

@ -41,7 +41,7 @@
****************************************************************************/
/****************************************************************************
* Name: sem_unlink
* Name: nxsem_unlink
*
* Description:
* This function removes the semaphore named by the input parameter 'name.'
@ -55,18 +55,17 @@
* name - Semaphore name
*
* Returned Value:
* 0 (OK), or -1 (ERROR) if unsuccessful.
* 0 (OK), or negated errno if unsuccessful.
*
* Assumptions:
*
****************************************************************************/
int sem_unlink(FAR const char *name)
int nxsem_unlink(FAR const char *name)
{
FAR struct inode *inode;
struct inode_search_s desc;
char fullpath[MAX_SEMPATH];
int errcode;
int ret;
/* Get the full path to the semaphore */
@ -83,7 +82,6 @@ int sem_unlink(FAR const char *name)
{
/* There is no inode that includes in this path */
errcode = -ret;
goto errout_with_search;
}
@ -95,7 +93,7 @@ int sem_unlink(FAR const char *name)
if (!INODE_IS_NAMEDSEM(inode))
{
errcode = ENOENT;
ret = -ENOENT;
goto errout_with_inode;
}
@ -106,13 +104,12 @@ int sem_unlink(FAR const char *name)
ret = inode_lock();
if (ret < 0)
{
errcode = -ret;
goto errout_with_inode;
}
if (inode->i_child != NULL)
{
errcode = ENOTEMPTY;
ret = -ENOTEMPTY;
goto errout_with_lock;
}
@ -139,7 +136,7 @@ int sem_unlink(FAR const char *name)
*/
inode_unlock();
ret = sem_close(&inode->u.i_nsem->ns_sem);
ret = nxsem_close(&inode->u.i_nsem->ns_sem);
RELEASE_SEARCH(&desc);
return ret;
@ -151,6 +148,5 @@ errout_with_inode:
errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode);
return ERROR;
return ret;
}

View file

@ -429,6 +429,98 @@ int nxsem_post(FAR sem_t *sem);
int nxsem_get_value(FAR sem_t *sem, FAR int *sval);
/****************************************************************************
* Name: nxsem_open
*
* Description:
* This function establishes a connection between named semaphores and a
* task. Following a call to sem_open() with the semaphore name, the task
* may reference the semaphore associated with name using the address
* returned by this call. The semaphore may be used in subsequent calls
* to sem_wait(), sem_trywait(), and sem_post(). The semaphore remains
* usable until the semaphore is closed by a successful call to
* sem_close().
*
* If a task makes multiple calls to sem_open() with the same name, then
* the same semaphore address is returned (provided there have been no
* calls to sem_unlink()).
*
* Input Parameters:
* name - Semaphore name
* oflags - Semaphore creation options. This may either or both of the
* following bit settings.
* oflags = 0: Connect to the semaphore only if it already exists.
* oflags = O_CREAT: Connect to the semaphore if it exists, otherwise
* create the semaphore.
* oflags = O_CREAT|O_EXCL: Create a new semaphore
* unless one of this name already exists.
* Optional parameters. When the O_CREAT flag is specified, two optional
* parameters are expected:
* 1. mode_t mode, and
* 2. unsigned int value. This initial value of the semaphore. Valid
* initial values of the semaphore must be less than or equal to
* SEM_VALUE_MAX.
*
* Returned Value:
* A pointer to sem_t or negated errno if unsuccessful.
*
* Assumptions:
*
****************************************************************************/
FAR sem_t *nxsem_open(FAR const char *name, int oflags, ...);
/****************************************************************************
* Name: nxsem_close
*
* Description:
* This function is called to indicate that the calling task is finished
* with the specified named semaphore, 'sem'. The sem_close() deallocates
* any system resources allocated by the system for this named semaphore.
*
* If the semaphore has not been removed with a call to sem_unlink(), then
* sem_close() has no effect on the named semaphore. However, when the
* named semaphore has been fully unlinked, the semaphore will vanish when
* the last task closes it.
*
* Input Parameters:
* sem - semaphore descriptor
*
* Returned Value:
* 0 (OK), or negated errno if unsuccessful.
*
* Assumptions:
* - Care must be taken to avoid risking the deletion of a semaphore that
* another calling task has already locked.
* - sem_close must not be called for an un-named semaphore
*
****************************************************************************/
int nxsem_close(FAR sem_t *sem);
/****************************************************************************
* Name: nxsem_unlink
*
* Description:
* This function removes the semaphore named by the input parameter 'name.'
* If the semaphore named by 'name' is currently referenced by other task,
* the sem_unlink() will have no effect on the state of the semaphore. If
* one or more processes have the semaphore open when sem_unlink() is
* called, destruction of the semaphore will be postponed until all
* references to the semaphore have been destroyed by calls of sem_close().
*
* Input Parameters:
* name - Semaphore name
*
* Returned Value:
* 0 (OK), or negated errno if unsuccessful.
*
* Assumptions:
*
****************************************************************************/
int nxsem_unlink(FAR const char *name);
/****************************************************************************
* Name: nxsem_reset
*

View file

@ -89,9 +89,9 @@ SYSCALL_LOOKUP(nxsem_wait, 1)
/* Named semaphores */
#ifdef CONFIG_FS_NAMED_SEMAPHORES
SYSCALL_LOOKUP(sem_open, 4)
SYSCALL_LOOKUP(sem_close, 1)
SYSCALL_LOOKUP(sem_unlink, 1)
SYSCALL_LOOKUP(nxsem_open, 4)
SYSCALL_LOOKUP(nxsem_close, 1)
SYSCALL_LOOKUP(nxsem_unlink, 1)
#endif
#ifndef CONFIG_BUILD_KERNEL

View file

@ -30,4 +30,8 @@ set(SRCS
sem_clockwait.c
sem_post.c)
if(CONFIG_FS_NAMED_SEMAPHORES)
list(APPEND SRCS sem_open.c sem_close.c sem_unlink.c)
endif()
target_sources(c PRIVATE ${SRCS})

View file

@ -24,6 +24,10 @@ 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
ifeq ($(CONFIG_FS_NAMED_SEMAPHORES),y)
CSRCS += sem_open.c sem_close.c sem_unlink.c
endif
# Add the semaphore directory to the build
DEPPATH += --dep-path semaphore

View file

@ -0,0 +1,75 @@
/****************************************************************************
* libs/libc/semaphore/sem_close.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 <nuttx/semaphore.h>
#ifdef CONFIG_FS_NAMED_SEMAPHORES
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sem_close
*
* Description:
* This function is called to indicate that the calling task is finished
* with the specified named semaphore, 'sem'. The sem_close() deallocates
* any system resources allocated by the system for this named semaphore.
*
* If the semaphore has not been removed with a call to sem_unlink(), then
* sem_close() has no effect on the named semaphore. However, when the
* named semaphore has been fully unlinked, the semaphore will vanish when
* the last task closes it.
*
* Input Parameters:
* sem - semaphore descriptor
*
* Returned Value:
* 0 (OK), or -1 (ERROR) if unsuccessful.
*
* Assumptions:
* - Care must be taken to avoid risking the deletion of a semaphore that
* another calling task has already locked.
* - sem_close must not be called for an un-named semaphore
*
****************************************************************************/
int sem_close(FAR sem_t *sem)
{
int ret;
ret = nxsem_close(sem);
if (ret < 0)
{
set_errno(-ret);
return ERROR;
}
return ret;
}
#endif /* CONFIG_FS_NAMED_SEMAPHORES */

View file

@ -0,0 +1,124 @@
/****************************************************************************
* libs/libc/semaphore/sem_open.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 <stdarg.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/semaphore.h>
#ifdef CONFIG_FS_NAMED_SEMAPHORES
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sem_open
*
* Description:
* This function establishes a connection between named semaphores and a
* task. Following a call to sem_open() with the semaphore name, the task
* may reference the semaphore associated with name using the address
* returned by this call. The semaphore may be used in subsequent calls
* to sem_wait(), sem_trywait(), and sem_post(). The semaphore remains
* usable until the semaphore is closed by a successful call to
* sem_close().
*
* If a task makes multiple calls to sem_open() with the same name, then
* the same semaphore address is returned (provided there have been no
* calls to sem_unlink()).
*
* Input Parameters:
* name - Semaphore name
* oflags - Semaphore creation options. This may either or both of the
* following bit settings.
* oflags = 0: Connect to the semaphore only if it already exists.
* oflags = O_CREAT: Connect to the semaphore if it exists, otherwise
* create the semaphore.
* oflags = O_CREAT|O_EXCL: Create a new semaphore
* unless one of this name already exists.
* Optional parameters. When the O_CREAT flag is specified, two optional
* parameters are expected:
* 1. mode_t mode, and
* 2. unsigned int value. This initial value of the semaphore. Valid
* initial values of the semaphore must be less than or equal to
* SEM_VALUE_MAX.
*
* Returned Value:
* A pointer to sem_t or SEM_FAILED if unsuccessful.
*
* Assumptions:
*
****************************************************************************/
FAR sem_t *sem_open(FAR const char *name, int oflags, ...)
{
FAR sem_t *sem;
va_list ap;
mode_t mode;
unsigned int value;
/* Make sure that a non-NULL name is supplied */
DEBUGASSERT(name != NULL);
if (name[0] == '/')
{
if (strlen(name) >= PATH_MAX)
{
set_errno(ENAMETOOLONG);
return SEM_FAILED;
}
if (strlen(strrchr(name, '/') + 1) >= NAME_MAX)
{
set_errno(ENAMETOOLONG);
return SEM_FAILED;
}
}
/* Off-load the variadic list */
va_start(ap, oflags);
mode = va_arg(ap, mode_t);
value = va_arg(ap, unsigned int);
va_end(ap);
/* Let nxsem_open() do the work */
sem = nxsem_open(name, oflags, mode, value);
if (sem < 0)
{
set_errno(-((intptr_t)sem));
return SEM_FAILED;
}
return sem;
}
#endif /* CONFIG_FS_NAMED_SEMAPHORES */

View file

@ -0,0 +1,68 @@
/****************************************************************************
* libs/libc/semaphore/sem_unlink.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_unlink
*
* Description:
* This function removes the semaphore named by the input parameter 'name.'
* If the semaphore named by 'name' is currently referenced by other task,
* the sem_unlink() will have no effect on the state of the semaphore. If
* one or more processes have the semaphore open when sem_unlink() is
* called, destruction of the semaphore will be postponed until all
* references to the semaphore have been destroyed by calls of sem_close().
*
* Input Parameters:
* name - Semaphore name
*
* Returned Value:
* 0 (OK), or -1 (ERROR) if unsuccessful.
*
* Assumptions:
*
****************************************************************************/
int sem_unlink(FAR const char *name)
{
int ret;
ret = nxsem_unlink(name);
if (ret < 0)
{
set_errno(-ret);
return ERROR;
}
return ret;
}

View file

@ -82,11 +82,14 @@
"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_close","nuttx/semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR sem_t *"
"nxsem_destroy","nuttx/semaphore.h","","int","FAR sem_t *"
"nxsem_open","nuttx/semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","FAR sem_t *","FAR const char *","int","...","mode_t","unsigned int"
"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_unlink","nuttx/semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR const char *"
"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"
@ -141,9 +144,6 @@
"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_close","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","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_unlink","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR const char *"
"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.