Skip to content

Commit

Permalink
sched/semaphore: Move named semaphores to user space
Browse files Browse the repository at this point in the history
  • Loading branch information
pussuw committed Nov 23, 2023
1 parent f91b719 commit f73581d
Show file tree
Hide file tree
Showing 11 changed files with 393 additions and 53 deletions.
6 changes: 3 additions & 3 deletions fs/semaphore/sem_close.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
****************************************************************************/

/****************************************************************************
* Name: sem_close
* Name: nxsem_close
*
* Description:
* This function is called to indicate that the calling task is finished
Expand All @@ -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
Expand All @@ -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;
Expand Down
43 changes: 10 additions & 33 deletions fs/semaphore/sem_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
****************************************************************************/

/****************************************************************************
* Name: sem_open
* Name: nxsem_open
*
* Description:
* This function establishes a connection between named semaphores and a
Expand Down Expand Up @@ -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,
Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -209,7 +188,6 @@ FAR sem_t *sem_open(FAR const char *name, int oflags, ...)

if (ret < 0)
{
errcode = -ret;
goto errout_with_lock;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -251,8 +229,7 @@ FAR sem_t *sem_open(FAR const char *name, int oflags, ...)

errout_with_lock:
RELEASE_SEARCH(&desc);
set_errno(errcode);
return SEM_FAILED;
return (FAR sem_t *)(intptr_t)ret;
}

#endif /* CONFIG_FS_NAMED_SEMAPHORES */
18 changes: 7 additions & 11 deletions fs/semaphore/sem_unlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
****************************************************************************/

/****************************************************************************
* Name: sem_unlink
* Name: nxsem_unlink
*
* Description:
* This function removes the semaphore named by the input parameter 'name.'
Expand All @@ -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 */
Expand All @@ -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;
}

Expand All @@ -95,7 +93,7 @@ int sem_unlink(FAR const char *name)

if (!INODE_IS_NAMEDSEM(inode))
{
errcode = ENOENT;
ret = -ENOENT;
goto errout_with_inode;
}

Expand All @@ -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;
}

Expand All @@ -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;

Expand All @@ -151,6 +148,5 @@ int sem_unlink(FAR const char *name)

errout_with_search:
RELEASE_SEARCH(&desc);
set_errno(errcode);
return ERROR;
return ret;
}
92 changes: 92 additions & 0 deletions include/nuttx/semaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,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
*
Expand Down
6 changes: 3 additions & 3 deletions include/sys/syscall_lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions libs/libc/semaphore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
4 changes: 4 additions & 0 deletions libs/libc/semaphore/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit f73581d

Please sign in to comment.