mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 17:48:54 +08:00
Merge branch 'cancelpt'
This commit is contained in:
+229
-122
File diff suppressed because it is too large
Load Diff
@@ -166,9 +166,9 @@ o Task/Scheduler (sched/)
|
|||||||
Priority: Low
|
Priority: Low
|
||||||
|
|
||||||
Title: REMOVE TASK_DELETE
|
Title: REMOVE TASK_DELETE
|
||||||
Description: Need to remove or fix task delete(). This interface is non-
|
Description: Need to remove asychronous fix task_delete(). This interface
|
||||||
standard and not safe. Arbitrary deleting tasks can cause
|
is non-standard and not safe. Arbitrary deleting tasks can
|
||||||
serious problems such as memory leaks and resources like
|
cause serious problems such as memory leaks and resources like
|
||||||
semaphores left in bad states.
|
semaphores left in bad states.
|
||||||
|
|
||||||
Task/process exit callbacks registered via atexit() or
|
Task/process exit callbacks registered via atexit() or
|
||||||
@@ -187,10 +187,12 @@ o Task/Scheduler (sched/)
|
|||||||
apps/netutils/thttpd to kill CGI tasks that timeout. So not
|
apps/netutils/thttpd to kill CGI tasks that timeout. So not
|
||||||
so simple to remove.
|
so simple to remove.
|
||||||
|
|
||||||
Option: Perhaps task_delete() should not do asynchronous
|
Option: With CONFIG_CANCELLATION_POINTS=y task_delete()
|
||||||
deletion but should rather do the same kind of
|
does not do asynchronous deletion but should rather do the
|
||||||
synchronization such as the pthread_cancellation points?
|
same kind of synchronization such as the pthread cancellation
|
||||||
(see pthread_cancel() issues).
|
points. In this configuration, none of the issues above
|
||||||
|
apply. It is only the asyncrhonous task deletion that cannot
|
||||||
|
be supported.
|
||||||
|
|
||||||
Status: Open
|
Status: Open
|
||||||
Priority: Low and not easily removable.
|
Priority: Low and not easily removable.
|
||||||
@@ -528,42 +530,6 @@ o Signals (sched/signal, arch/)
|
|||||||
o pthreads (sched/pthreads)
|
o pthreads (sched/pthreads)
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Title: CANCELLATION POINTS
|
|
||||||
Description: pthread_cancel(): Should implement cancellation points and
|
|
||||||
pthread_testcancel().
|
|
||||||
|
|
||||||
Internal implementation perhaps as follows. See list of
|
|
||||||
functions that are cancellation points on OpenGroup.org. In
|
|
||||||
general:
|
|
||||||
|
|
||||||
- Two types of cancellation. DEFFERRED and ASYCNCHOOUS:
|
|
||||||
PTHREAD_CANCEL_DEFERRED: A cancellation request is deferred
|
|
||||||
until the thread next calls a function that is a cancellation
|
|
||||||
point. This is the default cancelability type for all
|
|
||||||
threads.
|
|
||||||
PTHREAD_CANCEL_ASYNCHRONOUS: The thread can be canceled at
|
|
||||||
any time
|
|
||||||
DEFERRED should be the default but currently only
|
|
||||||
asyncrhononous is supported by NuttX
|
|
||||||
- To implement DEFERRED mode:
|
|
||||||
All cancellations must pend.
|
|
||||||
Check if the thread is within cancellation region, then
|
|
||||||
treat like a signal to wake up with -ECANCELED vs -EINTER
|
|
||||||
|
|
||||||
For each function/cancellation point
|
|
||||||
|
|
||||||
- Call enter_cancellation region() on entry. Checks for
|
|
||||||
pending cancellation and marks "within cancellation region"
|
|
||||||
in TCB flags.
|
|
||||||
- Will wake-up with -ECANCELED if cancellation occurs.
|
|
||||||
- Call leave_cancellation region() on exit. Checks for
|
|
||||||
pending cancellation and marks NOT "within cancellation region"
|
|
||||||
|
|
||||||
Perhaps task_delete() should do the same kind of synchronization?
|
|
||||||
|
|
||||||
Status: Open. No changes are planned.
|
|
||||||
Priority: Low, probably not that useful
|
|
||||||
|
|
||||||
Title: PTHREAD_PRIO_PROTECT
|
Title: PTHREAD_PRIO_PROTECT
|
||||||
Description: Extend pthread_mutexattr_setprotocol() support PTHREAD_PRIO_PROTECT:
|
Description: Extend pthread_mutexattr_setprotocol() support PTHREAD_PRIO_PROTECT:
|
||||||
|
|
||||||
@@ -624,6 +590,44 @@ o pthreads (sched/pthreads)
|
|||||||
solution. So I discarded a few hours of programming. Not a
|
solution. So I discarded a few hours of programming. Not a
|
||||||
big loss from the experience I gained."
|
big loss from the experience I gained."
|
||||||
|
|
||||||
|
Title: ISSUES WITH CANCELLATION POINTS
|
||||||
|
Description: According to POIX cancellation points must occur when a thread is executing
|
||||||
|
the following functions. There are some execptions as noted:
|
||||||
|
|
||||||
|
accept() mq_timedsend() NA putpmsg() sigtimedwait()
|
||||||
|
-4 aio_suspend() NA msgrcv() pwrite() NA sigwait()
|
||||||
|
NA clock_nanosleep() NA msgsnd() read() sigwaitinfo()
|
||||||
|
close() NA msync() NA readv() -1 sleep()
|
||||||
|
connect() nanosleep() recv() -2 system()
|
||||||
|
OK creat() open() recvfrom() NA tcdrain()
|
||||||
|
fcntl() pause() NA recvmsg() -1 usleep()
|
||||||
|
NA fdatasync() poll() select() OK wait()
|
||||||
|
fsync() pread() sem_timedwait() waitid()
|
||||||
|
NA getmsg() NA pselect() sem_wait() waitpid()
|
||||||
|
NA getpmsg() pthread_cond_timedwait() send() write()
|
||||||
|
NA lockf() pthread_cond_wait() NA sendmsg() NA writev()
|
||||||
|
mq_receive() pthread_join() sendto()
|
||||||
|
mq_send() pthread_testcancel() -3 sigpause()
|
||||||
|
mq_timedreceive() NA putmsg() sigsuspend()
|
||||||
|
|
||||||
|
NA Not supported
|
||||||
|
OK Doesn't need instrumentation. Handled by lower level calls.
|
||||||
|
-n See note n
|
||||||
|
|
||||||
|
NOTE 1: sleep() and usleep() are user-space functions in the C library and cannot
|
||||||
|
serve as cancellation points. They are, however, simple wrappers around nanosleep
|
||||||
|
which is a true cancellation point.
|
||||||
|
NOTE 2: system() is actually implemented in apps/ as part of NSH. It cannot be
|
||||||
|
a cancellation point either.
|
||||||
|
NOTE 3: sigpause() is a user-space function in the C library and cannot serve as
|
||||||
|
cancellation points. It is, however, a simple wrapper around sigsuspend()
|
||||||
|
which is a true cancellation point.
|
||||||
|
NOTE 4: aio_suspend() is a user-space function in the C library and cannot serve as
|
||||||
|
cancellation points. It does call around sigtimedwait() which is a true cancellation
|
||||||
|
point.
|
||||||
|
Status: Not really open. This is just the way it is.
|
||||||
|
Priority: Nothing additional is planned.
|
||||||
|
|
||||||
o Message Queues (sched/mqueue)
|
o Message Queues (sched/mqueue)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,10 @@ pthread_mutex_init NXpthread_mutex_init
|
|||||||
pthread_mutex_lock NXpthread_mutex_lock
|
pthread_mutex_lock NXpthread_mutex_lock
|
||||||
pthread_mutex_unlock NXpthread_mutex_unlock
|
pthread_mutex_unlock NXpthread_mutex_unlock
|
||||||
pthread_setspecific NXpthread_setspecific
|
pthread_setspecific NXpthread_setspecific
|
||||||
|
pthread_setcancelstate NXpthread_setcancelstate
|
||||||
|
pthread_setcanceltype NXpthread_setcanceltype
|
||||||
pthread_sigmask NXpthread_sigmask
|
pthread_sigmask NXpthread_sigmask
|
||||||
|
pthread_testcancel NXpthread_testcancel
|
||||||
pthread_yield NXpthread_yield
|
pthread_yield NXpthread_yield
|
||||||
ptsname NXptsname
|
ptsname NXptsname
|
||||||
ptsname_r NXptsname_r
|
ptsname_r NXptsname_r
|
||||||
|
|||||||
+14
-2
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/vfs/fs_close.c
|
* fs/vfs/fs_close.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2012, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -42,6 +42,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
|
|
||||||
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||||
@@ -82,7 +84,13 @@ int close(int fd)
|
|||||||
int errcode;
|
int errcode;
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
int ret;
|
int ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* close() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
/* Did we get a valid file descriptor? */
|
/* Did we get a valid file descriptor? */
|
||||||
|
|
||||||
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
||||||
@@ -93,7 +101,9 @@ int close(int fd)
|
|||||||
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||||
if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
|
if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
|
||||||
{
|
{
|
||||||
return net_close(fd);
|
ret = net_close(fd);
|
||||||
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -123,11 +133,13 @@ int close(int fd)
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/vfs/fs_fcntl.c
|
* fs/vfs/fs_fcntl.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009, 2012-2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2009, 2012-2014, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -44,20 +44,13 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <nuttx/sched.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
#include <nuttx/sched.h>
|
|
||||||
|
|
||||||
#include "inode/inode.h"
|
#include "inode/inode.h"
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -228,6 +221,10 @@ int fcntl(int fd, int cmd, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* fcntl() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Setup to access the variable argument list */
|
/* Setup to access the variable argument list */
|
||||||
|
|
||||||
va_start(ap, cmd);
|
va_start(ap, cmd);
|
||||||
@@ -244,6 +241,8 @@ int fcntl(int fd, int cmd, ...)
|
|||||||
{
|
{
|
||||||
/* The errno value has already been set */
|
/* The errno value has already been set */
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,5 +272,6 @@ int fcntl(int fd, int cmd, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-3
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/vfs/fs_fsync.c
|
* fs/vfs/fs_fsync.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2013-2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2013-2014, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -44,8 +44,9 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <nuttx/fs/fs.h>
|
|
||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
#include <nuttx/fs/fs.h>
|
||||||
|
|
||||||
#include "inode/inode.h"
|
#include "inode/inode.h"
|
||||||
|
|
||||||
@@ -117,6 +118,11 @@ errout:
|
|||||||
int fsync(int fd)
|
int fsync(int fd)
|
||||||
{
|
{
|
||||||
FAR struct file *filep;
|
FAR struct file *filep;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* fsync() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Get the file structure corresponding to the file descriptor. */
|
/* Get the file structure corresponding to the file descriptor. */
|
||||||
|
|
||||||
@@ -125,12 +131,15 @@ int fsync(int fd)
|
|||||||
{
|
{
|
||||||
/* The errno value has already been set */
|
/* The errno value has already been set */
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform the fsync operation */
|
/* Perform the fsync operation */
|
||||||
|
|
||||||
return file_fsync(filep);
|
ret = file_fsync(filep);
|
||||||
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !CONFIG_DISABLE_MOUNTPOINT */
|
#endif /* !CONFIG_DISABLE_MOUNTPOINT */
|
||||||
|
|||||||
+10
-5
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/vfs/fs_open.c
|
* fs/vfs/fs_open.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2011-2012, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -48,15 +48,12 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
|
|
||||||
#include "inode/inode.h"
|
#include "inode/inode.h"
|
||||||
#include "driver/driver.h"
|
#include "driver/driver.h"
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -106,6 +103,10 @@ int open(const char *path, int oflags, ...)
|
|||||||
# warning "File creation not implemented"
|
# warning "File creation not implemented"
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
/* open() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* If the file is opened for creation, then get the mode bits */
|
/* If the file is opened for creation, then get the mode bits */
|
||||||
|
|
||||||
if ((oflags & (O_WRONLY | O_CREAT)) != 0)
|
if ((oflags & (O_WRONLY | O_CREAT)) != 0)
|
||||||
@@ -159,6 +160,7 @@ int open(const char *path, int oflags, ...)
|
|||||||
|
|
||||||
/* Return the file descriptor */
|
/* Return the file descriptor */
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -204,6 +206,7 @@ int open(const char *path, int oflags, ...)
|
|||||||
{
|
{
|
||||||
/* The errno value has already been set */
|
/* The errno value has already been set */
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,6 +267,7 @@ int open(const char *path, int oflags, ...)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
errout_with_fd:
|
errout_with_fd:
|
||||||
@@ -272,5 +276,6 @@ errout_with_inode:
|
|||||||
inode_release(inode);
|
inode_release(inode);
|
||||||
errout:
|
errout:
|
||||||
set_errno(ret);
|
set_errno(ret);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
|
|
||||||
@@ -365,6 +366,10 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
|
|||||||
int errcode;
|
int errcode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* poll() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* This semaphore is used for signaling and, hence, should not have
|
/* This semaphore is used for signaling and, hence, should not have
|
||||||
* priority inheritance enabled.
|
* priority inheritance enabled.
|
||||||
*/
|
*/
|
||||||
@@ -425,6 +430,7 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sem_destroy(&sem);
|
sem_destroy(&sem);
|
||||||
|
leave_cancellation_point();
|
||||||
|
|
||||||
/* Check for errors */
|
/* Check for errors */
|
||||||
|
|
||||||
|
|||||||
+16
-9
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/vfs/fs_pread.c
|
* fs/vfs/fs_pread.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -43,12 +43,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -144,6 +141,11 @@ ssize_t file_pread(FAR struct file *filep, FAR void *buf, size_t nbytes,
|
|||||||
ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset)
|
ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset)
|
||||||
{
|
{
|
||||||
FAR struct file *filep;
|
FAR struct file *filep;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
/* pread() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Get the file structure corresponding to the file descriptor. */
|
/* Get the file structure corresponding to the file descriptor. */
|
||||||
|
|
||||||
@@ -152,10 +154,15 @@ ssize_t pread(int fd, FAR void *buf, size_t nbytes, off_t offset)
|
|||||||
{
|
{
|
||||||
/* The errno value has already been set */
|
/* The errno value has already been set */
|
||||||
|
|
||||||
return (ssize_t)ERROR;
|
ret = (ssize_t)ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Let file_pread do the real work */
|
||||||
|
|
||||||
|
ret = file_pread(filep, buf, nbytes, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let file_pread do the real work */
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
return file_pread(filep, buf, nbytes, offset);
|
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-9
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/vfs/fs_pwrite.c
|
* fs/vfs/fs_pwrite.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -43,12 +43,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -142,6 +139,11 @@ ssize_t file_pwrite(FAR struct file *filep, FAR const void *buf,
|
|||||||
ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset)
|
ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset)
|
||||||
{
|
{
|
||||||
FAR struct file *filep;
|
FAR struct file *filep;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
/* pread() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Get the file structure corresponding to the file descriptor. */
|
/* Get the file structure corresponding to the file descriptor. */
|
||||||
|
|
||||||
@@ -150,10 +152,15 @@ ssize_t pwrite(int fd, FAR const void *buf, size_t nbytes, off_t offset)
|
|||||||
{
|
{
|
||||||
/* The errno value has already been set */
|
/* The errno value has already been set */
|
||||||
|
|
||||||
return (ssize_t)ERROR;
|
ret = (ssize_t)ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Let file_pread do the real work */
|
||||||
|
|
||||||
|
ret = file_pwrite(filep, buf, nbytes, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let file_pread do the real work */
|
enter_cancellation_point();
|
||||||
|
return ret;
|
||||||
return file_pwrite(filep, buf, nbytes, offset);
|
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-16
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/vfs/fs_read.c
|
* fs/vfs/fs_read.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2012-2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2012-2014, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -38,19 +38,17 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "inode/inode.h"
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
/****************************************************************************
|
#include "inode/inode.h"
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
@@ -136,23 +134,30 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes)
|
|||||||
|
|
||||||
ssize_t read(int fd, FAR void *buf, size_t nbytes)
|
ssize_t read(int fd, FAR void *buf, size_t nbytes)
|
||||||
{
|
{
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
/* read() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Did we get a valid file descriptor? */
|
/* Did we get a valid file descriptor? */
|
||||||
|
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||||
/* No.. If networking is enabled, read() is the same as recv() with
|
/* No.. If networking is enabled, read() is the same as recv() with
|
||||||
* the flags parameter set to zero.
|
* the flags parameter set to zero. Note that recv() sets
|
||||||
|
* the errno variable.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
ret = recv(fd, buf, nbytes, 0);
|
||||||
return recv(fd, buf, nbytes, 0);
|
|
||||||
#else
|
#else
|
||||||
/* No networking... it is a bad descriptor in any event */
|
/* No networking... it is a bad descriptor in any event */
|
||||||
|
|
||||||
set_errno(EBADF);
|
set_errno(EBADF);
|
||||||
return ERROR;
|
ret = ERROR;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,20 +167,28 @@ ssize_t read(int fd, FAR void *buf, size_t nbytes)
|
|||||||
FAR struct file *filep;
|
FAR struct file *filep;
|
||||||
|
|
||||||
/* The descriptor is in a valid range to file descriptor... do the
|
/* The descriptor is in a valid range to file descriptor... do the
|
||||||
* read. First, get the file structure.
|
* read. First, get the file structure. Note that on failure,
|
||||||
|
* fs_getfilep() will set the errno variable.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
filep = fs_getfilep(fd);
|
filep = fs_getfilep(fd);
|
||||||
if (!filep)
|
if (filep == NULL)
|
||||||
{
|
{
|
||||||
/* The errno value has already been set */
|
/* The errno value has already been set */
|
||||||
|
|
||||||
return ERROR;
|
ret = ERROR;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Then let file_read do all of the work. Note that file_read()
|
||||||
|
* sets the errno variable.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Then let file_read do all of the work */
|
ret = file_read(filep, buf, nbytes);
|
||||||
|
}
|
||||||
return file_read(filep, buf, nbytes);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,6 +110,10 @@ int select(int nfds, FAR fd_set *readfds, FAR fd_set *writefds,
|
|||||||
int ndx;
|
int ndx;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* select() is cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* How many pollfd structures do we need to allocate? */
|
/* How many pollfd structures do we need to allocate? */
|
||||||
|
|
||||||
/* Initialize the descriptor list for poll() */
|
/* Initialize the descriptor list for poll() */
|
||||||
@@ -134,6 +138,7 @@ int select(int nfds, FAR fd_set *readfds, FAR fd_set *writefds,
|
|||||||
if (!pollset)
|
if (!pollset)
|
||||||
{
|
{
|
||||||
set_errno(ENOMEM);
|
set_errno(ENOMEM);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,6 +285,7 @@ int select(int nfds, FAR fd_set *readfds, FAR fd_set *writefds,
|
|||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
-22
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/vfs/fs_write.c
|
* fs/vfs/fs_write.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2012-2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2012-2014, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -49,11 +50,9 @@
|
|||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "inode/inode.h"
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
/****************************************************************************
|
#include "inode/inode.h"
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
@@ -72,7 +71,7 @@
|
|||||||
ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes)
|
ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes)
|
||||||
{
|
{
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
int ret;
|
ssize_t ret;
|
||||||
int errcode;
|
int errcode;
|
||||||
|
|
||||||
/* Was this file opened for write access? */
|
/* Was this file opened for write access? */
|
||||||
@@ -163,6 +162,11 @@ ssize_t write(int fd, FAR const void *buf, size_t nbytes)
|
|||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
FAR struct file *filep;
|
FAR struct file *filep;
|
||||||
#endif
|
#endif
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
/* write() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Did we get a valid file descriptor? */
|
/* Did we get a valid file descriptor? */
|
||||||
|
|
||||||
@@ -170,31 +174,44 @@ ssize_t write(int fd, FAR const void *buf, size_t nbytes)
|
|||||||
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* Write to a socket descriptor is equivalent to send with flags == 0 */
|
|
||||||
|
|
||||||
#if defined(CONFIG_NET_TCP) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
#if defined(CONFIG_NET_TCP) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||||
return send(fd, buf, nbytes, 0);
|
/* Write to a socket descriptor is equivalent to send with flags == 0.
|
||||||
|
* Note that send() will set the errno on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = send(fd, buf, nbytes, 0);
|
||||||
#else
|
#else
|
||||||
set_errno(EBADF);
|
set_errno(EBADF);
|
||||||
return ERROR;
|
ret = ERROR ERROR;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
/* The descriptor is in the right range to be a file descriptor... write
|
else
|
||||||
* to the file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
filep = fs_getfilep(fd);
|
|
||||||
if (!filep)
|
|
||||||
{
|
{
|
||||||
/* The errno value has already been set */
|
/* The descriptor is in the right range to be a file descriptor..
|
||||||
|
* write to the file. Note that fs_getfilep() will set the errno on
|
||||||
|
* failure.
|
||||||
|
*/
|
||||||
|
|
||||||
return ERROR;
|
filep = fs_getfilep(fd);
|
||||||
|
if (filep == NULL)
|
||||||
|
{
|
||||||
|
/* The errno value has already been set */
|
||||||
|
|
||||||
|
ret = ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Perform the write operation using the file descriptor as an
|
||||||
|
* index. Note that file_write() will set the errno on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = file_write(filep, buf, nbytes);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform the write operation using the file descriptor as an index */
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
return file_write(filep, buf, nbytes);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
+75
-1
@@ -2,7 +2,7 @@
|
|||||||
* include/nuttx/pthread.h
|
* include/nuttx/pthread.h
|
||||||
* Non-standard, NuttX-specific pthread-related declarations.
|
* Non-standard, NuttX-specific pthread-related declarations.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -127,6 +127,80 @@ EXTERN const pthread_attr_t g_default_pthread_attr;
|
|||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Cancellation Points.
|
||||||
|
*
|
||||||
|
* Cancellation points shall occur when a thread is executing the following
|
||||||
|
* functions:
|
||||||
|
*
|
||||||
|
* accept() mq_timedsend() putpmsg() sigtimedwait()
|
||||||
|
* aio_suspend() msgrcv() pwrite() sigwait()
|
||||||
|
* clock_nanosleep() msgsnd() read() sigwaitinfo()
|
||||||
|
* close() msync() readv() sleep()
|
||||||
|
* connect() nanosleep() recv() system()
|
||||||
|
* creat() open() recvfrom() tcdrain()
|
||||||
|
* fcntl() pause() recvmsg() usleep()
|
||||||
|
* fdatasync() poll() select() wait()
|
||||||
|
* fsync() pread() sem_timedwait() waitid()
|
||||||
|
* getmsg() pselect() sem_wait() waitpid()
|
||||||
|
* getpmsg() pthread_cond_timedwait() send() write()
|
||||||
|
* lockf() pthread_cond_wait() sendmsg() writev()
|
||||||
|
* mq_receive() pthread_join() sendto()
|
||||||
|
* mq_send() pthread_testcancel() sigpause()
|
||||||
|
* mq_timedreceive() putmsg() sigsuspend()
|
||||||
|
*
|
||||||
|
* Each of the above function must call enter_cancellation_point() on entry
|
||||||
|
* in order to establish the cancellation point and leave_cancellation_point()
|
||||||
|
* on exit. These functions are described below.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: enter_cancellation_point
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Called at the beginning of the cancellation point to establish the
|
||||||
|
* cancellation point. This function does the following:
|
||||||
|
*
|
||||||
|
* 1. If deferred cancellation does not apply to this thread, nothing is
|
||||||
|
* done, otherwise, it
|
||||||
|
* 2. Sets state information in the caller's TCB and increments a nesting
|
||||||
|
* count.
|
||||||
|
* 3. If this is the outermost nesting level, it checks if there is a
|
||||||
|
* pending cancellation and, if so, calls either exit() or
|
||||||
|
* pthread_exit(), depending upon the type of the thread.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_CANCELLATION_POINTS
|
||||||
|
void enter_cancellation_point(void);
|
||||||
|
#else
|
||||||
|
# define enter_cancellation_point()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: leave_cancellation_point
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Called at the end of the cancellation point. This function does the
|
||||||
|
* following:
|
||||||
|
*
|
||||||
|
* 1. If deferred cancellation does not apply to this thread, nothing is
|
||||||
|
* done, otherwise, it
|
||||||
|
* 2. Clears state information in the caller's TCB and decrements a
|
||||||
|
* nesting count.
|
||||||
|
* 3. If this is the outermost nesting level, it checks if there is a
|
||||||
|
* pending cancellation and, if so, calls either exit() or
|
||||||
|
* pthread_exit(), depending upon the type of the thread.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_CANCELLATION_POINTS
|
||||||
|
void leave_cancellation_point(void);
|
||||||
|
#else
|
||||||
|
# define leave_cancellation_point()
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,16 +141,17 @@
|
|||||||
# define TCB_FLAG_TTYPE_PTHREAD (1 << TCB_FLAG_TTYPE_SHIFT) /* User pthread */
|
# define TCB_FLAG_TTYPE_PTHREAD (1 << TCB_FLAG_TTYPE_SHIFT) /* User pthread */
|
||||||
# define TCB_FLAG_TTYPE_KERNEL (2 << TCB_FLAG_TTYPE_SHIFT) /* Kernel thread */
|
# define TCB_FLAG_TTYPE_KERNEL (2 << TCB_FLAG_TTYPE_SHIFT) /* Kernel thread */
|
||||||
#define TCB_FLAG_NONCANCELABLE (1 << 2) /* Bit 2: Pthread is non-cancelable */
|
#define TCB_FLAG_NONCANCELABLE (1 << 2) /* Bit 2: Pthread is non-cancelable */
|
||||||
#define TCB_FLAG_CANCEL_PENDING (1 << 3) /* Bit 3: Pthread cancel is pending */
|
#define TCB_FLAG_CANCEL_DEFERRED (1 << 3) /* Bit 3: Deferred (vs asynch) cancellation type */
|
||||||
#define TCB_FLAG_POLICY_SHIFT (4) /* Bit 4-5: Scheduling policy */
|
#define TCB_FLAG_CANCEL_PENDING (1 << 4) /* Bit 4: Pthread cancel is pending */
|
||||||
|
#define TCB_FLAG_POLICY_SHIFT (5) /* Bit 5-6: Scheduling policy */
|
||||||
#define TCB_FLAG_POLICY_MASK (3 << TCB_FLAG_POLICY_SHIFT)
|
#define TCB_FLAG_POLICY_MASK (3 << TCB_FLAG_POLICY_SHIFT)
|
||||||
# define TCB_FLAG_SCHED_FIFO (0 << TCB_FLAG_POLICY_SHIFT) /* FIFO scheding policy */
|
# define TCB_FLAG_SCHED_FIFO (0 << TCB_FLAG_POLICY_SHIFT) /* FIFO scheding policy */
|
||||||
# define TCB_FLAG_SCHED_RR (1 << TCB_FLAG_POLICY_SHIFT) /* Round robin scheding policy */
|
# define TCB_FLAG_SCHED_RR (1 << TCB_FLAG_POLICY_SHIFT) /* Round robin scheding policy */
|
||||||
# define TCB_FLAG_SCHED_SPORADIC (2 << TCB_FLAG_POLICY_SHIFT) /* Sporadic scheding policy */
|
# define TCB_FLAG_SCHED_SPORADIC (2 << TCB_FLAG_POLICY_SHIFT) /* Sporadic scheding policy */
|
||||||
# define TCB_FLAG_SCHED_OTHER (3 << TCB_FLAG_POLICY_SHIFT) /* Other scheding policy */
|
# define TCB_FLAG_SCHED_OTHER (3 << TCB_FLAG_POLICY_SHIFT) /* Other scheding policy */
|
||||||
#define TCB_FLAG_CPU_LOCKED (1 << 6) /* Bit 6: Locked to this CPU */
|
#define TCB_FLAG_CPU_LOCKED (1 << 7) /* Bit 7: Locked to this CPU */
|
||||||
#define TCB_FLAG_EXIT_PROCESSING (1 << 7) /* Bit 7: Exitting */
|
#define TCB_FLAG_EXIT_PROCESSING (1 << 8) /* Bit 8: Exitting */
|
||||||
/* Bits 8-15: Available */
|
/* Bits 9-15: Available */
|
||||||
|
|
||||||
/* Values for struct task_group tg_flags */
|
/* Values for struct task_group tg_flags */
|
||||||
|
|
||||||
@@ -582,6 +583,9 @@ struct tcb_s
|
|||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
int16_t irqcount; /* 0=interrupts enabled */
|
int16_t irqcount; /* 0=interrupts enabled */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_CANCELLATION_POINTS
|
||||||
|
int16_t cpcount; /* Nested cancellation point count */
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC)
|
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC)
|
||||||
int32_t timeslice; /* RR timeslice OR Sporadic budget */
|
int32_t timeslice; /* RR timeslice OR Sporadic budget */
|
||||||
|
|||||||
+7
-1
@@ -115,11 +115,16 @@
|
|||||||
|
|
||||||
#define PTHREAD_DEFAULT_PRIORITY 100
|
#define PTHREAD_DEFAULT_PRIORITY 100
|
||||||
|
|
||||||
/* Cancellation states returned by pthread_cancelstate() */
|
/* Cancellation states used by pthread_setcancelstate() */
|
||||||
|
|
||||||
#define PTHREAD_CANCEL_ENABLE (0)
|
#define PTHREAD_CANCEL_ENABLE (0)
|
||||||
#define PTHREAD_CANCEL_DISABLE (1)
|
#define PTHREAD_CANCEL_DISABLE (1)
|
||||||
|
|
||||||
|
/* Cancellation types used by pthread_setcanceltype() */
|
||||||
|
|
||||||
|
#define PTHREAD_CANCEL_DEFERRED (0)
|
||||||
|
#define PTHREAD_CANCEL_ASYNCHRONOUS (1)
|
||||||
|
|
||||||
/* Thread return value when a pthread is canceled */
|
/* Thread return value when a pthread is canceled */
|
||||||
|
|
||||||
#define PTHREAD_CANCELED ((FAR void*)ERROR)
|
#define PTHREAD_CANCELED ((FAR void*)ERROR)
|
||||||
@@ -340,6 +345,7 @@ int pthread_detach(pthread_t thread);
|
|||||||
void pthread_exit(pthread_addr_t value) noreturn_function;
|
void pthread_exit(pthread_addr_t value) noreturn_function;
|
||||||
int pthread_cancel(pthread_t thread);
|
int pthread_cancel(pthread_t thread);
|
||||||
int pthread_setcancelstate(int state, FAR int *oldstate);
|
int pthread_setcancelstate(int state, FAR int *oldstate);
|
||||||
|
int pthread_setcanceltype(int type, FAR int *oldtype);
|
||||||
void pthread_testcancel(void);
|
void pthread_testcancel(void);
|
||||||
|
|
||||||
/* A thread may set up cleanup functions to execut when the thread exits or
|
/* A thread may set up cleanup functions to execut when the thread exits or
|
||||||
|
|||||||
@@ -47,27 +47,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_FS_AIO
|
#ifdef CONFIG_FS_AIO
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
/* Configuration ************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Types
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|||||||
@@ -43,26 +43,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Type Declarations
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|||||||
+16
-1
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/socket/accept.c
|
* net/socket/accept.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2012, 2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2012, 2015-2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
|
|
||||||
#include "tcp/tcp.h"
|
#include "tcp/tcp.h"
|
||||||
@@ -132,6 +133,10 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
|
|||||||
|
|
||||||
DEBUGASSERT(psock != NULL);
|
DEBUGASSERT(psock != NULL);
|
||||||
|
|
||||||
|
/* Treat as a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Is the socket a stream? */
|
/* Is the socket a stream? */
|
||||||
|
|
||||||
if (psock->s_type != SOCK_STREAM)
|
if (psock->s_type != SOCK_STREAM)
|
||||||
@@ -269,6 +274,8 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
|
|||||||
|
|
||||||
newsock->s_flags |= _SF_CONNECTED;
|
newsock->s_flags |= _SF_CONNECTED;
|
||||||
newsock->s_flags &= ~_SF_CLOSED;
|
newsock->s_flags &= ~_SF_CLOSED;
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
errout_after_accept:
|
errout_after_accept:
|
||||||
@@ -276,6 +283,7 @@ errout_after_accept:
|
|||||||
|
|
||||||
errout:
|
errout:
|
||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,6 +363,10 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
|
|||||||
int errcode;
|
int errcode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* accept() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Verify that the sockfd corresponds to valid, allocated socket */
|
/* Verify that the sockfd corresponds to valid, allocated socket */
|
||||||
|
|
||||||
if (psock == NULL || psock->s_crefs <= 0)
|
if (psock == NULL || psock->s_crefs <= 0)
|
||||||
@@ -402,9 +414,11 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
|
|||||||
/* The errno value has already been set */
|
/* The errno value has already been set */
|
||||||
|
|
||||||
sockfd_release(newfd);
|
sockfd_release(newfd);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return newfd;
|
return newfd;
|
||||||
|
|
||||||
errout_with_socket:
|
errout_with_socket:
|
||||||
@@ -412,6 +426,7 @@ errout_with_socket:
|
|||||||
|
|
||||||
errout:
|
errout:
|
||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-1
@@ -51,6 +51,7 @@
|
|||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
|
|
||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
#include <nuttx/net/udp.h>
|
#include <nuttx/net/udp.h>
|
||||||
@@ -516,6 +517,10 @@ int psock_connect(FAR struct socket *psock, FAR const struct sockaddr *addr,
|
|||||||
#endif
|
#endif
|
||||||
int errcode;
|
int errcode;
|
||||||
|
|
||||||
|
/* Treat as a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Verify that the psock corresponds to valid, allocated socket */
|
/* Verify that the psock corresponds to valid, allocated socket */
|
||||||
|
|
||||||
if (!psock || psock->s_crefs <= 0)
|
if (!psock || psock->s_crefs <= 0)
|
||||||
@@ -663,10 +668,12 @@ int psock_connect(FAR struct socket *psock, FAR const struct sockaddr *addr,
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -741,13 +748,21 @@ errout:
|
|||||||
|
|
||||||
int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen)
|
int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* accept() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Get the underlying socket structure */
|
/* Get the underlying socket structure */
|
||||||
|
|
||||||
FAR struct socket *psock = sockfd_socket(sockfd);
|
FAR struct socket *psock = sockfd_socket(sockfd);
|
||||||
|
|
||||||
/* Then let psock_connect() do all of the work */
|
/* Then let psock_connect() do all of the work */
|
||||||
|
|
||||||
return psock_connect(psock, addr, addrlen);
|
ret = psock_connect(psock, addr, addrlen);
|
||||||
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET */
|
#endif /* CONFIG_NET */
|
||||||
|
|||||||
@@ -71,6 +71,8 @@
|
|||||||
|
|
||||||
ssize_t recv(int sockfd, FAR void *buf, size_t len, int flags)
|
ssize_t recv(int sockfd, FAR void *buf, size_t len, int flags)
|
||||||
{
|
{
|
||||||
|
/* recv is a cancellation point, but that can all be handled by recvfrom */
|
||||||
|
|
||||||
return recvfrom(sockfd, buf, len, flags, NULL, 0);
|
return recvfrom(sockfd, buf, len, flags, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-1
@@ -57,6 +57,7 @@
|
|||||||
|
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
#include <nuttx/net/iob.h>
|
#include <nuttx/net/iob.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
@@ -1851,6 +1852,10 @@ ssize_t psock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
int errcode;
|
int errcode;
|
||||||
|
|
||||||
|
/* Treat as a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Verify that non-NULL pointers were passed */
|
/* Verify that non-NULL pointers were passed */
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FEATURES
|
#ifdef CONFIG_DEBUG_FEATURES
|
||||||
@@ -2013,10 +2018,12 @@ ssize_t psock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||||||
|
|
||||||
/* Success return */
|
/* Success return */
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2076,6 +2083,11 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
|
|||||||
FAR struct sockaddr *from, FAR socklen_t *fromlen)
|
FAR struct sockaddr *from, FAR socklen_t *fromlen)
|
||||||
{
|
{
|
||||||
FAR struct socket *psock;
|
FAR struct socket *psock;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
/* recvfrom() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Get the underlying socket structure */
|
/* Get the underlying socket structure */
|
||||||
|
|
||||||
@@ -2083,7 +2095,9 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
|
|||||||
|
|
||||||
/* Then let psock_recvfrom() do all of the work */
|
/* Then let psock_recvfrom() do all of the work */
|
||||||
|
|
||||||
return psock_recvfrom(psock, buf, len, flags, from, fromlen);
|
ret = psock_recvfrom(psock, buf, len, flags, from, fromlen);
|
||||||
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET */
|
#endif /* CONFIG_NET */
|
||||||
|
|||||||
+24
-2
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/socket/send.c
|
* net/socket/send.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -43,6 +43,8 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "tcp/tcp.h"
|
#include "tcp/tcp.h"
|
||||||
#include "udp/udp.h"
|
#include "udp/udp.h"
|
||||||
#include "pkt/pkt.h"
|
#include "pkt/pkt.h"
|
||||||
@@ -122,6 +124,10 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* Treat as a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
switch (psock->s_type)
|
switch (psock->s_type)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_NET_PKT)
|
#if defined(CONFIG_NET_PKT)
|
||||||
@@ -192,6 +198,7 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,5 +268,20 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
|
|||||||
|
|
||||||
ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags)
|
ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags)
|
||||||
{
|
{
|
||||||
return psock_send(sockfd_socket(sockfd), buf, len, flags);
|
FAR struct socket *psock;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
/* send() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
|
/* Get the underlying socket structure */
|
||||||
|
|
||||||
|
psock = sockfd_socket(sockfd);
|
||||||
|
|
||||||
|
/* And let psock_send do all of the work */
|
||||||
|
|
||||||
|
ret = psock_send(psock, buf, len, flags, to, tolen);
|
||||||
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -309,6 +309,11 @@ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,
|
|||||||
FAR const struct sockaddr *to, socklen_t tolen)
|
FAR const struct sockaddr *to, socklen_t tolen)
|
||||||
{
|
{
|
||||||
FAR struct socket *psock;
|
FAR struct socket *psock;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
/* sendto() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Get the underlying socket structure */
|
/* Get the underlying socket structure */
|
||||||
|
|
||||||
@@ -316,5 +321,7 @@ ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,
|
|||||||
|
|
||||||
/* And let psock_sendto do all of the work */
|
/* And let psock_sendto do all of the work */
|
||||||
|
|
||||||
return psock_sendto(psock, buf, len, flags, to, tolen);
|
ret = psock_sendto(psock, buf, len, flags, to, tolen);
|
||||||
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -560,6 +560,15 @@ config PTHREAD_CLEANUP_STACKSIZE
|
|||||||
|
|
||||||
endmenu # Pthread Options
|
endmenu # Pthread Options
|
||||||
|
|
||||||
|
config CANCELLATION_POINTS
|
||||||
|
bool "Cancellation points"
|
||||||
|
default n
|
||||||
|
depends on EXPERIMENTAL
|
||||||
|
---help---
|
||||||
|
Enable POSIX cancellation points for pthread_cancel(). If selected,
|
||||||
|
cancellation points will also used with the () task_delete() API even if
|
||||||
|
pthreads are not enabled.
|
||||||
|
|
||||||
menu "Performance Monitoring"
|
menu "Performance Monitoring"
|
||||||
|
|
||||||
config SCHED_CPULOAD
|
config SCHED_CPULOAD
|
||||||
|
|||||||
@@ -218,6 +218,13 @@ int os_smp_start(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
up_initial_state(tcb);
|
up_initial_state(tcb);
|
||||||
|
|
||||||
|
/* Set the task flags to indicate that this is a kernel thread and that
|
||||||
|
* this task is locked to this CPU.
|
||||||
|
*/
|
||||||
|
|
||||||
|
tcb->flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_NONCANCELABLE | TCB_FLAG_CPU_LOCKED);
|
||||||
|
tcb->cpu = cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then start all of the other CPUs after we have completed the memory
|
/* Then start all of the other CPUs after we have completed the memory
|
||||||
|
|||||||
@@ -470,10 +470,11 @@ void os_start(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_LOCKED);
|
g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL TCB_FLAG_NONCANCELABLE |
|
||||||
|
TCB_FLAG_CPU_LOCKED);
|
||||||
g_idletcb[cpu].cmn.cpu = cpu;
|
g_idletcb[cpu].cmn.cpu = cpu;
|
||||||
#else
|
#else
|
||||||
g_idletcb[cpu].cmn.flags = TCB_FLAG_TTYPE_KERNEL;
|
g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_NONCANCELABLE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "mqueue/mqueue.h"
|
#include "mqueue/mqueue.h"
|
||||||
|
|
||||||
@@ -103,12 +104,17 @@ ssize_t mq_receive(mqd_t mqdes, FAR char *msg, size_t msglen,
|
|||||||
|
|
||||||
DEBUGASSERT(up_interrupt_context() == false);
|
DEBUGASSERT(up_interrupt_context() == false);
|
||||||
|
|
||||||
|
/* mq_receive() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Verify the input parameters and, in case of an error, set
|
/* Verify the input parameters and, in case of an error, set
|
||||||
* errno appropriately.
|
* errno appropriately.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (mq_verifyreceive(mqdes, msg, msglen) != OK)
|
if (mq_verifyreceive(mqdes, msg, msglen) != OK)
|
||||||
{
|
{
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,5 +151,6 @@ ssize_t mq_receive(mqd_t mqdes, FAR char *msg, size_t msglen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "mqueue/mqueue.h"
|
#include "mqueue/mqueue.h"
|
||||||
|
|
||||||
@@ -103,12 +104,17 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio)
|
|||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
int ret = ERROR;
|
int ret = ERROR;
|
||||||
|
|
||||||
|
/* mq_send() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Verify the input parameters -- setting errno appropriately
|
/* Verify the input parameters -- setting errno appropriately
|
||||||
* on any failures to verify.
|
* on any failures to verify.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (mq_verifysend(mqdes, msg, msglen, prio) != OK)
|
if (mq_verifysend(mqdes, msg, msglen, prio) != OK)
|
||||||
{
|
{
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,5 +183,6 @@ int mq_send(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/wdog.h>
|
#include <nuttx/wdog.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "clock/clock.h"
|
#include "clock/clock.h"
|
||||||
@@ -174,18 +175,24 @@ ssize_t mq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
|
|||||||
|
|
||||||
DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL);
|
DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL);
|
||||||
|
|
||||||
|
/* mq_timedreceive() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Verify the input parameters and, in case of an error, set
|
/* Verify the input parameters and, in case of an error, set
|
||||||
* errno appropriately.
|
* errno appropriately.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (mq_verifyreceive(mqdes, msg, msglen) != OK)
|
if (mq_verifyreceive(mqdes, msg, msglen) != OK)
|
||||||
{
|
{
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!abstime || abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
|
if (!abstime || abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
|
||||||
{
|
{
|
||||||
set_errno(EINVAL);
|
set_errno(EINVAL);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +205,7 @@ ssize_t mq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
|
|||||||
if (!rtcb->waitdog)
|
if (!rtcb->waitdog)
|
||||||
{
|
{
|
||||||
set_errno(EINVAL);
|
set_errno(EINVAL);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +258,7 @@ ssize_t mq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
|
|||||||
rtcb->waitdog = NULL;
|
rtcb->waitdog = NULL;
|
||||||
|
|
||||||
set_errno(result);
|
set_errno(result);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,5 +297,6 @@ ssize_t mq_timedreceive(mqd_t mqdes, FAR char *msg, size_t msglen,
|
|||||||
sched_unlock();
|
sched_unlock();
|
||||||
wd_delete(rtcb->waitdog);
|
wd_delete(rtcb->waitdog);
|
||||||
rtcb->waitdog = NULL;
|
rtcb->waitdog = NULL;
|
||||||
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/wdog.h>
|
#include <nuttx/wdog.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "clock/clock.h"
|
#include "clock/clock.h"
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
@@ -178,6 +179,10 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
|
|
||||||
DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL);
|
DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL);
|
||||||
|
|
||||||
|
/* mq_timedsend() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Verify the input parameters -- setting errno appropriately
|
/* Verify the input parameters -- setting errno appropriately
|
||||||
* on any failures to verify.
|
* on any failures to verify.
|
||||||
*/
|
*/
|
||||||
@@ -186,6 +191,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
{
|
{
|
||||||
/* mq_verifysend() will set the errno appropriately */
|
/* mq_verifysend() will set the errno appropriately */
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,6 +205,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
set_errno(ENOMEM);
|
set_errno(ENOMEM);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,6 +236,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
|
|
||||||
ret = mq_dosend(mqdes, mqmsg, msg, msglen, prio);
|
ret = mq_dosend(mqdes, mqmsg, msg, msglen, prio);
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,6 +328,7 @@ int mq_timedsend(mqd_t mqdes, FAR const char *msg, size_t msglen, int prio,
|
|||||||
sched_unlock();
|
sched_unlock();
|
||||||
wd_delete(rtcb->waitdog);
|
wd_delete(rtcb->waitdog);
|
||||||
rtcb->waitdog = NULL;
|
rtcb->waitdog = NULL;
|
||||||
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Exit here with (1) the scheduler locked, (2) a message allocated, (3) a
|
/* Exit here with (1) the scheduler locked, (2) a message allocated, (3) a
|
||||||
@@ -341,5 +350,6 @@ errout_with_mqmsg:
|
|||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
|
||||||
set_errno(result);
|
set_errno(result);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,8 +42,10 @@ CSRCS += pthread_mutexlock.c pthread_mutextrylock.c pthread_mutexunlock.c
|
|||||||
CSRCS += pthread_condinit.c pthread_conddestroy.c
|
CSRCS += pthread_condinit.c pthread_conddestroy.c
|
||||||
CSRCS += pthread_condwait.c pthread_condsignal.c pthread_condbroadcast.c
|
CSRCS += pthread_condwait.c pthread_condsignal.c pthread_condbroadcast.c
|
||||||
CSRCS += pthread_barrierinit.c pthread_barrierdestroy.c pthread_barrierwait.c
|
CSRCS += pthread_barrierinit.c pthread_barrierdestroy.c pthread_barrierwait.c
|
||||||
CSRCS += pthread_cancel.c pthread_setcancelstate.c
|
CSRCS += pthread_cancel.c pthread_setcancelstate.c pthread_setcanceltype.c
|
||||||
CSRCS += pthread_keycreate.c pthread_setspecific.c pthread_getspecific.c pthread_keydelete.c
|
CSRCS += pthread_testcancel.c
|
||||||
|
CSRCS += pthread_keycreate.c pthread_setspecific.c pthread_getspecific.c
|
||||||
|
CSRCS += pthread_keydelete.c
|
||||||
CSRCS += pthread_initialize.c pthread_completejoin.c pthread_findjoininfo.c
|
CSRCS += pthread_initialize.c pthread_completejoin.c pthread_findjoininfo.c
|
||||||
CSRCS += pthread_once.c pthread_release.c pthread_setschedprio.c
|
CSRCS += pthread_once.c pthread_release.c pthread_setschedprio.c
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
|
#include "task/task.h"
|
||||||
#include "pthread/pthread.h"
|
#include "pthread/pthread.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -104,6 +105,35 @@ int pthread_cancel(pthread_t thread)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CANCELLATION_POINTS
|
||||||
|
/* Check if this thread supports deferred cancellation */
|
||||||
|
|
||||||
|
if ((tcb->cmn.flags & TCB_FLAG_CANCEL_DEFERRED) != 0)
|
||||||
|
{
|
||||||
|
/* Then we cannot cancel the thread asynchronoulsy. Mark the cancellation
|
||||||
|
* as pending.
|
||||||
|
*/
|
||||||
|
|
||||||
|
tcb->cmn.flags |= TCB_FLAG_CANCEL_PENDING;
|
||||||
|
|
||||||
|
/* If the thread is waiting at a cancellation point, then notify of the
|
||||||
|
* cancellation thereby waking the task up with an ECANCELED error.
|
||||||
|
*
|
||||||
|
* REVISIT: is locking the scheduler sufficent in SMP mode?
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (tcb->cmn.cpcount > 0)
|
||||||
|
{
|
||||||
|
notify_cancellation(&tcb->cmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
sched_unlock();
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Otherwise, perform the asyncrhonous cancellation */
|
||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
|
||||||
/* Check to see if the ID refers to ourselves.. this would be the
|
/* Check to see if the ID refers to ourselves.. this would be the
|
||||||
|
|||||||
@@ -67,6 +67,9 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The scheduler is locked.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void pthread_cleanup_pop_tcb(FAR struct pthread_tcb_s *tcb, int execute)
|
static void pthread_cleanup_pop_tcb(FAR struct pthread_tcb_s *tcb, int execute)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/wdog.h>
|
#include <nuttx/wdog.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "pthread/pthread.h"
|
#include "pthread/pthread.h"
|
||||||
@@ -178,6 +179,10 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex,
|
|||||||
|
|
||||||
DEBUGASSERT(rtcb->waitdog == NULL);
|
DEBUGASSERT(rtcb->waitdog == NULL);
|
||||||
|
|
||||||
|
/* pthread_cond_timedwait() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Make sure that non-NULL references were provided. */
|
/* Make sure that non-NULL references were provided. */
|
||||||
|
|
||||||
if (!cond || !mutex)
|
if (!cond || !mutex)
|
||||||
@@ -338,6 +343,7 @@ int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
sinfo("Returning %d\n", ret);
|
sinfo("Returning %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/pthread/pthread_condwait.c
|
* sched/pthread/pthread_condwait.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2012, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -45,6 +45,8 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "pthread/pthread.h"
|
#include "pthread/pthread.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -73,6 +75,10 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex)
|
|||||||
|
|
||||||
sinfo("cond=0x%p mutex=0x%p\n", cond, mutex);
|
sinfo("cond=0x%p mutex=0x%p\n", cond, mutex);
|
||||||
|
|
||||||
|
/* pthread_cond_wait() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Make sure that non-NULL references were provided. */
|
/* Make sure that non-NULL references were provided. */
|
||||||
|
|
||||||
if (!cond || !mutex)
|
if (!cond || !mutex)
|
||||||
@@ -111,6 +117,7 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
sinfo("Returning %d\n", ret);
|
sinfo("Returning %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -483,6 +483,12 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CANCELLATION_POINTS
|
||||||
|
/* Set the deferred cancellation type */
|
||||||
|
|
||||||
|
ptcb->cmn.flags |= TCB_FLAG_CANCEL_DEFERRED;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get the assigned pid before we start the task (who knows what
|
/* Get the assigned pid before we start the task (who knows what
|
||||||
* could happen to ptcb after this!). Copy this ID into the join structure
|
* could happen to ptcb after this!). Copy this ID into the join structure
|
||||||
* as well.
|
* as well.
|
||||||
|
|||||||
@@ -94,6 +94,17 @@ void pthread_exit(FAR void *exit_value)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_CANCELLATION_POINTS
|
||||||
|
/* Mark the pthread as non-cancelable to avoid additional calls to
|
||||||
|
* pthread_exit() due to any cancellation point logic that might get
|
||||||
|
* kicked off by actions taken during pthread_exit processing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
tcb->flags |= TCB_FLAG_NONCANCELABLE;
|
||||||
|
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
||||||
|
tcb->cpcount = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PTHREAD_CLEANUP
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
/* Perform any stack pthread clean-up callbacks */
|
/* Perform any stack pthread clean-up callbacks */
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/pthread/pthread_join.c
|
* sched/pthread/pthread_join.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2008, 2011, 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2008, 2011, 2013, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -37,12 +37,16 @@
|
|||||||
* Included Files
|
* Included Files
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "group/group.h"
|
#include "group/group.h"
|
||||||
#include "pthread/pthread.h"
|
#include "pthread/pthread.h"
|
||||||
@@ -90,12 +94,17 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
|
|||||||
sinfo("thread=%d group=%p\n", thread, group);
|
sinfo("thread=%d group=%p\n", thread, group);
|
||||||
DEBUGASSERT(group);
|
DEBUGASSERT(group);
|
||||||
|
|
||||||
|
/* pthread_join() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* First make sure that this is not an attempt to join to
|
/* First make sure that this is not an attempt to join to
|
||||||
* ourself.
|
* ourself.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((pid_t)thread == getpid())
|
if ((pid_t)thread == getpid())
|
||||||
{
|
{
|
||||||
|
leave_cancellation_point();
|
||||||
return EDEADLK;
|
return EDEADLK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +239,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
|
|||||||
ret = OK;
|
ret = OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
sinfo("Returning %d\n", ret);
|
sinfo("Returning %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,8 +37,12 @@
|
|||||||
* Included Files
|
* Included Files
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "task/task.h"
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -47,6 +51,18 @@
|
|||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: pthread_setcancelstate
|
* Name: pthread_setcancelstate
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The pthread_setcancelstate() function atomically both sets the calling
|
||||||
|
* thread's cancelability state to the indicated state and returns the
|
||||||
|
* previous cancelability state at the location referenced by oldstate.
|
||||||
|
* Legal values for state are PTHREAD_CANCEL_ENABLE and
|
||||||
|
* PTHREAD_CANCEL_DISABLE.
|
||||||
|
*
|
||||||
|
* The cancelability state and type of any newly created threads,
|
||||||
|
* including the thread in which main() was first invoked, are
|
||||||
|
* PTHREAD_CANCEL_ENABLE and PTHREAD_CANCEL_DEFERRED respectively.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int pthread_setcancelstate(int state, FAR int *oldstate)
|
int pthread_setcancelstate(int state, FAR int *oldstate)
|
||||||
@@ -78,17 +94,38 @@ int pthread_setcancelstate(int state, FAR int *oldstate)
|
|||||||
|
|
||||||
if (state == PTHREAD_CANCEL_ENABLE)
|
if (state == PTHREAD_CANCEL_ENABLE)
|
||||||
{
|
{
|
||||||
unsigned flags = tcb->flags;
|
/* Clear the non-cancelable flag */
|
||||||
|
|
||||||
/* Clear the non-cancelable and cancel pending flags */
|
tcb->flags &= ~TCB_FLAG_NONCANCELABLE;
|
||||||
|
|
||||||
tcb->flags &= ~(TCB_FLAG_NONCANCELABLE | TCB_FLAG_CANCEL_PENDING);
|
/* Check if a cancellation was pending */
|
||||||
|
|
||||||
/* If the cancel was pending, then just exit as requested */
|
if ((tcb->flags & TCB_FLAG_CANCEL_PENDING) != 0)
|
||||||
|
|
||||||
if (flags & TCB_FLAG_CANCEL_PENDING)
|
|
||||||
{
|
{
|
||||||
pthread_exit(PTHREAD_CANCELED);
|
#ifdef CONFIG_CANCELLATION_POINTS
|
||||||
|
/* If we are using deferred cancellation? */
|
||||||
|
|
||||||
|
if ((tcb->flags & TCB_FLAG_CANCEL_DEFERRED) != 0)
|
||||||
|
{
|
||||||
|
/* Yes.. If we are within a cancellation point, then
|
||||||
|
* notify of the cancellation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (tcb->cpcount > 0)
|
||||||
|
{
|
||||||
|
notify_cancellation(tcb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* No.. We are using asynchronous cancellation. If the
|
||||||
|
* cancellation was pending in this case, then just exit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
||||||
|
pthread_exit(PTHREAD_CANCELED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (state == PTHREAD_CANCEL_DISABLE)
|
else if (state == PTHREAD_CANCEL_DISABLE)
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* sched/pthread/pthread_setcanceltype.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 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 <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "sched/sched.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pthread_setcancelstate
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The pthread_setcanceltype() function atomically both sets the calling
|
||||||
|
* thread's cancelability type to the indicated type and returns the
|
||||||
|
* previous cancelability type at the location referenced by oldtype
|
||||||
|
* Legal values for type are PTHREAD_CANCEL_DEFERRED and
|
||||||
|
* PTHREAD_CANCEL_ASYNCHRONOUS.
|
||||||
|
*
|
||||||
|
* The cancelability state and type of any newly created threads,
|
||||||
|
* including the thread in which main() was first invoked, are
|
||||||
|
* PTHREAD_CANCEL_ENABLE and PTHREAD_CANCEL_DEFERRED respectively.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pthread_setcanceltype(int type, FAR int *oldtype)
|
||||||
|
{
|
||||||
|
FAR struct tcb_s *tcb = this_task();
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
/* Suppress context changes for a bit so that the flags are stable. (the
|
||||||
|
* flags should not change in interrupt handling).
|
||||||
|
*/
|
||||||
|
|
||||||
|
sched_lock();
|
||||||
|
|
||||||
|
/* Return the current type if so requrested */
|
||||||
|
|
||||||
|
if (oldtype)
|
||||||
|
{
|
||||||
|
if ((tcb->flags & TCB_FLAG_CANCEL_DEFERRED) != 0)
|
||||||
|
{
|
||||||
|
*oldtype = PTHREAD_CANCEL_DEFERRED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*oldtype = PTHREAD_CANCEL_ASYNCHRONOUS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the new cancellation type */
|
||||||
|
|
||||||
|
if (type == PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||||
|
{
|
||||||
|
/* Clear the deferred cancellation bit */
|
||||||
|
|
||||||
|
tcb->flags &= ~TCB_FLAG_CANCEL_DEFERRED;
|
||||||
|
|
||||||
|
#ifdef CONFIG_CANCELLATION_POINTS
|
||||||
|
/* If we just switched from deferred to asynchronous type and if a
|
||||||
|
* cancellation is pending, then exit now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((tcb->flags & TCB_FLAG_CANCEL_PENDING) != 0 &&
|
||||||
|
(tcb->flags & TCB_FLAG_NONCANCELABLE) == 0)
|
||||||
|
{
|
||||||
|
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
|
||||||
|
pthread_exit(PTHREAD_CANCELED);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_CANCELLATION_POINTS
|
||||||
|
else if (type == PTHREAD_CANCEL_DEFERRED)
|
||||||
|
{
|
||||||
|
/* Set the deferred cancellation type */
|
||||||
|
|
||||||
|
tcb->flags |= TCB_FLAG_CANCEL_DEFERRED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sched_unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* sched/pthread/pthread_testcancel.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 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 <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
|
#include "sched/sched.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pthread_testcancel
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The pthread_testcancel() function creates a cancellation point in the
|
||||||
|
* calling thread. The pthread_testcancel() function has no effect if
|
||||||
|
* cancelability is disabled
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void pthread_testcancel(void)
|
||||||
|
{
|
||||||
|
enter_cancellation_point();
|
||||||
|
leave_cancellation_point();
|
||||||
|
}
|
||||||
@@ -44,6 +44,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
|
|
||||||
@@ -80,8 +81,11 @@
|
|||||||
|
|
||||||
pid_t wait(FAR int *stat_loc)
|
pid_t wait(FAR int *stat_loc)
|
||||||
{
|
{
|
||||||
|
/* wait() is a cancellation point, but nothings needs to be done for this
|
||||||
|
* trivial case.
|
||||||
|
*/
|
||||||
|
|
||||||
return waitpid((pid_t)-1, stat_loc, 0);
|
return waitpid((pid_t)-1, stat_loc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_SCHED_WAITPID && CONFIG_SCHED_HAVE_PARENT */
|
#endif /* CONFIG_SCHED_WAITPID && CONFIG_SCHED_HAVE_PARENT */
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "group/group.h"
|
#include "group/group.h"
|
||||||
@@ -164,6 +165,10 @@ int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options)
|
|||||||
int errcode;
|
int errcode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* waitid() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* MISSING LOGIC: If WNOHANG is provided in the options, then this function
|
/* MISSING LOGIC: If WNOHANG is provided in the options, then this function
|
||||||
* should returned immediately. However, there is no mechanism available now
|
* should returned immediately. However, there is no mechanism available now
|
||||||
* know if the thread has child: The children remember their parents (if
|
* know if the thread has child: The children remember their parents (if
|
||||||
@@ -404,12 +409,14 @@ int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
errout_with_errno:
|
errout_with_errno:
|
||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
errout:
|
errout:
|
||||||
|
leave_cancellation_point();
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "group/group.h"
|
#include "group/group.h"
|
||||||
@@ -185,12 +186,17 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
|||||||
|
|
||||||
DEBUGASSERT(stat_loc);
|
DEBUGASSERT(stat_loc);
|
||||||
|
|
||||||
|
/* waitpid() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* None of the options are supported */
|
/* None of the options are supported */
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FEATURES
|
#ifdef CONFIG_DEBUG_FEATURES
|
||||||
if (options != 0)
|
if (options != 0)
|
||||||
{
|
{
|
||||||
set_errno(ENOSYS);
|
set_errno(ENOSYS);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -268,12 +274,14 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
|||||||
|
|
||||||
/* On success, return the PID */
|
/* On success, return the PID */
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return pid;
|
return pid;
|
||||||
|
|
||||||
errout_with_errno:
|
errout_with_errno:
|
||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
errout:
|
errout:
|
||||||
|
leave_cancellation_point();
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
@@ -307,12 +315,17 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
|||||||
|
|
||||||
DEBUGASSERT(stat_loc);
|
DEBUGASSERT(stat_loc);
|
||||||
|
|
||||||
|
/* waitpid() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* None of the options are supported */
|
/* None of the options are supported */
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FEATURES
|
#ifdef CONFIG_DEBUG_FEATURES
|
||||||
if (options != 0)
|
if (options != 0)
|
||||||
{
|
{
|
||||||
set_errno(ENOSYS);
|
set_errno(ENOSYS);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -528,6 +541,7 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return (int)pid;
|
return (int)pid;
|
||||||
|
|
||||||
@@ -535,6 +549,7 @@ errout_with_errno:
|
|||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
|
|
||||||
errout_with_lock:
|
errout_with_lock:
|
||||||
|
leave_cancellation_point();
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/wdog.h>
|
#include <nuttx/wdog.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "clock/clock.h"
|
#include "clock/clock.h"
|
||||||
@@ -103,6 +104,10 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
|
|||||||
|
|
||||||
DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL);
|
DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL);
|
||||||
|
|
||||||
|
/* sem_timedwait() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Verify the input parameters and, in case of an error, set
|
/* Verify the input parameters and, in case of an error, set
|
||||||
* errno appropriately.
|
* errno appropriately.
|
||||||
*/
|
*/
|
||||||
@@ -209,6 +214,7 @@ success_with_irqdisabled:
|
|||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
wd_delete(rtcb->waitdog);
|
wd_delete(rtcb->waitdog);
|
||||||
rtcb->waitdog = NULL;
|
rtcb->waitdog = NULL;
|
||||||
|
leave_cancellation_point();
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
/* Error exits */
|
/* Error exits */
|
||||||
@@ -220,5 +226,6 @@ errout_with_irqdisabled:
|
|||||||
|
|
||||||
errout:
|
errout:
|
||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "semaphore/semaphore.h"
|
#include "semaphore/semaphore.h"
|
||||||
@@ -86,6 +87,10 @@ int sem_wait(FAR sem_t *sem)
|
|||||||
|
|
||||||
DEBUGASSERT(sem != NULL && up_interrupt_context() == false);
|
DEBUGASSERT(sem != NULL && up_interrupt_context() == false);
|
||||||
|
|
||||||
|
/* sem_wait is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Make sure we were supplied with a valid semaphore. */
|
/* Make sure we were supplied with a valid semaphore. */
|
||||||
|
|
||||||
if (sem != NULL)
|
if (sem != NULL)
|
||||||
@@ -196,5 +201,6 @@ int sem_wait(FAR sem_t *sem)
|
|||||||
set_errno(EINVAL);
|
set_errno(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave_cancellation_point();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "clock/clock.h"
|
#include "clock/clock.h"
|
||||||
|
|
||||||
@@ -112,6 +113,10 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp)
|
|||||||
int ret;
|
int ret;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* nanosleep() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
if (!rqtp || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= 1000000000)
|
if (!rqtp || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= 1000000000)
|
||||||
{
|
{
|
||||||
errval = EINVAL;
|
errval = EINVAL;
|
||||||
@@ -154,6 +159,7 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp)
|
|||||||
/* The timeout "error" is the normal, successful result */
|
/* The timeout "error" is the normal, successful result */
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
leave_cancellation_point();
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,5 +209,6 @@ int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp)
|
|||||||
|
|
||||||
errout:
|
errout:
|
||||||
set_errno(errval);
|
set_errno(errval);
|
||||||
|
leave_cancellation_point();
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/signal/sig_pause.c
|
* sched/signal/sig_pause.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -42,6 +42,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -72,8 +74,13 @@
|
|||||||
|
|
||||||
int pause(void)
|
int pause(void)
|
||||||
{
|
{
|
||||||
sigset_t set;
|
|
||||||
struct siginfo value;
|
struct siginfo value;
|
||||||
|
sigset_t set;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* pause() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Set up for the sleep. Using the empty set means that we are not
|
/* Set up for the sleep. Using the empty set means that we are not
|
||||||
* waiting for any particular signal. However, any unmasked signal
|
* waiting for any particular signal. However, any unmasked signal
|
||||||
@@ -86,5 +93,7 @@ int pause(void)
|
|||||||
* meaning that some unblocked signal was caught.
|
* meaning that some unblocked signal was caught.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return sigwaitinfo(&set, &value);
|
ret = sigwaitinfo(&set, &value);
|
||||||
|
leave_cancellation_point();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "signal/signal.h"
|
#include "signal/signal.h"
|
||||||
@@ -98,6 +99,10 @@ int sigsuspend(FAR const sigset_t *set)
|
|||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
int unblocksigno;
|
int unblocksigno;
|
||||||
|
|
||||||
|
/* sigsuspend() is a cancellation point */
|
||||||
|
|
||||||
|
enter_cancellation_point();
|
||||||
|
|
||||||
/* Several operations must be performed below: We must determine if any
|
/* Several operations must be performed below: We must determine if any
|
||||||
* signal is pending and, if not, wait for the signal. Since signals can
|
* signal is pending and, if not, wait for the signal. Since signals can
|
||||||
* be posted from the interrupt level, there is a race condition that
|
* be posted from the interrupt level, there is a race condition that
|
||||||
@@ -154,5 +159,6 @@ int sigsuspend(FAR const sigset_t *set)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return ERROR;
|
leave_cancellation_point();
|
||||||
|
return ERROR; /* ??REVISIT: Always returns ERROR?? */
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user