Completes VFS-based named semaphore implemetation. Still a little buggy
This commit is contained in:
parent
30694f064c
commit
650a0d0615
23 changed files with 147 additions and 455 deletions
|
@ -43,6 +43,5 @@ CSRCS += fs_binfs.c
|
|||
|
||||
DEPPATH += --dep-path binfs
|
||||
VPATH += :binfs
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)binfs}
|
||||
|
||||
endif
|
||||
|
|
|
@ -43,5 +43,4 @@ CSRCS += fs_closedir.c fs_opendir.c fs_readdir.c fs_rewinddir.c fs_seekdir.c
|
|||
|
||||
DEPPATH += --dep-path dirent
|
||||
VPATH += :dirent
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)dirent}
|
||||
endif
|
||||
|
|
|
@ -53,5 +53,4 @@ endif
|
|||
|
||||
DEPPATH += --dep-path driver
|
||||
VPATH += :driver
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)driver}
|
||||
endif
|
||||
|
|
|
@ -48,6 +48,5 @@ CSRCS += fs_mkfatfs.c fs_configfat.c fs_writefat.c
|
|||
|
||||
DEPPATH += --dep-path fat
|
||||
VPATH += :fat
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)fat}
|
||||
|
||||
endif
|
||||
|
|
|
@ -45,5 +45,4 @@ CSRCS += fs_inoderemove.c fs_inodereserve.c
|
|||
|
||||
DEPPATH += --dep-path inode
|
||||
VPATH += :inode
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)inode}
|
||||
endif
|
||||
|
|
|
@ -44,5 +44,4 @@ endif
|
|||
|
||||
DEPPATH += --dep-path mmap
|
||||
VPATH += :mmap
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)mmap}
|
||||
|
||||
|
|
|
@ -48,6 +48,5 @@ endif
|
|||
|
||||
DEPPATH += --dep-path mount
|
||||
VPATH += :mount
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)mount}
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -48,6 +48,5 @@ CSRCS += rpc_clnt.c nfs_util.c nfs_vfsops.c
|
|||
|
||||
DEPPATH += --dep-path nfs
|
||||
VPATH += :nfs
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)nfs}
|
||||
|
||||
endif
|
||||
|
|
|
@ -44,6 +44,5 @@ CSRCS += nxffs_block.c nxffs_blockstats.c nxffs_cache.c nxffs_dirent.c \
|
|||
|
||||
DEPPATH += --dep-path nxffs
|
||||
VPATH += :nxffs
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)nxffs}
|
||||
|
||||
endif
|
||||
|
|
|
@ -44,6 +44,5 @@ CSRCS += fs_procfscpuload.c
|
|||
|
||||
DEPPATH += --dep-path procfs
|
||||
VPATH += :procfs
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)procfs}
|
||||
|
||||
endif
|
||||
|
|
|
@ -43,6 +43,5 @@ CSRCS += fs_romfs.c fs_romfsutil.c
|
|||
|
||||
DEPPATH += --dep-path romfs
|
||||
VPATH += :romfs
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)romfs}
|
||||
|
||||
endif
|
||||
|
|
|
@ -37,11 +37,10 @@
|
|||
|
||||
ifneq ($(CONFIG_FS_NAMED_SEMAPHORES),0)
|
||||
|
||||
CSRCS += sem_open.c
|
||||
CSRCS += sem_open.c sem_close.c sem_unlink.c
|
||||
|
||||
# Include named semaphore build support
|
||||
|
||||
DEPPATH += --dep-path semaphore
|
||||
VPATH += :semaphore
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)semaphore}
|
||||
endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* sched/semaphore/sem_close.c
|
||||
* fs/semaphore/sem_close.c
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -39,16 +39,20 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <semaphore.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "semaphore/semaphore.h"
|
||||
#include "fs.h"
|
||||
|
||||
#ifdef CONFIG_FS_NAMED_SEMAPHORES
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -99,43 +103,47 @@
|
|||
|
||||
int sem_close(FAR sem_t *sem)
|
||||
{
|
||||
FAR nsem_t *psem;
|
||||
int ret = ERROR;
|
||||
FAR struct nsem_inode_s *nsem;
|
||||
struct inode *inode ;
|
||||
|
||||
/* Verify the inputs */
|
||||
DEBUGASSERT(sem);
|
||||
|
||||
if (sem)
|
||||
/* Upcast to get back to out internal representation */
|
||||
|
||||
nsem = (FAR struct nsem_inode_s *)sem;
|
||||
DEBUGASSERT(nsem->ns_inode);
|
||||
inode = nsem->ns_inode;
|
||||
|
||||
/* Decrement the reference count on the inode */
|
||||
|
||||
inode_semtake();
|
||||
if (inode->i_crefs)
|
||||
{
|
||||
sched_lock();
|
||||
|
||||
/* Search the list of named semaphores */
|
||||
|
||||
for (psem = (FAR nsem_t*)g_nsems.head;
|
||||
((psem) && (sem != &psem->sem));
|
||||
psem = psem->flink);
|
||||
|
||||
/* Check if we found it */
|
||||
|
||||
if (psem)
|
||||
{
|
||||
/* Decrement the count of sem_open connections to this semaphore */
|
||||
|
||||
if (psem->nconnect) psem->nconnect--;
|
||||
|
||||
/* If the semaphore is no long connected to any processes AND the
|
||||
* semaphore was previously unlinked, then deallocate it.
|
||||
*/
|
||||
|
||||
if (!psem->nconnect && psem->unlinked)
|
||||
{
|
||||
dq_rem((FAR dq_entry_t*)psem, &g_nsems);
|
||||
sched_kfree(psem);
|
||||
}
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
inode->i_crefs--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* If the semaphore was previously unlinked and the reference count has
|
||||
* decremented to zero, then release the semaphore and delete the inode
|
||||
* now.
|
||||
*/
|
||||
|
||||
if (inode->i_crefs <= 0 && (inode->i_flags & FSNODEFLAG_DELETED) != 0)
|
||||
{
|
||||
/* Destroy the semaphore and free the container */
|
||||
|
||||
sem_destroy(&nsem->ns_sem);
|
||||
group_free(NULL, nsem);
|
||||
|
||||
/* Release and free the inode */
|
||||
|
||||
inode_semgive();
|
||||
inode_free(inode->i_child);
|
||||
kmm_free(inode);
|
||||
return OK;
|
||||
}
|
||||
|
||||
inode_semgive();
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FS_NAMED_SEMAPHORES */
|
|
@ -53,6 +53,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "fs.h"
|
||||
#include "semaphore/semaphore.h"
|
||||
|
||||
#ifdef CONFIG_FS_NAMED_SEMAPHORES
|
||||
|
||||
|
@ -60,8 +61,6 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define MAX_SEMPATH 64
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
@ -122,7 +121,6 @@
|
|||
|
||||
FAR sem_t *sem_open (FAR const char *name, int oflags, ...)
|
||||
{
|
||||
FAR struct filelist *list;
|
||||
FAR struct inode *inode;
|
||||
FAR const char *relpath = NULL;
|
||||
mode_t mode;
|
||||
|
@ -150,12 +148,7 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...)
|
|||
|
||||
snprintf(fullpath, MAX_SEMPATH, CONFIG_FS_NAMED_SEMPATH "/%s", name);
|
||||
|
||||
/* Get the thread-specific file list */
|
||||
|
||||
list = sched_getfiles();
|
||||
DEBUGASSERT(list);
|
||||
|
||||
/* Get the inode for this file. This should succeed if the semaphore
|
||||
/* Get the inode for this semaphore. This should succeed if the semaphore
|
||||
* has already been created.
|
||||
*/
|
||||
|
||||
|
@ -180,11 +173,11 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...)
|
|||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
/* Allow a new connection to the semaphore */
|
||||
/* Return a reference to the semaphore, retaining the reference
|
||||
* count on the inode.
|
||||
*/
|
||||
|
||||
nsem = inode->u.i_nsem;
|
||||
nsem->ns_refs++;
|
||||
sem = &nsem->ns_sem;
|
||||
sem = &inode->u.i_nsem->ns_sem;
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -244,11 +237,23 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...)
|
|||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Initialize the semaphore */
|
||||
/* Link to the inode */
|
||||
|
||||
inode->u.i_nsem = nsem;
|
||||
nsem->ns_refs = 1;
|
||||
sem = &nsem->ns_sem;
|
||||
nsem->ns_inode = inode;
|
||||
|
||||
/* Initialize the inode */
|
||||
|
||||
INODE_SET_NAMEDSEM(inode);
|
||||
inode->i_crefs = 1;
|
||||
|
||||
/* Initialize the semaphore */
|
||||
|
||||
sem_init(&nsem->ns_sem, 0, value);
|
||||
|
||||
/* Return a reference to the semaphore */
|
||||
|
||||
sem = &nsem->ns_sem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* sched/semaphore/sem_unlink.c
|
||||
* fs/semaphore/sem_unlink.c
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -39,13 +39,15 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <semaphore.h>
|
||||
#include <sched.h>
|
||||
#include <queue.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include "fs.h"
|
||||
#include "semaphore/semaphore.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -95,47 +97,76 @@
|
|||
|
||||
int sem_unlink(FAR const char *name)
|
||||
{
|
||||
FAR nsem_t *psem;
|
||||
int ret = ERROR;
|
||||
FAR struct inode *inode;
|
||||
FAR const char *relpath = NULL;
|
||||
char fullpath[MAX_SEMPATH];
|
||||
int errcode;
|
||||
int ret;
|
||||
|
||||
/* Verify the input values */
|
||||
/* Get the full path to the semaphore */
|
||||
|
||||
if (name)
|
||||
snprintf(fullpath, MAX_SEMPATH, CONFIG_FS_NAMED_SEMPATH "/%s", name);
|
||||
|
||||
/* Get the inode for this semaphore. */
|
||||
|
||||
sched_lock();
|
||||
inode = inode_find(fullpath, &relpath);
|
||||
if (!inode)
|
||||
{
|
||||
sched_lock();
|
||||
/* There is no inode that includes in this path */
|
||||
|
||||
/* Find the named semaphore */
|
||||
|
||||
psem = sem_findnamed(name);
|
||||
|
||||
/* Check if the semaphore was found */
|
||||
|
||||
if (psem)
|
||||
{
|
||||
/* If the named semaphore was found and if there are no
|
||||
* connects to it, then deallocate it
|
||||
*/
|
||||
|
||||
if (!psem->nconnect)
|
||||
{
|
||||
dq_rem((FAR dq_entry_t*)psem, &g_nsems);
|
||||
sched_kfree(psem);
|
||||
}
|
||||
|
||||
/* If one or more process still has the semaphore open,
|
||||
* then just mark it as unlinked. The unlinked semaphore will
|
||||
* be deleted when the final process closes the semaphore.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
psem->unlinked = true;
|
||||
}
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
errcode = ENOENT;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* Verify that what we found is, indeed, a semaphore */
|
||||
|
||||
if (!INODE_IS_NAMEDSEM(inode))
|
||||
{
|
||||
errcode = ENXIO;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
/* Refuse to unlink the inode if it has children. I.e., if it is
|
||||
* functioning as a directory and the directory is not empty.
|
||||
*/
|
||||
|
||||
inode_semtake();
|
||||
if (inode->i_child != NULL)
|
||||
{
|
||||
errcode = ENOTEMPTY;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Mark the inode as deleted */
|
||||
|
||||
inode->i_flags |= FSNODEFLAG_DELETED;
|
||||
|
||||
/* Remove the old inode from the tree. Because we hold a reference count
|
||||
* on the inode, it will not be deleted now.
|
||||
*/
|
||||
|
||||
ret = inode_remove(fullpath);
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Now we do not release the reference count in the normal way (by calling
|
||||
* inode release. Rather, we call sem_close(). sem_close will decrement
|
||||
* the reference count on the inode. But it will also free the semaphore
|
||||
* if that reference count decrements to zero. Since we hold one reference,
|
||||
* that can only occur if the semaphore is not in-use.
|
||||
*/
|
||||
|
||||
return sem_close((FAR sem_t *)&inode->u.i_nsem);
|
||||
|
||||
errout_with_semaphore:
|
||||
inode_semgive();
|
||||
errout_with_inode:
|
||||
inode_release(inode);
|
||||
errout:
|
||||
set_errno(errcode);
|
||||
return ERROR;
|
||||
}
|
|
@ -49,6 +49,5 @@ CSRCS += smartfs_mksmartfs.c
|
|||
|
||||
DEPPATH += --dep-path smartfs
|
||||
VPATH += :smartfs
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)smartfs}
|
||||
|
||||
endif
|
||||
|
|
|
@ -59,7 +59,6 @@ endif
|
|||
|
||||
DEPPATH += --dep-path vfs
|
||||
VPATH += :vfs
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)vfs}
|
||||
endif
|
||||
|
||||
else
|
||||
|
@ -87,5 +86,4 @@ endif
|
|||
|
||||
DEPPATH += --dep-path vfs
|
||||
VPATH += :vfs
|
||||
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)vfs}
|
||||
endif
|
||||
|
|
|
@ -57,12 +57,14 @@
|
|||
#ifdef CONFIG_FS_NAMED_SEMAPHORES
|
||||
/* This is the named semaphore inode */
|
||||
|
||||
struct inode;
|
||||
struct nsem_inode_s
|
||||
{
|
||||
/* Payload unique to named semaphores */
|
||||
/* Inode payload unique to named semaphores */
|
||||
|
||||
sem_t ns_sem; /* The semaphore */
|
||||
FAR struct inode *ns_inode; /* Containing inode */
|
||||
|
||||
uint16_t ns_refs; /* Number of open references semaphore */
|
||||
sem_t ns_sem; /* The semaphore itself */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -33,9 +33,8 @@
|
|||
#
|
||||
############################################################################
|
||||
|
||||
SEM_SRCS = sem_initialize.c sem_destroy.c sem_open.c sem_close.c
|
||||
SEM_SRCS += sem_unlink.c sem_wait.c sem_trywait.c sem_timedwait.c
|
||||
SEM_SRCS += sem_post.c sem_findnamed.c
|
||||
SEM_SRCS = sem_initialize.c sem_destroy.c sem_wait.c sem_trywait.c
|
||||
SEM_SRCS += sem_timedwait.c sem_post.c
|
||||
|
||||
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
||||
SEM_SRCS += sem_waitirq.c
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/************************************************************************
|
||||
* sched/semaphore/sem_findnamed.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Included Files
|
||||
************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "semaphore/semaphore.h"
|
||||
|
||||
/************************************************************************
|
||||
* Definitions
|
||||
************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Private Type Declarations
|
||||
************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Global Variables
|
||||
************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Private Variables
|
||||
************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* Name: sem_findnamed
|
||||
*
|
||||
* Description:
|
||||
* Search the g_nsems list to find the semaphore with the matching name.
|
||||
*
|
||||
* Parameters:
|
||||
* name - semaphore name
|
||||
*
|
||||
* Return Value:
|
||||
* Pointer to the semaphore or NULL if not found
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
FAR nsem_t *sem_findnamed(const char *name)
|
||||
{
|
||||
FAR nsem_t *psem;
|
||||
|
||||
/* Search the list of named semaphores */
|
||||
|
||||
for (psem = (FAR nsem_t*)g_nsems.head; (psem); psem = psem->flink)
|
||||
{
|
||||
if (!strcmp(name, psem->name))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(psem);
|
||||
}
|
||||
|
|
@ -39,8 +39,6 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <queue.h>
|
||||
|
||||
#include "semaphore/semaphore.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -55,10 +53,6 @@
|
|||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/* This is a list of dyanamically allocated named semaphores */
|
||||
|
||||
dq_queue_t g_nsems;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
@ -90,10 +84,6 @@ dq_queue_t g_nsems;
|
|||
|
||||
void sem_initialize(void)
|
||||
{
|
||||
/* Initialize the queue of named semaphores */
|
||||
|
||||
dq_init(&g_nsems);
|
||||
|
||||
/* Initialize holder structures needed to support priority inheritiance */
|
||||
|
||||
sem_initholders();
|
||||
|
|
|
@ -1,208 +0,0 @@
|
|||
/****************************************************************************
|
||||
* sched/semaphore/sem_open.c
|
||||
*
|
||||
* Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include "semaphore/semaphore.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* 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()).
|
||||
*
|
||||
* Parameters:
|
||||
* name - Semaphore name
|
||||
* oflag - Semaphore creation options. This may either or both of the
|
||||
* following bit settings.
|
||||
* oflag = 0: Connect to the semaphore only if it already exists.
|
||||
* oflag = O_CREAT: Connect to the semaphore if it exists, otherwise
|
||||
* create the semaphore.
|
||||
* oflag = 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 (ignored), 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.
|
||||
*
|
||||
* Return Value:
|
||||
* A pointer to sem_t or -1 (ERROR) if unsuccessful.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR sem_t *sem_open (FAR const char *name, int oflag, ...)
|
||||
{
|
||||
int namelen;
|
||||
FAR nsem_t *psem;
|
||||
FAR sem_t *sem = (FAR sem_t*)ERROR;
|
||||
va_list arg; /* Points to each un-named argument */
|
||||
unsigned int value; /* Semaphore value parameter */
|
||||
|
||||
/* Make sure that a non-NULL name is supplied */
|
||||
|
||||
if (name)
|
||||
{
|
||||
/* The POSIX specification requires that the "check for the
|
||||
* existence of a semaphore and the creation of the semaphore
|
||||
* if it does not exist shall be atomic with respect to other
|
||||
* processes executing sem_open()..." A simple sched_lock()
|
||||
* should be sufficient to meet this requirement.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
namelen = strlen(name);
|
||||
if (namelen > 0)
|
||||
{
|
||||
/* See if the semaphore already exists */
|
||||
|
||||
psem = sem_findnamed(name);
|
||||
if (psem)
|
||||
{
|
||||
/* It does. Check if the caller wanted to created
|
||||
* a new semahore with this name.
|
||||
*/
|
||||
|
||||
if (!(oflag & O_CREAT) || !(oflag & O_EXCL))
|
||||
{
|
||||
/* Allow a new connection to the semaphore */
|
||||
|
||||
psem->nconnect++;
|
||||
sem = &psem->sem;
|
||||
}
|
||||
}
|
||||
|
||||
/* It doesn't exist. Should we create one? */
|
||||
|
||||
else if ((oflag & O_CREAT) != 0)
|
||||
{
|
||||
/* Set up to get the optional arguments needed to create
|
||||
* a message queue.
|
||||
*/
|
||||
|
||||
va_start(arg, oflag);
|
||||
(void)va_arg(arg, mode_t); /* Creation mode parameter (ignored) */
|
||||
value = va_arg(arg, unsigned int);
|
||||
|
||||
/* Verify that a legal initial value was selected. */
|
||||
|
||||
if (value <= SEM_VALUE_MAX)
|
||||
{
|
||||
/* Allocate memory for the new semaphore */
|
||||
|
||||
psem = (FAR nsem_t*)kmm_malloc((sizeof(nsem_t) + namelen + 1));
|
||||
if (psem)
|
||||
{
|
||||
/* Initialize the named semaphore */
|
||||
|
||||
sem = &psem->sem;
|
||||
sem_init(sem, 0, value);
|
||||
|
||||
psem->nconnect = 1;
|
||||
psem->unlinked = false;
|
||||
psem->name = (FAR char*)psem + sizeof(nsem_t);
|
||||
strcpy(psem->name, name);
|
||||
|
||||
/* Add the new semaphore to the list of named
|
||||
* semaphores
|
||||
*/
|
||||
|
||||
dq_addfirst((FAR dq_entry_t*)psem, &g_nsems);
|
||||
}
|
||||
|
||||
/* Clean-up variable argument stuff */
|
||||
|
||||
va_end(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
|
@ -57,28 +57,10 @@
|
|||
* Public Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/* This is the named semaphore structure */
|
||||
|
||||
struct nsem_s
|
||||
{
|
||||
FAR struct nsem_s *flink; /* Forward link */
|
||||
FAR struct nsem_s *blink; /* Backward link */
|
||||
uint16_t nconnect; /* Number of connections to semaphore */
|
||||
FAR char *name; /* Semaphore name (NULL if un-named) */
|
||||
bool unlinked; /* true if the semaphore has been unlinked */
|
||||
sem_t sem; /* The semaphore itself */
|
||||
};
|
||||
|
||||
typedef struct nsem_s nsem_t;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Variables
|
||||
****************************************************************************/
|
||||
|
||||
/* This is a list of dynamically allocated named semaphores */
|
||||
|
||||
extern dq_queue_t g_nsems;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
@ -95,7 +77,6 @@ extern "C"
|
|||
|
||||
void weak_function sem_initialize(void);
|
||||
void sem_waitirq(FAR struct tcb_s *wtcb, int errcode);
|
||||
FAR nsem_t *sem_findnamed(const char *name);
|
||||
|
||||
/* Special logic needed only by priority inheritance to manage collections of
|
||||
* holders of semaphores.
|
||||
|
@ -129,4 +110,3 @@ void sem_canceled(FAR struct tcb_s *stcb, FAR sem_t *sem);
|
|||
#endif
|
||||
|
||||
#endif /* __SCHED_SEMAPHORE_SEMAPHORE_H */
|
||||
|
||||
|
|
Loading…
Reference in a new issue