aboutsummaryrefslogtreecommitdiff
path: root/nuttx/sched
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-17 18:18:44 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-17 18:18:44 +0000
commit57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff (patch)
tree25d07d14e920d31c0b1947c9ca586f2a01fc32d8 /nuttx/sched
downloadpx4-firmware-57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff.tar.gz
px4-firmware-57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff.tar.bz2
px4-firmware-57623d42ebb04f0a0b9e6eb7c0847a3ece2aa0ff.zip
Resync new repository with old repo r5166
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5153 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/sched')
-rw-r--r--nuttx/sched/Kconfig419
-rw-r--r--nuttx/sched/Makefile216
-rw-r--r--nuttx/sched/atexit.c162
-rw-r--r--nuttx/sched/clock_abstime2ticks.c126
-rw-r--r--nuttx/sched/clock_dow.c88
-rw-r--r--nuttx/sched/clock_getres.c121
-rw-r--r--nuttx/sched/clock_gettime.c180
-rw-r--r--nuttx/sched/clock_gettimeofday.c113
-rw-r--r--nuttx/sched/clock_initialize.c270
-rw-r--r--nuttx/sched/clock_internal.h91
-rw-r--r--nuttx/sched/clock_settime.c149
-rw-r--r--nuttx/sched/clock_systimer.c110
-rw-r--r--nuttx/sched/clock_ticks2time.c94
-rw-r--r--nuttx/sched/clock_time2ticks.c102
-rw-r--r--nuttx/sched/env_clearenv.c83
-rw-r--r--nuttx/sched/env_dup.c132
-rw-r--r--nuttx/sched/env_dupenv.c112
-rw-r--r--nuttx/sched/env_findvar.c131
-rw-r--r--nuttx/sched/env_getenv.c135
-rw-r--r--nuttx/sched/env_getenvironptr.c104
-rw-r--r--nuttx/sched/env_internal.h95
-rw-r--r--nuttx/sched/env_putenv.c123
-rw-r--r--nuttx/sched/env_release.c125
-rw-r--r--nuttx/sched/env_removevar.c119
-rw-r--r--nuttx/sched/env_setenv.c208
-rw-r--r--nuttx/sched/env_share.c117
-rw-r--r--nuttx/sched/env_unsetenv.c138
-rw-r--r--nuttx/sched/errno_get.c84
-rw-r--r--nuttx/sched/errno_getptr.c117
-rw-r--r--nuttx/sched/errno_set.c83
-rw-r--r--nuttx/sched/exit.c108
-rw-r--r--nuttx/sched/getpid.c85
-rw-r--r--nuttx/sched/irq_attach.c127
-rw-r--r--nuttx/sched/irq_dispatch.c105
-rw-r--r--nuttx/sched/irq_initialize.c91
-rw-r--r--nuttx/sched/irq_internal.h83
-rw-r--r--nuttx/sched/irq_unexpectedisr.c88
-rw-r--r--nuttx/sched/kmm_addregion.c113
-rw-r--r--nuttx/sched/kmm_initialize.c113
-rw-r--r--nuttx/sched/kmm_kfree.c110
-rw-r--r--nuttx/sched/kmm_kmalloc.c110
-rw-r--r--nuttx/sched/kmm_krealloc.c111
-rw-r--r--nuttx/sched/kmm_kzalloc.c110
-rw-r--r--nuttx/sched/kmm_semaphore.c140
-rw-r--r--nuttx/sched/mq_close.c187
-rw-r--r--nuttx/sched/mq_descreate.c159
-rw-r--r--nuttx/sched/mq_findnamed.c105
-rw-r--r--nuttx/sched/mq_initialize.c243
-rw-r--r--nuttx/sched/mq_internal.h183
-rw-r--r--nuttx/sched/mq_msgfree.c134
-rw-r--r--nuttx/sched/mq_msgqfree.c108
-rw-r--r--nuttx/sched/mq_notify.c211
-rw-r--r--nuttx/sched/mq_open.c236
-rw-r--r--nuttx/sched/mq_rcvinternal.c312
-rw-r--r--nuttx/sched/mq_receive.c166
-rw-r--r--nuttx/sched/mq_send.c184
-rw-r--r--nuttx/sched/mq_sndinternal.c455
-rw-r--r--nuttx/sched/mq_timedreceive.c303
-rw-r--r--nuttx/sched/mq_timedsend.c319
-rw-r--r--nuttx/sched/mq_unlink.c146
-rw-r--r--nuttx/sched/mq_waitirq.c172
-rw-r--r--nuttx/sched/on_exit.c171
-rw-r--r--nuttx/sched/os_bringup.c194
-rw-r--r--nuttx/sched/os_internal.h306
-rw-r--r--nuttx/sched/os_start.c466
-rw-r--r--nuttx/sched/pg_internal.h126
-rw-r--r--nuttx/sched/pg_miss.c179
-rw-r--r--nuttx/sched/pg_worker.c678
-rw-r--r--nuttx/sched/prctl.c167
-rw-r--r--nuttx/sched/pthread_barrierdestroy.c110
-rw-r--r--nuttx/sched/pthread_barrierinit.c122
-rw-r--r--nuttx/sched/pthread_barrierwait.c182
-rw-r--r--nuttx/sched/pthread_cancel.c148
-rw-r--r--nuttx/sched/pthread_completejoin.c231
-rw-r--r--nuttx/sched/pthread_condbroadcast.c145
-rw-r--r--nuttx/sched/pthread_conddestroy.c88
-rw-r--r--nuttx/sched/pthread_condinit.c93
-rw-r--r--nuttx/sched/pthread_condsignal.c137
-rw-r--r--nuttx/sched/pthread_condtimedwait.c308
-rw-r--r--nuttx/sched/pthread_condwait.c137
-rw-r--r--nuttx/sched/pthread_create.c435
-rw-r--r--nuttx/sched/pthread_detach.c137
-rw-r--r--nuttx/sched/pthread_exit.c137
-rw-r--r--nuttx/sched/pthread_findjoininfo.c101
-rw-r--r--nuttx/sched/pthread_getschedparam.c139
-rw-r--r--nuttx/sched/pthread_getspecific.c123
-rw-r--r--nuttx/sched/pthread_initialize.c198
-rw-r--r--nuttx/sched/pthread_internal.h133
-rw-r--r--nuttx/sched/pthread_join.c248
-rw-r--r--nuttx/sched/pthread_keycreate.c135
-rw-r--r--nuttx/sched/pthread_keydelete.c96
-rw-r--r--nuttx/sched/pthread_kill.c95
-rw-r--r--nuttx/sched/pthread_mutexdestroy.c131
-rw-r--r--nuttx/sched/pthread_mutexinit.c138
-rw-r--r--nuttx/sched/pthread_mutexlock.c187
-rw-r--r--nuttx/sched/pthread_mutextrylock.c147
-rw-r--r--nuttx/sched/pthread_mutexunlock.c164
-rw-r--r--nuttx/sched/pthread_once.c128
-rw-r--r--nuttx/sched/pthread_removejoininfo.c137
-rw-r--r--nuttx/sched/pthread_setcancelstate.c131
-rw-r--r--nuttx/sched/pthread_setschedparam.c142
-rw-r--r--nuttx/sched/pthread_setschedprio.c120
-rw-r--r--nuttx/sched/pthread_setspecific.c137
-rw-r--r--nuttx/sched/pthread_sigmask.c107
-rw-r--r--nuttx/sched/pthread_yield.c87
-rw-r--r--nuttx/sched/sched_addblocked.c122
-rw-r--r--nuttx/sched/sched_addprioritized.c175
-rw-r--r--nuttx/sched/sched_addreadytorun.c149
-rw-r--r--nuttx/sched/sched_foreach.c84
-rw-r--r--nuttx/sched/sched_free.c114
-rw-r--r--nuttx/sched/sched_garbage.c117
-rw-r--r--nuttx/sched/sched_getfiles.c76
-rw-r--r--nuttx/sched/sched_getparam.c146
-rw-r--r--nuttx/sched/sched_getscheduler.c131
-rw-r--r--nuttx/sched/sched_getsockets.c77
-rw-r--r--nuttx/sched/sched_getstreams.c76
-rw-r--r--nuttx/sched/sched_gettcb.c107
-rw-r--r--nuttx/sched/sched_lock.c110
-rw-r--r--nuttx/sched/sched_lockcount.c97
-rw-r--r--nuttx/sched/sched_mergepending.c177
-rw-r--r--nuttx/sched/sched_processtimer.c190
-rw-r--r--nuttx/sched/sched_releasefiles.c114
-rw-r--r--nuttx/sched/sched_releasetcb.c181
-rw-r--r--nuttx/sched/sched_removeblocked.c111
-rw-r--r--nuttx/sched/sched_removereadytorun.c121
-rw-r--r--nuttx/sched/sched_reprioritize.c129
-rw-r--r--nuttx/sched/sched_rrgetinterval.c157
-rw-r--r--nuttx/sched/sched_self.c83
-rw-r--r--nuttx/sched/sched_setparam.c156
-rw-r--r--nuttx/sched/sched_setpriority.c233
-rw-r--r--nuttx/sched/sched_setscheduler.c187
-rw-r--r--nuttx/sched/sched_setupidlefiles.c148
-rw-r--r--nuttx/sched/sched_setuppthreadfiles.c108
-rw-r--r--nuttx/sched/sched_setupstreams.c98
-rw-r--r--nuttx/sched/sched_setuptaskfiles.c248
-rw-r--r--nuttx/sched/sched_unlock.c130
-rw-r--r--nuttx/sched/sched_verifytcb.c86
-rw-r--r--nuttx/sched/sched_waitpid.c248
-rw-r--r--nuttx/sched/sched_yield.c101
-rw-r--r--nuttx/sched/sem_close.c140
-rw-r--r--nuttx/sched/sem_destroy.c126
-rw-r--r--nuttx/sched/sem_findnamed.c100
-rw-r--r--nuttx/sched/sem_holder.c1055
-rw-r--r--nuttx/sched/sem_initialize.c100
-rw-r--r--nuttx/sched/sem_internal.h131
-rw-r--r--nuttx/sched/sem_open.c209
-rw-r--r--nuttx/sched/sem_post.c182
-rw-r--r--nuttx/sched/sem_timedwait.c286
-rw-r--r--nuttx/sched/sem_trywait.c142
-rw-r--r--nuttx/sched/sem_unlink.c140
-rw-r--r--nuttx/sched/sem_wait.c216
-rw-r--r--nuttx/sched/sem_waitirq.c145
-rw-r--r--nuttx/sched/sig_action.c272
-rw-r--r--nuttx/sched/sig_allocatependingsigaction.c137
-rw-r--r--nuttx/sched/sig_cleanup.c118
-rw-r--r--nuttx/sched/sig_deliver.c159
-rw-r--r--nuttx/sched/sig_findaction.c100
-rw-r--r--nuttx/sched/sig_initialize.c271
-rw-r--r--nuttx/sched/sig_internal.h190
-rw-r--r--nuttx/sched/sig_kill.c135
-rw-r--r--nuttx/sched/sig_lowest.c91
-rw-r--r--nuttx/sched/sig_mqnotempty.c128
-rw-r--r--nuttx/sched/sig_pending.c130
-rw-r--r--nuttx/sched/sig_procmask.c180
-rw-r--r--nuttx/sched/sig_queue.c159
-rw-r--r--nuttx/sched/sig_received.c404
-rw-r--r--nuttx/sched/sig_releasependingsigaction.c120
-rw-r--r--nuttx/sched/sig_releasependingsignal.c131
-rw-r--r--nuttx/sched/sig_removependingsignal.c115
-rw-r--r--nuttx/sched/sig_suspend.c180
-rw-r--r--nuttx/sched/sig_timedwait.c334
-rw-r--r--nuttx/sched/sig_unmaskpendingsignal.c138
-rw-r--r--nuttx/sched/sig_waitinfo.c89
-rw-r--r--nuttx/sched/sleep.c196
-rw-r--r--nuttx/sched/task_activate.c117
-rw-r--r--nuttx/sched/task_create.c269
-rw-r--r--nuttx/sched/task_delete.c194
-rw-r--r--nuttx/sched/task_deletecurrent.c140
-rw-r--r--nuttx/sched/task_exithook.c290
-rw-r--r--nuttx/sched/task_init.c154
-rw-r--r--nuttx/sched/task_restart.c184
-rw-r--r--nuttx/sched/task_setup.c347
-rw-r--r--nuttx/sched/task_start.c114
-rw-r--r--nuttx/sched/timer_create.c237
-rw-r--r--nuttx/sched/timer_delete.c106
-rw-r--r--nuttx/sched/timer_getoverrun.c111
-rw-r--r--nuttx/sched/timer_gettime.c123
-rw-r--r--nuttx/sched/timer_initialize.c168
-rw-r--r--nuttx/sched/timer_internal.h102
-rw-r--r--nuttx/sched/timer_release.c159
-rw-r--r--nuttx/sched/timer_settime.c397
-rw-r--r--nuttx/sched/usleep.c168
-rw-r--r--nuttx/sched/wd_cancel.c165
-rw-r--r--nuttx/sched/wd_create.c109
-rw-r--r--nuttx/sched/wd_delete.c127
-rw-r--r--nuttx/sched/wd_gettime.c118
-rw-r--r--nuttx/sched/wd_initialize.c135
-rw-r--r--nuttx/sched/wd_internal.h119
-rw-r--r--nuttx/sched/wd_start.c375
-rw-r--r--nuttx/sched/work_cancel.c127
-rw-r--r--nuttx/sched/work_internal.h114
-rw-r--r--nuttx/sched/work_queue.c138
-rw-r--r--nuttx/sched/work_signal.c96
-rw-r--r--nuttx/sched/work_thread.c256
204 files changed, 33580 insertions, 0 deletions
diff --git a/nuttx/sched/Kconfig b/nuttx/sched/Kconfig
new file mode 100644
index 000000000..4f7149595
--- /dev/null
+++ b/nuttx/sched/Kconfig
@@ -0,0 +1,419 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+config MSEC_PER_TICK
+ int "tick timer"
+ default 10
+ ---help---
+ The default system timer is 100Hz or MSEC_PER_TICK=10. This setting
+ may be defined to inform NuttX that the processor hardware is providing
+ system timer interrupts at some interrupt interval other than 10 msec.
+
+config RR_INTERVAL
+ int "round robin timeslice"
+ default 0
+ ---help---
+ The round robin timeslice will be set this number of milliseconds;
+ Round robin scheduling can be disabled by setting this value to zero.
+
+config SCHED_INSTRUMENTATION
+ bool "Monitor system performance"
+ default n
+ ---help---
+ enables instrumentation in scheduler to monitor system performance.
+
+config TASK_NAME_SIZE
+ int "Maximum task name size"
+ default 32
+ ---help---
+ Spcifies that maximum size of a task name to save in the TCB.
+ Useful if scheduler instrumentation is selected. Set to zero to
+ disable.
+
+config JULIAN_TIME
+ bool "Enables Julian time conversions"
+ default n
+ ---help---
+ Enables Julian time conversions
+
+config START_YEAR
+ int "start year"
+ default 2010
+
+config START_MONTH
+ int "start month"
+ default 1
+
+config START_DAY
+ int "start day"
+ default 1
+
+config DEV_CONSOLE
+ bool "Enable /dev/console"
+ default y
+ ---help---
+ Set if architecture-specific logic provides /dev/console. Enables
+ stdout, stderr, stdin.
+
+config DEV_LOWCONSOLE
+ bool "enable low-level serial console"
+ default n
+ ---help---
+ Use the simple, low-level, write-only serial console driver (minimul support)
+
+config MUTEX_TYPES:
+ bool "Enable mutex types"
+ default n
+ ---help---
+ Set to enable support for recursive and errorcheck mutexes. Enables
+ pthread_mutexattr_settype().
+
+config PRIORITY_INHERITANCE
+ bool "Enable priority inheritance "
+ default n
+ ---help---
+ Set to enable support for priority inheritance on mutexes and semaphores.
+
+config SEM_PREALLOCHOLDERS
+ int "Pre-allocated holders"
+ default 16
+ depends on PRIORITY_INHERITANCE
+ ---help---
+ This setting is only used if priority inheritance is enabled.
+ It defines the maximum number of different threads (minus one) that
+ can take counts on a semaphore with priority inheritance support.
+ This may be set to zero if priority inheritance is disabled OR if you
+ are only using semaphores as mutexes (only one holder) OR if no more
+ than two threads participate using a counting semaphore.
+
+config SEM_NNESTPRIO
+ int "Maximum number of higher priority threads"
+ default 16
+ depends on PRIORITY_INHERITANCE
+ ---help---
+ If priority inheritance is enabled, then this setting is the
+ maximum number of higher priority threads (minus 1) than can be
+ waiting for another thread to release a count on a semaphore.
+ This value may be set to zero if no more than one thread is
+ expected to wait for a semaphore.
+
+config FDCLONE_DISABLE
+ bool "Disable cloning of file descriptors"
+ default n
+ ---help---
+ Disable cloning of all file descriptors
+ by task_create() when a new task is started. If set, all
+ files/drivers will appear to be closed in the new task.
+
+config FDCLONE_STDIO
+ bool "Disable clone file descriptors without stdio"
+ default n
+ ---help---
+ Disable cloning of all but the first three file descriptors (stdin,
+ stdout, stderr) by task_create() when a new task is started. If set,
+ all files/drivers will appear to be closed in the new task except
+ for stdin, stdout, and stderr.
+
+config SDCLONE_DISABLE
+ bool "Disable cloning of socket descriptors"
+ default n
+ ---help---
+ Disable cloning of all socket
+ desciptors by task_create() when a new task is started. If
+ set, all sockets will appear to be closed in the new task.
+
+config SCHED_WORKQUEUE
+ bool "Enable worker thread"
+ default n
+ ---help---
+ Create a dedicated "worker" thread to handle delayed processing from interrupt
+ handlers. This feature is required for some drivers but, if there are no
+ complaints, can be safely disabled. The worker thread also performs
+ garbage collection -- completing any delayed memory deallocations from
+ interrupt handlers. If the worker thread is disabled, then that clean up will
+ be performed by the IDLE thread instead (which runs at the lowest of priority
+ and may not be appropriate if memory reclamation is of high priority).
+
+config SCHED_WORKPRIORITY
+ int "Worker thread priority"
+ default 192
+ depends on SCHED_WORKQUEUE
+ ---help---
+ The execution priority of the worker thread. Default: 192
+
+config SCHED_WORKPERIOD
+ int "Worker thread period"
+ default 50000
+ depends on SCHED_WORKQUEUE
+ ---help---
+ How often the worker thread checks for work in units of microseconds.
+ Default: 50*1000 (50 MS).
+
+config SCHED_WORKSTACKSIZE
+ int "Worker thread stack size"
+ default 2048
+ depends on SCHED_WORKQUEUE
+ ---help---
+ The stack size allocated for the worker thread. Default: 2K.
+
+config SIG_SIGWORK
+ int "Worker thread wakeup signal"
+ default 4
+ depends on SCHED_WORKQUEUE
+ ---help---
+ The signal number that will be used to wake-up the worker thread.
+ Default: 4
+
+config SCHED_LPWORK
+ bool "Enable a lower priority worker thread"
+ default n
+ depends on SCHED_WORKQUEUE
+ ---help---
+ If SCHED_WORKQUEUE is defined, then a single work queue is created by
+ default. If SCHED_LPWORK is also defined then an additional, lower-
+ priority work queue will also be created. This lower priority work
+ queue is better suited for more extended processing (such as file system
+ clean-up operations)
+
+config SCHED_LPWORKPRIORITY
+ int "Lower priority worker thread priority"
+ default 50
+ depends on SCHED_LPWORK
+ ---help---
+ The execution priority of the lopwer priority worker thread. Default: 192
+
+config SCHED_LPWORKPERIOD
+ int "Lower priority worker thread period"
+ default 50000
+ depends on SCHED_LPWORK
+ ---help---
+ How often the lower priority worker thread checks for work in units
+ of microseconds. Default: 50*1000 (50 MS).
+
+config SCHED_LPWORKSTACKSIZE
+ int "Lower priority worker thread stack size"
+ default 2048
+ depends on SCHED_LPWORK
+ ---help---
+ The stack size allocated for the lower priority worker thread. Default: 2K.
+
+config SCHED_WAITPID
+ bool "Enable waitpid() API"
+ default n
+ ---help---
+ Enables the waitpid() API
+
+config SCHED_ATEXIT
+ bool "Enable atexit() API"
+ default n
+ ---help---
+ Enables the atexit() API
+
+config SCHED_ATEXIT_MAX
+ int "Max number of atexit() functions"
+ default 1
+ depends on SCHED_ATEXIT
+ ---help---
+ By default if SCHED_ATEXIT is selected, only a single atexit() function
+ is supported. That number can be increased by defined this setting to
+ the number that you require.
+
+config SCHED_ONEXIT
+ bool "Enable on_exit() API"
+ default n
+ ---help---
+ Enables the on_exit() API
+
+config SCHED_ONEXIT_MAX
+ int "Max number of on_exit() functions"
+ default 1
+ depends on SCHED_ONEXIT
+ ---help---
+ By default if SCHED_ONEXIT is selected, only a single on_exit() function
+ is supported. That number can be increased by defined this setting to the
+ number that you require.
+
+config USER_ENTRYPOINT
+ string "Application entry point"
+ default "user_start"
+ ---help---
+ The name of the entry point for user applications. For the example
+ applications this is of the form 'app_main' where 'app' is the application
+ name. If not defined, USER_ENTRYPOINT defaults to "user_start."
+
+config DISABLE_OS_API
+ bool "Disable NuttX interfaces"
+ default y
+ ---help---
+ The following can be used to disable categories of
+ APIs supported by the OS. If the compiler supports
+ weak functions, then it should not be necessary to
+ disable functions unless you want to restrict usage
+ of those APIs.
+
+ There are certain dependency relationships in these
+ features.
+
+ o mq_notify logic depends on signals to awaken tasks
+ waiting for queues to become full or empty.
+ o pthread_condtimedwait() depends on signals to wake
+ up waiting tasks.
+
+config DISABLE_CLOCK
+ bool "Disable clock interfaces"
+ depends on DISABLE_OS_API
+ default n
+
+config DISABLE_POSIX_TIMERS
+ bool "Disable POSIX timers"
+ depends on DISABLE_OS_API
+ default n
+
+config DISABLE_PTHREAD
+ bool "Disable pthread support"
+ depends on DISABLE_OS_API
+ default n
+
+config DISABLE_SIGNALS
+ bool "Disable signal support"
+ depends on DISABLE_OS_API
+ default n
+
+config DISABLE_MQUEUE
+ bool "Disable POSIX message queue support"
+ depends on DISABLE_OS_API
+ default n
+
+config DISABLE_MOUNTPOINT
+ bool "Disable support for mount points"
+ depends on DISABLE_OS_API
+ default n
+
+config DISABLE_ENVIRON
+ bool "Disable environment variable support"
+ depends on DISABLE_OS_API
+ default n
+
+config DISABLE_POLL
+ bool "Disable driver poll interfaces"
+ depends on DISABLE_OS_API
+ default n
+
+comment "Sizes of configurable things (0 disables)"
+
+config MAX_TASKS
+ int "Max tasks"
+ default 32
+ ---help---
+ The maximum number of simultaneously active tasks. This value must be
+ a power of two.
+
+config MAX_TASK_ARGS
+ int "Maximum number of task arguments"
+ default 4
+ ---help---
+ This controls the maximum number of of parameters that a task may
+ receive (i.e., maxmum value of 'argc')
+
+config NPTHREAD_KEYS
+ int "Number of pthread keys"
+ default 4
+ ---help---
+ The number of items of thread-
+ specific data that can be retained
+
+config NFILE_DESCRIPTORS
+ int "Max file descriptors"
+ default 16
+ ---help---
+ The maximum number of file
+ descriptors (one for each open)
+
+config NFILE_STREAMS
+ int "Max file streams"
+ default 16
+ ---help---
+ The maximum number of streams that can be fopen'ed
+
+config NAME_MAX
+ int "name max"
+ default 32
+ ---help---
+ The maximum size of a file name.
+
+config PREALLOC_MQ_MSGS
+ int "Pre-allocated messages"
+ default 32
+ ---help---
+ The number of pre-allocated message structures. The system manages
+ a pool of preallocated message structures to minimize dynamic allocations
+
+config MQ_MAXMSGSIZE
+ int "Maximum message size"
+ default 32
+ ---help---
+ Message structures are allocated with a fixed payload size given by this
+ setting (does not include other message structure overhead.
+
+config MAX_WDOGPARMS
+ int "max watchdog parms"
+ default 4
+ ---help---
+ Maximum number of parameters that
+ can be passed to a watchdog handler
+
+config PREALLOC_WDOGS
+ int "Pre-allocated watchdogs"
+ default 32
+ ---help---
+ The number of pre-allocated watchdog structures. The system manages a
+ pool of preallocated watchdog structures to minimize dynamic allocations
+
+config PREALLOC_TIMERS
+ int "Pre-allocated timers"
+ default 8
+ ---help---
+ The number of pre-allocated POSIX timer structures. The system manages a
+ pool of preallocated timer structures to minimize dynamic allocations. Set to
+ zero for all dynamic allocations.
+
+comment "Stack and heap information"
+
+config CUSTOM_STACK
+ bool "Enable custom stack"
+ default n
+ ---help---
+ The up_ implementation will handle all stack operations outside of the
+ nuttx model. This is necessary for certain architectures that have
+ have hardware stacks (such as the 8051 family).
+
+config IDLETHREAD_STACKSIZE
+ int "Idle thread stack size"
+ default 1024
+ ---help---
+ The size of the initial stack used by the IDLE thread. The IDLE thread
+ is the thread that (1) performs the inital boot of the system up to the
+ point where user_start() is spawned, and (2) there after is the IDLE
+ thread that executes only when there is no other thread ready to run.
+
+config USERMAIN_STACKSIZE
+ int "Main thread stack size"
+ default 2048
+ ---help---
+ The size of the stack to allocate for the main user thread that begins at
+ the user_start() entry point.
+
+config PTHREAD_STACK_MIN
+ int "Minimum pthread stack size"
+ default 256
+ ---help---
+ Minimum pthread stack size
+
+config PTHREAD_STACK_DEFAULT
+ int "Default pthread stack size"
+ default 2048
+ ---help---
+ Default pthread stack size
+
diff --git a/nuttx/sched/Makefile b/nuttx/sched/Makefile
new file mode 100644
index 000000000..1e0a55aea
--- /dev/null
+++ b/nuttx/sched/Makefile
@@ -0,0 +1,216 @@
+############################################################################
+# sched/Makefile
+#
+# Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+-include $(TOPDIR)/Make.defs
+
+ASRCS =
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+
+MISC_SRCS = os_start.c os_bringup.c errno_getptr.c errno_get.c errno_set.c \
+ sched_garbage.c sched_setupstreams.c sched_getfiles.c sched_getsockets.c \
+ sched_getstreams.c sched_setupidlefiles.c sched_setuptaskfiles.c \
+ sched_setuppthreadfiles.c sched_releasefiles.c
+
+TSK_SRCS = prctl.c task_create.c task_init.c task_setup.c task_activate.c \
+ task_start.c task_delete.c task_deletecurrent.c task_exithook.c \
+ task_restart.c exit.c getpid.c sched_addreadytorun.c \
+ sched_removereadytorun.c sched_addprioritized.c sched_mergepending.c \
+ sched_addblocked.c sched_removeblocked.c sched_free.c sched_gettcb.c \
+ sched_verifytcb.c sched_releasetcb.c
+
+SCHED_SRCS = sched_setparam.c sched_setpriority.c sched_getparam.c \
+ sched_setscheduler.c sched_getscheduler.c \
+ sched_yield.c sched_rrgetinterval.c sched_foreach.c \
+ sched_lock.c sched_unlock.c sched_lockcount.c sched_self.c
+
+ifeq ($(CONFIG_SCHED_ATEXIT),y)
+SCHED_SRCS += atexit.c
+endif
+
+ifeq ($(CONFIG_SCHED_ONEXIT),y)
+SCHED_SRCS += on_exit.c
+endif
+
+ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
+SCHED_SRCS += sched_reprioritize.c
+endif
+
+ifeq ($(CONFIG_SCHED_WAITPID),y)
+SCHED_SRCS += sched_waitpid.c
+endif
+
+ENV_SRCS = env_getenvironptr.c env_dup.c env_share.c env_release.c \
+ env_findvar.c env_removevar.c \
+ env_clearenv.c env_getenv.c env_putenv.c env_setenv.c env_unsetenv.c
+
+WDOG_SRCS = wd_initialize.c wd_create.c wd_start.c wd_cancel.c wd_delete.c \
+ wd_gettime.c
+
+TIME_SRCS = sched_processtimer.c
+
+ifneq ($(CONFIG_DISABLE_SIGNALS),y)
+TIME_SRCS += sleep.c usleep.c
+endif
+
+CLOCK_SRCS = clock_initialize.c clock_settime.c clock_gettime.c clock_getres.c \
+ clock_time2ticks.c clock_abstime2ticks.c clock_ticks2time.c \
+ clock_gettimeofday.c clock_systimer.c
+
+SIGNAL_SRCS = sig_initialize.c \
+ sig_action.c sig_procmask.c sig_pending.c sig_suspend.c \
+ sig_kill.c sig_queue.c sig_waitinfo.c sig_timedwait.c \
+ sig_findaction.c sig_allocatependingsigaction.c \
+ sig_releasependingsigaction.c sig_unmaskpendingsignal.c \
+ sig_removependingsignal.c sig_releasependingsignal.c sig_lowest.c \
+ sig_mqnotempty.c sig_cleanup.c sig_received.c sig_deliver.c
+
+MQUEUE_SRCS = mq_open.c mq_close.c mq_unlink.c mq_send.c mq_timedsend.c\
+ mq_sndinternal.c mq_receive.c mq_timedreceive.c mq_rcvinternal.c \
+ mq_initialize.c mq_descreate.c mq_findnamed.c mq_msgfree.c mq_msgqfree.c
+
+ifneq ($(CONFIG_DISABLE_SIGNALS),y)
+MQUEUE_SRCS += mq_waitirq.c
+endif
+
+ifneq ($(CONFIG_DISABLE_SIGNALS),y)
+MQUEUE_SRCS += mq_notify.c
+endif
+
+PTHREAD_SRCS = pthread_create.c pthread_exit.c pthread_join.c pthread_detach.c \
+ pthread_yield.c pthread_getschedparam.c pthread_setschedparam.c \
+ pthread_mutexinit.c pthread_mutexdestroy.c \
+ pthread_mutexlock.c pthread_mutextrylock.c pthread_mutexunlock.c \
+ pthread_condinit.c pthread_conddestroy.c \
+ pthread_condwait.c pthread_condsignal.c pthread_condbroadcast.c \
+ pthread_barrierinit.c pthread_barrierdestroy.c pthread_barrierwait.c \
+ pthread_cancel.c pthread_setcancelstate.c \
+ pthread_keycreate.c pthread_setspecific.c pthread_getspecific.c pthread_keydelete.c \
+ pthread_initialize.c pthread_completejoin.c pthread_findjoininfo.c \
+ pthread_removejoininfo.c pthread_once.c pthread_setschedprio.c
+
+ifneq ($(CONFIG_DISABLE_SIGNALS),y)
+PTHREAD_SRCS += pthread_condtimedwait.c pthread_kill.c pthread_sigmask.c
+endif
+
+SEM_SRCS = sem_initialize.c sem_destroy.c sem_open.c sem_close.c sem_unlink.c \
+ sem_wait.c sem_trywait.c sem_timedwait.c sem_post.c sem_findnamed.c
+
+ifneq ($(CONFIG_DISABLE_SIGNALS),y)
+SEM_SRCS += sem_waitirq.c
+endif
+
+ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
+SEM_SRCS += sem_holder.c
+endif
+
+ifneq ($(CONFIG_DISABLE_POSIX_TIMERS),y)
+TIMER_SRCS = timer_initialize.c timer_create.c timer_delete.c timer_getoverrun.c \
+ timer_gettime.c timer_settime.c timer_release.c
+endif
+
+ifeq ($(CONFIG_SCHED_WORKQUEUE),y)
+WORK_SRCS = work_thread.c work_queue.c work_cancel.c work_signal.c
+endif
+
+ifeq ($(CONFIG_PAGING),y)
+PGFILL_SRCS = pg_miss.c pg_worker.c
+endif
+
+IRQ_SRCS = irq_initialize.c irq_attach.c irq_dispatch.c irq_unexpectedisr.c
+
+KMM_SRCS = kmm_initialize.c kmm_addregion.c kmm_semaphore.c \
+ kmm_kmalloc.c kmm_kzalloc.c kmm_krealloc.c kmm_kfree.c
+
+CSRCS = $(MISC_SRCS) $(TSK_SRCS) $(SCHED_SRCS) $(WDOG_SRCS) $(TIME_SRCS) \
+ $(SEM_SRCS) $(TIMER_SRCS) $(WORK_SRCS) $(PGFILL_SRCS) $(IRQ_SRCS)
+
+ifneq ($(CONFIG_DISABLE_CLOCK),y)
+CSRCS += $(CLOCK_SRCS)
+endif
+
+ifneq ($(CONFIG_DISABLE_PTHREAD),y)
+CSRCS += $(PTHREAD_SRCS)
+endif
+
+ifneq ($(CONFIG_DISABLE_SIGNALS),y)
+CSRCS += $(SIGNAL_SRCS)
+endif
+
+ifneq ($(CONFIG_DISABLE_MQUEUE),y)
+CSRCS += $(MQUEUE_SRCS)
+endif
+
+ifneq ($(CONFIG_DISABLE_ENVIRON),y)
+CSRCS += $(ENV_SRCS)
+endif
+
+ifeq ($(CONFIG_NUTTX_KERNEL),y)
+CSRCS += $(KMM_SRCS)
+endif
+
+COBJS = $(CSRCS:.c=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS)
+OBJS = $(AOBJS) $(COBJS)
+
+BIN = libsched$(LIBEXT)
+
+all: $(BIN)
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+$(BIN): $(OBJS)
+ @( for obj in $(OBJS) ; do \
+ $(call ARCHIVE, $@, $${obj}); \
+ done ; )
+
+.depend: Makefile $(SRCS)
+ @$(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
+ @touch $@
+
+depend: .depend
+
+clean:
+ @rm -f $(BIN) *~ .*.swp
+ $(call CLEAN)
+
+distclean: clean
+ @rm -f Make.dep .depend
+
+-include Make.dep
diff --git a/nuttx/sched/atexit.c b/nuttx/sched/atexit.c
new file mode 100644
index 000000000..f7d81bec2
--- /dev/null
+++ b/nuttx/sched/atexit.c
@@ -0,0 +1,162 @@
+/****************************************************************************
+ * sched/atexit.c
+ *
+ * Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/fs/fs.h>
+
+#include "os_internal.h"
+
+#ifdef CONFIG_SCHED_ATEXIT
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: atexit
+ *
+ * Description:
+ * Registers a function to be called at program exit.
+ * The atexit() function registers the given function to be called
+ * at normal process termination, whether via exit or via return from
+ * the program's main().
+ *
+ * NOTE: CONFIG_SCHED_ATEXIT must be defined to enable this function
+ *
+ * Limitiations in the current implementation:
+ *
+ * 1. Only a single atexit function can be registered unless
+ * CONFIG_SCHED_ATEXIT_MAX defines a larger number.
+ * 2. atexit functions are not inherited when a new task is
+ * created.
+ *
+ * Parameters:
+ * func - A pointer to the function to be called when the task exits.
+ *
+ * Return Value:
+ * Zero on success. Non-zero on failure.
+ *
+ ****************************************************************************/
+
+int atexit(void (*func)(void))
+{
+#if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1
+ _TCB *tcb = (_TCB*)g_readytorun.head;
+ int index;
+ int ret = ERROR;
+
+ /* The following must be atomic */
+
+ if (func)
+ {
+ sched_lock();
+
+ /* Search for the first available slot. atexit() functions are registered
+ * from lower to higher arry indices; they must be called in the reverse
+ * order of registration when task exists, i.e., from higher to lower
+ * indices.
+ */
+
+ available = -1;
+ for (index = 0; index < CONFIG_SCHED_ATEXIT_MAX; index++)
+ {
+ if (!tcb->atexitfunc[index])
+ {
+ tcb->atexitfunc[index] = func;
+ ret = OK;
+ break;
+ }
+ }
+
+ sched_unlock();
+ }
+
+ return ret;
+#else
+ _TCB *tcb = (_TCB*)g_readytorun.head;
+ int ret = ERROR;
+
+ /* The following must be atomic */
+
+ sched_lock();
+ if (func && !tcb->atexitfunc)
+ {
+ tcb->atexitfunc = func;
+ ret = OK;
+ }
+
+ sched_unlock();
+ return ret;
+#endif
+}
+
+#endif /* CONFIG_SCHED_ATEXIT */
+
+
diff --git a/nuttx/sched/clock_abstime2ticks.c b/nuttx/sched/clock_abstime2ticks.c
new file mode 100644
index 000000000..2d7f7f480
--- /dev/null
+++ b/nuttx/sched/clock_abstime2ticks.c
@@ -0,0 +1,126 @@
+/********************************************************************************
+ * clock_abstime2ticks.c
+ *
+ * Copyright (C) 2007, 2008 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 <time.h>
+#include <errno.h>
+#include <debug.h>
+#include "clock_internal.h"
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Type Declarations
+ ********************************************************************************/
+
+/********************************************************************************
+ * Global Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: clock_abstime2ticks
+ *
+ * Description:
+ * Convert an absolute timespec delay to system timer ticks.
+ *
+ * Parameters:
+ * clockid - The timing source to use in the conversion
+ * reltime - Convert this absolue time to system clock ticks.
+ * ticks - Return the converted number of ticks here.
+ *
+ * Return Value:
+ * OK on success; A non-zero error number on failure;
+ *
+ * Assumptions:
+ * Interrupts should be disabled so that the time is not changing during the
+ * calculation
+ *
+ ********************************************************************************/
+
+int clock_abstime2ticks(clockid_t clockid, FAR const struct timespec *abstime,
+ FAR int *ticks)
+{
+ struct timespec currtime;
+ struct timespec reltime;
+ int ret;
+
+ /* Convert the timespec to clock ticks. NOTE: Here we use internal knowledge
+ * that CLOCK_REALTIME is defined to be zero!
+ */
+
+ ret = clock_gettime(clockid, &currtime);
+ if (ret)
+ {
+ return EINVAL;
+ }
+
+ /* The relative time to wait is the absolute time minus the current time. */
+
+ reltime.tv_nsec = (abstime->tv_nsec - currtime.tv_nsec);
+ reltime.tv_sec = (abstime->tv_sec - currtime.tv_sec);
+
+ /* Check if we were supposed to borrow from the seconds to borrow from the
+ * seconds
+ */
+
+ if (reltime.tv_nsec < 0)
+ {
+ reltime.tv_nsec += NSEC_PER_SEC;
+ reltime.tv_sec -= 1;
+ }
+
+ /* Convert this relative time into microseconds.*/
+
+ return clock_time2ticks(&reltime, ticks);
+}
diff --git a/nuttx/sched/clock_dow.c b/nuttx/sched/clock_dow.c
new file mode 100644
index 000000000..93bcfc2d9
--- /dev/null
+++ b/nuttx/sched/clock_dow.c
@@ -0,0 +1,88 @@
+/****************************************************************************
+ * sched/clock_dow.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <nuttx/clock.h>
+
+#include "clock_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* 23 * (month + 1) / 9, month = 0..11 */
+
+static const uint8_t g_lookup[12] = {2, 5, 7, 10, 12, 15, 17, 20, 23, 25, 28, 30};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: clock_dow
+ *
+ * Description:
+ * Calculate the day of week (DOW) from they year month and day. Based on
+ * an algorithm pubished in 1990 by Michael Keith and Tom Craver with some
+ * tweaks to handle months in the range 0-11.
+ *
+ * Parameters:
+ * year - year (e.g., 1988)
+ * month - 0 through 11
+ * day - 1 through 31
+ *
+ * Return Value:
+ * The day of the week as days since Sunday: 0 = Sunday, 1 = Monday, etc.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int clock_dow(int year, int month, int day)
+{
+ day += month < 2 ? year-- : year - 2;
+ return ((int)g_lookup[month] + day + 4 + year/4 - year/100 + year/400) % 7;
+}
diff --git a/nuttx/sched/clock_getres.c b/nuttx/sched/clock_getres.c
new file mode 100644
index 000000000..a76b14ab6
--- /dev/null
+++ b/nuttx/sched/clock_getres.c
@@ -0,0 +1,121 @@
+/************************************************************************
+ * sched/clock_getres.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "clock_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/**********************************************************************
+ * Public Constant Data
+ **********************************************************************/
+
+/************************************************************************
+ * Public Variables
+ ************************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: clock_getres
+ *
+ * Description:
+ * Clock Functions based on POSIX APIs
+ *
+ ************************************************************************/
+
+int clock_getres(clockid_t clock_id, struct timespec *res)
+{
+ uint32_t time_res;
+ int ret = OK;
+
+ sdbg("clock_id=%d\n", clock_id);
+
+ /* Only CLOCK_REALTIME is supported */
+
+ if (clock_id != CLOCK_REALTIME)
+ {
+ sdbg("Returning ERROR\n");
+ set_errno(EINVAL);
+ ret = ERROR;
+ }
+ else
+ {
+ /* Get the clock resolution in nanoseconds */
+
+ time_res = MSEC_PER_TICK * NSEC_PER_MSEC;
+
+ /* And return this as a timespec. */
+
+ res->tv_sec = 0;
+ res->tv_nsec = time_res;
+
+ sdbg("Returning res=(%d,%d) time_res=%d\n",
+ (int)res->tv_sec, (int)res->tv_nsec,
+ (int)time_res);
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/clock_gettime.c b/nuttx/sched/clock_gettime.c
new file mode 100644
index 000000000..d6772dada
--- /dev/null
+++ b/nuttx/sched/clock_gettime.c
@@ -0,0 +1,180 @@
+/************************************************************************
+ * sched/clock_gettime.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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 <nuttx/rtc.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include "clock_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/**********************************************************************
+ * Public Constant Data
+ **********************************************************************/
+
+/************************************************************************
+ * Public Variables
+ ************************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: clock_gettime
+ *
+ * Description:
+ * Clock Functions based on POSIX APIs
+ *
+ ************************************************************************/
+
+int clock_gettime(clockid_t clock_id, struct timespec *tp)
+{
+#ifdef CONFIG_SYSTEM_TIME64
+ uint64_t msecs;
+ uint64_t secs;
+ uint64_t nsecs;
+#else
+ uint32_t msecs;
+ uint32_t secs;
+ uint32_t nsecs;
+#endif
+ int ret = OK;
+
+ sdbg("clock_id=%d\n", clock_id);
+ DEBUGASSERT(tp != NULL);
+
+ /* CLOCK_REALTIME - POSIX demands this to be present. This is the wall
+ * time clock.
+ */
+
+#ifdef CONFIG_RTC
+ if (clock_id == CLOCK_REALTIME || clock_id == CLOCK_ACTIVETIME)
+#else
+ if (clock_id == CLOCK_REALTIME)
+#endif
+ {
+ /* Do we have a high-resolution RTC that can provie us with the time? */
+
+#ifdef CONFIG_RTC_HIRES
+ if (g_rtc_enabled && clock_id != CLOCK_ACTIVETIME)
+ {
+ /* Yes.. Get the hi-resolution time from the RTC */
+
+ ret = up_rtc_gettime(tp);
+ }
+ else
+#endif
+ {
+ /* Get the elapsed time since power up (in milliseconds) biased
+ * as appropriate.
+ */
+
+ msecs = MSEC_PER_TICK * (g_system_timer - g_tickbias);
+
+ sdbg("msecs = %d g_tickbias=%d\n",
+ (int)msecs, (int)g_tickbias);
+
+ /* Get the elapsed time in seconds and nanoseconds. */
+
+ secs = msecs / MSEC_PER_SEC;
+ nsecs = (msecs - (secs * MSEC_PER_SEC)) * NSEC_PER_MSEC;
+
+ sdbg("secs = %d + %d nsecs = %d + %d\n",
+ (int)msecs, (int)g_basetime.tv_sec,
+ (int)nsecs, (int)g_basetime.tv_nsec);
+
+ /* Add the base time to this. */
+
+ secs += (uint32_t)g_basetime.tv_sec;
+ nsecs += (uint32_t)g_basetime.tv_nsec;
+
+ /* Handle carry to seconds. */
+
+ if (nsecs > NSEC_PER_SEC)
+ {
+ uint32_t dwCarrySecs = nsecs / NSEC_PER_SEC;
+ secs += dwCarrySecs;
+ nsecs -= (dwCarrySecs * NSEC_PER_SEC);
+ }
+
+ /* And return the result to the caller. */
+
+ tp->tv_sec = (time_t)secs;
+ tp->tv_nsec = (long)nsecs;
+ }
+
+ sdbg("Returning tp=(%d,%d)\n", (int)tp->tv_sec, (int)tp->tv_nsec);
+ }
+ else
+ {
+ sdbg("Returning ERROR\n");
+
+ errno = EINVAL;
+ ret = ERROR;
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/clock_gettimeofday.c b/nuttx/sched/clock_gettimeofday.c
new file mode 100644
index 000000000..6437ef955
--- /dev/null
+++ b/nuttx/sched/clock_gettimeofday.c
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * sched/clock_gettimeofday.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/time.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "clock_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/**************************************************************************
+ * Public Constant Data
+ **************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gettimeofday
+ *
+ * Description:
+ * Get the current time
+ *
+ ****************************************************************************/
+
+int gettimeofday(struct timeval *tp, void *tzp)
+{
+ struct timespec ts;
+ int ret;
+
+#ifdef CONFIG_DEBUG
+ if (!tp)
+ {
+ errno = EINVAL;
+ return ERROR;
+ }
+#endif
+
+ /* Let clock_gettime do most of the work */
+
+ ret = clock_gettime(CLOCK_REALTIME, &ts);
+ if (ret == OK)
+ {
+ /* Convert the struct timespec to a struct timeval */
+
+ tp->tv_sec = ts.tv_sec;
+ tp->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/clock_initialize.c b/nuttx/sched/clock_initialize.c
new file mode 100644
index 000000000..2e146bb47
--- /dev/null
+++ b/nuttx/sched/clock_initialize.c
@@ -0,0 +1,270 @@
+/****************************************************************************
+ * sched/clock_initialize.c
+ *
+ * Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <stdint.h>
+#include <time.h>
+#include <errno.h>
+#include <debug.h>
+
+#ifdef CONFIG_RTC
+# include <arch/irq.h>
+#endif
+
+#include <nuttx/clock.h>
+#include <nuttx/time.h>
+#include <nuttx/rtc.h>
+
+#include "clock_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+/* Standard time definitions (in units of seconds) */
+
+#define SEC_PER_MIN ((time_t)60)
+#define SEC_PER_HOUR ((time_t)60 * SEC_PER_MIN)
+#define SEC_PER_DAY ((time_t)24 * SEC_PER_HOUR)
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/**************************************************************************
+ * Public Constant Data
+ **************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_TIME64
+volatile uint64_t g_system_timer;
+uint64_t g_tickbias;
+#else
+volatile uint32_t g_system_timer;
+uint32_t g_tickbias;
+#endif
+
+struct timespec g_basetime;
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Functions
+ **************************************************************************/
+
+/****************************************************************************
+ * Name: clock_basetime
+ *
+ * Description:
+ * Get the initial time value from the best source available.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC
+#if defined(CONFIG_RTC_DATETIME)
+/* Initialize the system time using a broken out date/time structure */
+
+static inline void clock_basetime(FAR struct timespec *tp)
+{
+ struct tm rtctime;
+
+ /* Get the broken-out time from the date/time RTC. */
+
+ (void)up_rtc_getdatetime(&rtctime);
+
+ /* And use the broken-out time to initialize the system time */
+
+ tp->tv_sec = mktime(&rtctime);
+ tp->tv_nsec = 0;
+}
+
+#elif defined(CONFIG_RTC_HIRES)
+
+/* Initialize the system time using a high-resolution structure */
+
+static inline void clock_basetime(FAR struct timespec *tp)
+{
+ /* Get the complete time from the hi-res RTC. */
+
+ (void)up_rtc_gettime(tp);
+}
+
+#else
+
+/* Initialize the system time using seconds only */
+
+static inline void clock_basetime(FAR struct timespec *tp)
+{
+ /* Get the seconds (only) from the lo-resolution RTC */
+
+ tp->tv_sec = up_rtc_time();
+ tp->tv_nsec = 0;
+}
+
+#endif /* CONFIG_RTC_HIRES */
+#else /* CONFIG_RTC */
+
+static inline void clock_basetime(FAR struct timespec *tp)
+{
+ time_t jdn = 0;
+
+ /* Get the EPOCH-relative julian date from the calendar year,
+ * month, and date
+ */
+
+ jdn = clock_calendar2utc(CONFIG_START_YEAR, CONFIG_START_MONTH,
+ CONFIG_START_DAY);
+
+ /* Set the base time as seconds into this julian day. */
+
+ tp->tv_sec = jdn * SEC_PER_DAY;
+ tp->tv_nsec = 0;
+}
+
+#endif /* CONFIG_RTC */
+
+/****************************************************************************
+ * Name: clock_inittime
+ *
+ * Description:
+ * Get the initial time value from the best source available.
+ *
+ ****************************************************************************/
+
+static void clock_inittime(void)
+{
+ /* (Re-)initialize the time value to match the RTC*/
+
+ clock_basetime(&g_basetime);
+ g_system_timer = 0;
+ g_tickbias = 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: clock_initialize
+ *
+ * Description:
+ * Perform one-time initialization of the timing facilities.
+ *
+ ****************************************************************************/
+
+void clock_initialize(void)
+{
+ /* Initialize the RTC hardware */
+
+#ifdef CONFIG_RTC
+ up_rtcinitialize();
+#endif
+
+ /* Initialize the time value to match the RTC */
+
+ clock_inittime();
+}
+
+/****************************************************************************
+ * Name: clock_synchronize
+ *
+ * Description:
+ * Synchronize the system timer to a hardware RTC. This operation is
+ * normally performed automatically by the system during clock
+ * initialization. However, the user may also need to explicitly re-
+ * synchronize the system timer to the RTC under certain conditions where
+ * the system timer is known to be in error. For example, in certain low-
+ * power states, the system timer may be stopped but the RTC will continue
+ * keep correct time. After recovering from such low-power state, this
+ * function should be called to restore the correct system time.
+ *
+ * Calling this function could result in system time going "backward" in
+ * time, especially with certain lower resolution RTC implementations.
+ * Time going backward could have bad consequences if there are ongoing
+ * timers and delays. So use this interface with care.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC
+void clock_synchronize(void)
+{
+ irqstate_t flags;
+
+ /* Re-initialize the time value to match the RTC */
+
+ flags = irqsave();
+ clock_inittime();
+ irqrestore(flags);
+}
+#endif
+
+/****************************************************************************
+ * Name: clock_timer
+ *
+ * Description:
+ * This function must be called once every time the real time clock
+ * interrupt occurs. The interval of this clock interrupt must be
+ * MSEC_PER_TICK
+ *
+ ****************************************************************************/
+
+void clock_timer(void)
+{
+ /* Increment the per-tick system counter */
+
+ g_system_timer++;
+}
diff --git a/nuttx/sched/clock_internal.h b/nuttx/sched/clock_internal.h
new file mode 100644
index 000000000..aba9723b6
--- /dev/null
+++ b/nuttx/sched/clock_internal.h
@@ -0,0 +1,91 @@
+/********************************************************************************
+ * sched/clock_internal.h
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ********************************************************************************/
+
+#ifndef __SCHED_CLOCK_INTERNAL_H
+#define __SCHED_CLOCK_INTERNAL_H
+
+/********************************************************************************
+ * Included Files
+ ********************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+#include <nuttx/clock.h>
+#include <nuttx/compiler.h>
+
+/********************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************/
+/* Configuration ************************************************************/
+/* If CONFIG_SYSTEM_TIME64 is selected and the CPU supports long long types,
+ * then a 64-bit system time will be used.
+ */
+
+#ifndef CONFIG_HAVE_LONG_LONG
+# undef CONFIG_SYSTEM_TIME64
+#endif
+
+/********************************************************************************
+ * Public Type Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Global Variables
+ ********************************************************************************/
+
+#ifdef CONFIG_SYSTEM_TIME64
+extern uint64_t g_tickbias;
+#else
+extern uint32_t g_tickbias;
+#endif
+
+extern struct timespec g_basetime;
+
+/********************************************************************************
+ * Public Function Prototypes
+ ********************************************************************************/
+
+void weak_function clock_initialize(void);
+void weak_function clock_timer(void);
+
+int clock_abstime2ticks(clockid_t clockid,
+ FAR const struct timespec *abstime,
+ FAR int *ticks);
+int clock_time2ticks(FAR const struct timespec *reltime, FAR int *ticks);
+int clock_ticks2time(int ticks, FAR struct timespec *reltime);
+
+#endif /* __SCHED_CLOCK_INTERNAL_H */
diff --git a/nuttx/sched/clock_settime.c b/nuttx/sched/clock_settime.c
new file mode 100644
index 000000000..ce809aa11
--- /dev/null
+++ b/nuttx/sched/clock_settime.c
@@ -0,0 +1,149 @@
+/************************************************************************
+ * sched/clock_settime.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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 <nuttx/rtc.h>
+
+#include <time.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+#include "clock_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/**********************************************************************
+ * Public Constant Data
+ **********************************************************************/
+
+/************************************************************************
+ * Public Variables
+ ************************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: clock_settime
+ *
+ * Description:
+ * Clock Functions based on POSIX APIs
+ *
+ ************************************************************************/
+
+int clock_settime(clockid_t clock_id, FAR const struct timespec *tp)
+{
+ irqstate_t flags;
+ int ret = OK;
+
+ sdbg("clock_id=%d\n", clock_id);
+ DEBUGASSERT(tp != NULL);
+
+ /* CLOCK_REALTIME - POSIX demands this to be present. This is the wall
+ * time clock.
+ */
+
+#ifdef CONFIG_RTC
+ if (clock_id == CLOCK_REALTIME || clock_id == CLOCK_ACTIVETIME)
+#else
+ if (clock_id == CLOCK_REALTIME)
+#endif
+ {
+ /* Interrupts are disabled here so that the in-memory time
+ * representation and the RTC setting will be as close as
+ * possible.
+ */
+
+ flags = irqsave();
+
+ /* Save the new base time. */
+
+ g_basetime.tv_sec = tp->tv_sec;
+ g_basetime.tv_nsec = tp->tv_nsec;
+
+ /* Get the elapsed time since power up (in milliseconds) biased
+ * as appropriate.
+ */
+
+ g_tickbias = g_system_timer;
+
+ /* Setup the RTC (lo- or high-res) */
+
+#ifdef CONFIG_RTC
+ if (g_rtc_enabled && clock_id != CLOCK_ACTIVETIME)
+ {
+ up_rtc_settime(tp);
+ }
+#endif
+ irqrestore(flags);
+
+ sdbg("basetime=(%d,%d) tickbias=%d\n",
+ (int)g_basetime.tv_sec, (int)g_basetime.tv_nsec,
+ (int)g_tickbias);
+ }
+ else
+ {
+ sdbg("Returning ERROR\n");
+ set_errno(EINVAL);
+ ret = ERROR;
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/clock_systimer.c b/nuttx/sched/clock_systimer.c
new file mode 100644
index 000000000..33c16db94
--- /dev/null
+++ b/nuttx/sched/clock_systimer.c
@@ -0,0 +1,110 @@
+/****************************************************************************
+ * sched/clock_systimer.c
+ *
+ * Copyright (C) 2011 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 <stdint.h>
+
+#include <nuttx/clock.h>
+
+#include "clock_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: clock_systimer
+ *
+ * Description:
+ * Return the current value of the 32-bit system timer counter
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * The current value of the system timer counter
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#if !defined(clock_systimer) /* See nuttx/clock.h */
+uint32_t clock_systimer(void)
+{
+#ifdef CONFIG_SYSTEM_TIME64
+ return (uint32_t)(g_system_timer & 0x00000000ffffffff);
+#else
+ return g_system_timer;
+#endif
+}
+#endif
+
+/****************************************************************************
+ * Name: clock_systimer64
+ *
+ * Description:
+ * Return the current value of the 64-bit system timer counter
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * The current value of the system timer counter
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#if !defined(clock_systimer) /* See nuttx/clock.h */
+#ifdef CONFIG_SYSTEM_TIME64
+uint64_t clock_systimer64(void)
+{
+ return g_system_timer;
+}
+#endif
+#endif
diff --git a/nuttx/sched/clock_ticks2time.c b/nuttx/sched/clock_ticks2time.c
new file mode 100644
index 000000000..fd300692d
--- /dev/null
+++ b/nuttx/sched/clock_ticks2time.c
@@ -0,0 +1,94 @@
+/********************************************************************************
+ * clock_ticks2time.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ********************************************************************************/
+
+/********************************************************************************
+ * Included Files
+ ********************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <time.h>
+#include "clock_internal.h"
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Type Declarations
+ ********************************************************************************/
+
+/********************************************************************************
+ * Global Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: clock_ticks2time
+ *
+ * Description:
+ * Convert the system time tick value to a relative time.
+ *
+ * Parameters:
+ * ticks - The number of system time ticks to convert.
+ * reltime - Return the converted system time here.
+ *
+ * Return Value:
+ * Always returns OK
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int clock_ticks2time(int ticks, FAR struct timespec *reltime)
+{
+ int remainder;
+
+ reltime->tv_sec = ticks / TICK_PER_SEC;
+ remainder = ticks - TICK_PER_SEC * reltime->tv_sec;
+ reltime->tv_nsec = remainder * NSEC_PER_TICK;
+ return OK;
+}
diff --git a/nuttx/sched/clock_time2ticks.c b/nuttx/sched/clock_time2ticks.c
new file mode 100644
index 000000000..383264d51
--- /dev/null
+++ b/nuttx/sched/clock_time2ticks.c
@@ -0,0 +1,102 @@
+/********************************************************************************
+ * sched/clock_time2ticks.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ********************************************************************************/
+
+/********************************************************************************
+ * Included Files
+ ********************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <time.h>
+
+#include "clock_internal.h"
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Type Declarations
+ ********************************************************************************/
+
+/********************************************************************************
+ * Global Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: clock_time2ticks
+ *
+ * Description:
+ * Convert a timespec delay to system timer ticks. This function is suitable
+ * for calculating relative time delays and does not depend on the other
+ * clock_* logic.
+ *
+ * Parameters:
+ * reltime - Convert this relative time to system clock ticks.
+ * ticks - Return the converted number of ticks here.
+ *
+ * Return Value:
+ * Always returns OK
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int clock_time2ticks(FAR const struct timespec *reltime, FAR int *ticks)
+{
+ int32_t relusec;
+
+ /* Convert the relative time into microseconds.*/
+
+ relusec = reltime->tv_sec * USEC_PER_SEC + reltime->tv_nsec / NSEC_PER_USEC;
+
+ /* Convert microseconds to clock ticks */
+
+ *ticks = relusec / USEC_PER_TICK;
+ return OK;
+}
diff --git a/nuttx/sched/env_clearenv.c b/nuttx/sched/env_clearenv.c
new file mode 100644
index 000000000..7fe97a911
--- /dev/null
+++ b/nuttx/sched/env_clearenv.c
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * sched/env_clearenv.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <sched.h>
+#include <stdlib.h>
+#include "os_internal.h"
+#include "env_internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: clearenv
+ *
+ * Description:
+ * The clearenv() function clears the environment of all name-value pairs
+ * and sets the value of the external variable environ to NULL.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * Not called from an interrupt handler
+ *
+ ****************************************************************************/
+
+int clearenv(void)
+{
+ return env_release((FAR _TCB*)g_readytorun.head);
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_dup.c b/nuttx/sched/env_dup.c
new file mode 100644
index 000000000..033348411
--- /dev/null
+++ b/nuttx/sched/env_dup.c
@@ -0,0 +1,132 @@
+/****************************************************************************
+ * sched/env_dup.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <sys/types.h>
+#include <sched.h>
+#include <string.h>
+#include <errno.h>
+
+#include <nuttx/kmalloc.h>
+
+#include "os_internal.h"
+#include "env_internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: env_dup
+ *
+ * Description:
+ * Copy the internal environment structure of a task. This is the action
+ * that is performed when a new task is created: The new task has a private,
+ * exact duplicate of the parent task's environment.
+ *
+ * Parameters:
+ * ptcb The tcb to receive the newly allocated copy of the parspecifiedent
+ * TCB's environment structure with reference count equal to one
+ *
+ * Return Value:
+ * zero on success
+ *
+ * Assumptions:
+ * Not called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+int env_dup(FAR _TCB *ptcb)
+{
+ int ret = OK;
+ if (!ptcb )
+ {
+ ret = -EINVAL;
+ }
+ else
+ {
+ FAR _TCB *parent = (FAR _TCB*)g_readytorun.head;
+ environ_t *envp = NULL;
+
+ /* Pre-emption must be disabled throughout the following because the
+ * environment may be shared.
+ */
+
+ sched_lock();
+
+ /* Does the parent task have an environment? */
+
+ if (parent->envp)
+ {
+ /* Yes..The parent task has an environment, duplicate it */
+
+ size_t envlen = parent->envp->ev_alloc;
+ envp = (environ_t*)kmalloc(SIZEOF_ENVIRON_T( envlen ));
+ if (!envp)
+ {
+ ret = -ENOMEM;
+ }
+ else
+ {
+ envp->ev_crefs = 1;
+ envp->ev_alloc = envlen;
+ memcpy( envp->ev_env, parent->envp->ev_env, envlen );
+ }
+ }
+
+ /* Save the cloned environment in the new TCB */
+
+ ptcb->envp = envp;
+ sched_unlock();
+ }
+
+ return ret;
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_dupenv.c b/nuttx/sched/env_dupenv.c
new file mode 100644
index 000000000..32bf6a433
--- /dev/null
+++ b/nuttx/sched/env_dupenv.c
@@ -0,0 +1,112 @@
+/****************************************************************************
+ * eched/env_dupenv.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <sys/types.h>
+#include <sched.h>
+
+#include <nuttx/kmalloc.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: dupenv
+ *
+ * Description:
+ * Copy the internal environment structure of a task. This is the action
+ * that is performed when a new task is created: The new task has a private,
+ * exact duplicate of the parent task's environment.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * A pointer to a newly allocated copy of the specified TCB's environment
+ * structure with reference count equal to one.
+ *
+ * Assumptions:
+ * Not called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+FAR environ_t *dupenv(FAR _TCB *ptcb)
+{
+ environ_t *envp = NULL;
+
+ /* Pre-emption must be disabled throughout the following because the
+ * environment may be shared.
+ */
+
+ sched_lock();
+
+ /* Does the parent task have an environment? */
+
+ if (ptcb->envp)
+ {
+ /* Yes..The parent task has an environment, duplicate it */
+
+ size_t envlen = ptcb->envp->ev_alloc
+ envp = (environ_t*)kmalloc(SIZEOF_ENVIRON_T( envlen ));
+ if (envp)
+ {
+ envp->ev_crefs = 1;
+ envp->ev_alloc = envlen;
+ memcmp( envp->ev_env, ptcb->envp->ev_env, envlen );
+ }
+ }
+
+ sched_unlock();
+ return envp;
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_findvar.c b/nuttx/sched/env_findvar.c
new file mode 100644
index 000000000..a8e94180c
--- /dev/null
+++ b/nuttx/sched/env_findvar.c
@@ -0,0 +1,131 @@
+/****************************************************************************
+ * sched/env_findvar.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <stdbool.h>
+#include <string.h>
+#include <sched.h>
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: env_cmpname
+ ****************************************************************************/
+
+static bool env_cmpname(const char *pszname, const char *peqname)
+{
+ /* Search until we find anything different in the two names */
+
+ for (; *pszname == *peqname; pszname++, peqname++);
+
+ /* On sucess, pszname will end with '\0' and peqname with '=' */
+
+ if ( *pszname == '\0' && *peqname == '=' )
+ {
+ return true;
+ }
+
+ return false;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: env_findvar
+ *
+ * Description:
+ * Search the provided environment structure for the variable of the
+ * specified name.
+ *
+ * Parameters:
+ * envp The environment structre to be searched.
+ * pname The variable name to find
+ *
+ * Return Value:
+ * A pointer to the name=value string in the environment
+ *
+ * Assumptions:
+ * - Not called from an interrupt handler
+ * - Pre-emptions is disabled by caller
+ *
+ ****************************************************************************/
+
+FAR char *env_findvar(environ_t *envp, const char *pname)
+{
+ char *ret = NULL;
+
+ /* Verify input parameters */
+
+ if (envp && pname)
+ {
+ char *ptr;
+ char *end = &envp->ev_env[envp->ev_alloc];
+
+ /* Search for a name=value string with matching name */
+
+ for (ptr = envp->ev_env;
+ ptr < end && !env_cmpname( pname, ptr);
+ ptr += (strlen(ptr) + 1));
+
+ /* Check for success */
+
+ if (ptr < end)
+ {
+ ret = ptr;
+ }
+ }
+
+ return ret;
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_getenv.c b/nuttx/sched/env_getenv.c
new file mode 100644
index 000000000..ee8d798b1
--- /dev/null
+++ b/nuttx/sched/env_getenv.c
@@ -0,0 +1,135 @@
+/****************************************************************************
+ * env_getenv.c
+ *
+ * Copyright (C) 2007, 2008 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>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <sched.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "os_internal.h"
+#include "env_internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getenv
+ *
+ * Description:
+ * The getenv() function searches the environment list for a string that
+ * matches the string pointed to by name.
+ *
+ * Parameters:
+ * name - The name of the variable to find.
+ *
+ * Return Value:
+ * The value of the valiable (read-only) or NULL on failure
+ *
+ * Assumptions:
+ * Not called from an interrupt handler
+ *
+ ****************************************************************************/
+
+FAR char *getenv(const char *name)
+{
+ FAR _TCB *rtcb;
+ FAR environ_t *envp;
+ FAR char *pvar;
+ FAR char *pvalue = NULL;
+ int ret = OK;
+
+ /* Verify that a string was passed */
+
+ if (!name)
+ {
+ ret = EINVAL;
+ goto errout;
+ }
+
+ /* Get a reference to the thread-private environ in the TCB.*/
+
+ sched_lock();
+ rtcb = (FAR _TCB*)g_readytorun.head;
+ envp = rtcb->envp;
+
+ /* Check if the variable exists */
+
+ if ( !envp || (pvar = env_findvar(envp, name)) == NULL)
+ {
+ ret = ENOENT;
+ goto errout_with_lock;
+ }
+
+ /* It does! Get the value sub-string from the name=value string */
+
+ pvalue = strchr(pvar, '=');
+ if (!pvalue)
+ {
+ /* The name=value string has no '=' This is a bug! */
+
+ ret = EINVAL;
+ goto errout_with_lock;
+ }
+
+ /* Adjust the pointer so that it points to the value right after the '=' */
+
+ pvalue++;
+ sched_unlock();
+ return pvalue;
+
+errout_with_lock:
+ sched_unlock();
+errout:
+ set_errno(ret);
+ return NULL;
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_getenvironptr.c b/nuttx/sched/env_getenvironptr.c
new file mode 100644
index 000000000..25b09755b
--- /dev/null
+++ b/nuttx/sched/env_getenvironptr.c
@@ -0,0 +1,104 @@
+/****************************************************************************
+ * env_getenvironptr.c
+ *
+ * Copyright (C) 2007, 2008, 2011 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>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <sched.h>
+#include <stdlib.h>
+#include "os_internal.h"
+
+#undef get_environ_ptr
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: get_environ_ptr
+ *
+ * Description:
+ * Return a pointer to the thread specific environ variable.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * A pointer to the per-thread environ variable.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+FAR char **get_environ_ptr( void )
+{
+#if 1
+
+ /* Type of internal representation of environment is incompatible with
+ * char ** return value.
+ */
+
+ return NULL;
+
+#else
+
+ /* Return a reference to the thread-private environ in the TCB.*/
+
+ FAR _TCB *ptcb = (FAR _TCB*)g_readytorun.head;
+ if (ptcb->envp)
+ {
+ return &ptcb->envp->ev_env;
+ }
+ else
+ {
+ return NULL;
+ }
+
+#endif
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_internal.h b/nuttx/sched/env_internal.h
new file mode 100644
index 000000000..a6205d658
--- /dev/null
+++ b/nuttx/sched/env_internal.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * sched/env_internal.h
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_ENV_INTERNAL_H
+#define __SCHED_ENV_INTERNAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/sched.h>
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DISABLE_ENVIRON
+# define env_dup(ptcb) (0)
+# define env_share(ptcb) (0)
+# define env_release(ptcb) (0)
+#endif
+
+/****************************************************************************
+ * Public Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+#ifndef CONFIG_DISABLE_ENVIRON
+/* functions used by the task/pthread creation and destruction logic */
+
+EXTERN int env_dup(FAR _TCB *ptcb);
+EXTERN int env_share(FAR _TCB *ptcb);
+EXTERN int env_release(FAR _TCB *ptcb);
+
+/* functions used internally the environment handling logic */
+
+EXTERN FAR char *env_findvar(environ_t *envp, const char *pname);
+EXTERN int env_removevar(environ_t *envp, char *pvar);
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SCHED_ENV_INTERNAL_H */
+
diff --git a/nuttx/sched/env_putenv.c b/nuttx/sched/env_putenv.c
new file mode 100644
index 000000000..ad00dd13d
--- /dev/null
+++ b/nuttx/sched/env_putenv.c
@@ -0,0 +1,123 @@
+/****************************************************************************
+ * sched/env_putenv.c
+ *
+ * Copyright (C) 2007-2009, 2011 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>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <stdlib.h>
+#include <sched.h>
+#include <string.h>
+#include <errno.h>
+
+#include <nuttx/kmalloc.h>
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: putenv
+ *
+ * Description:
+ * The putenv() function adds or changes the value of environment variables.
+ * The argument string is of the form name=value. If name does not already
+ * exist in the environment, then string is added to the environment. If
+ * name does exist, then the value of name in the environment is changed to
+ * value.
+ *
+ * Parameters:
+ * name=value string describing the environment setting to add/modify
+ *
+ * Return Value:
+ * Zero on sucess
+ *
+ * Assumptions:
+ * Not called from an interrupt handler
+ *
+ ****************************************************************************/
+
+int putenv(FAR const char *string)
+{
+ char *pname;
+ char *pequal;
+ int ret = OK;
+
+ /* Verify that a string was passed */
+
+ if (!string)
+ {
+ ret = EINVAL;
+ goto errout;
+ }
+
+ /* Parse the name=value string */
+
+ pname = strdup(string);
+ if (!pname)
+ {
+ ret = ENOMEM;
+ goto errout;
+ }
+
+ pequal = strchr( pname, '=');
+ if (pequal)
+ {
+ /* Then let setenv do all of the work */
+
+ *pequal = '\0';
+ ret = setenv(pname, pequal+1, TRUE);
+ }
+
+ kfree(pname);
+ return ret;
+
+errout:
+ errno = ret;
+ return ERROR;
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_release.c b/nuttx/sched/env_release.c
new file mode 100644
index 000000000..83e65dbb5
--- /dev/null
+++ b/nuttx/sched/env_release.c
@@ -0,0 +1,125 @@
+/****************************************************************************
+ * sched/env_clearenv.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <sched.h>
+#include <errno.h>
+#include "os_internal.h"
+#include "env_internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: env_release
+ *
+ * Description:
+ * The env_release() function clears the environment of all name-value
+ * pairs and sets the value of the external variable environ to NULL.
+ *
+ * Parameters:
+ * ptcb Identifies the TCB containing the environment structure
+ *
+ * Return Value:
+ * zero on success
+ *
+ * Assumptions:
+ * Not called from an interrupt handler
+ *
+ ****************************************************************************/
+
+int env_release(FAR _TCB *ptcb)
+{
+ int ret = OK;
+
+ if (!ptcb)
+ {
+ ret = -EINVAL;
+ }
+ else
+ {
+ FAR environ_t *envp;
+
+ /* Examine the environ data in the TCB. Preemption is disabled because the
+ * the environment could be shared among threads.
+ */
+
+ sched_lock();
+ envp = ptcb->envp;
+ if (ptcb->envp)
+ {
+ /* Check the reference count on the environment structure */
+
+ if ( envp->ev_crefs <= 1)
+ {
+ /* Decrementing the reference count will destroy the environment */
+
+ sched_free( envp ); /* plain free() should be fine here */
+ }
+ else
+ {
+ /* The environment will persist after decrementing the reference
+ * count */
+
+ envp->ev_crefs--;
+ }
+
+ /* In any case, the environment is no longer accessible on this thread */
+
+ ptcb->envp = NULL;
+ }
+
+ sched_unlock();
+ }
+
+ return ret;
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_removevar.c b/nuttx/sched/env_removevar.c
new file mode 100644
index 000000000..e96aa7a37
--- /dev/null
+++ b/nuttx/sched/env_removevar.c
@@ -0,0 +1,119 @@
+/****************************************************************************
+ * sched/env_removevar.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <string.h>
+#include <sched.h>
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: env_removevar
+ *
+ * Description:
+ * Remove the referenced name=value pair from the environment
+ *
+ * Parameters:
+ * envp The environment containing the name=value pair
+ * pvar A pointer to the name=value pair in the restroom
+ *
+ * Return Value:
+ * Zero on success
+ *
+ * Assumptions:
+ * - Not called from an interrupt handler
+ * - Caller has pre-emptions disabled
+ * - Caller will reallocate the environment structure to the correct size
+ *
+ ****************************************************************************/
+
+int env_removevar(environ_t *envp, char *pvar)
+{
+ int ret = ERROR;
+ if (envp && pvar)
+ {
+ /* Verify that the pointer lies within the environment region */
+
+ int alloc = envp->ev_alloc; /* Size of the allocated environment */
+ char *end = &envp->ev_env[alloc]; /* Pointer to the end+1 of the environment */
+
+ if (pvar >= envp->ev_env && pvar < end)
+ {
+ /* Set up for the removal */
+
+ int len = strlen(pvar) + 1; /* Length of name=value string to remove */
+ char *src = &pvar[len]; /* Address of name=value string after */
+ char *dest = pvar; /* Location to move the next string */
+ int count = end - src; /* Number of bytes to move (might be zero) */
+
+ /* Move all of the environment strings after the removed one 'down.'
+ * this is inefficient, but robably not high duty.
+ */
+
+ while (count-- > 0)
+ {
+ *dest++ = *src++;
+ }
+
+ /* Then set to the new allocation size. The caller is expected to
+ * call realloc at some point but we don't do that here because the
+ * caller may add more stuff to the environment.
+ */
+
+ envp->ev_alloc -= len;
+ ret = OK;
+ }
+ }
+
+ return ret;
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_setenv.c b/nuttx/sched/env_setenv.c
new file mode 100644
index 000000000..c186241ef
--- /dev/null
+++ b/nuttx/sched/env_setenv.c
@@ -0,0 +1,208 @@
+/****************************************************************************
+ * sched/env_setenv.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <string.h>
+#include <errno.h>
+
+#include <nuttx/kmalloc.h>
+
+#include "os_internal.h"
+#include "env_internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: setenv
+ *
+ * Description:
+ * The setenv() function adds the variable name to the environment with the
+ * specified 'value' if the varialbe 'name" does not exist. If the 'name'
+ * does exist in the environment, then its value is changed to 'value' if
+ * 'overwrite' is non-zero; if 'overwrite' is zero, then the value of name
+ * unaltered.
+ *
+ * Parameters:
+ * name - The name of the variable to change
+ * value - The new value of the variable
+ * overwrite - Replace any existing value if non-zero.
+ *
+ * Return Value:
+ * Zero on success
+ *
+ * Assumptions:
+ * Not called from an interrupt handler
+ *
+ ****************************************************************************/
+
+int setenv(const char *name, const char *value, int overwrite)
+{
+ FAR _TCB *rtcb;
+ FAR environ_t *envp;
+ FAR char *pvar;
+ int varlen;
+ int ret = OK;
+
+ /* Verify input parameter */
+
+ if (!name)
+ {
+ ret = EINVAL;
+ goto errout;
+ }
+
+ /* if no value is provided, then this is the same as unsetenv (unless
+ * overwrite is false)
+ */
+
+ if (!value || *value == '\0')
+ {
+ /* If overwite is set then this is the same as unsetenv */
+
+ if (overwrite)
+ {
+ return unsetenv(name);
+ }
+ else
+ {
+ /* Otherwise, it is a request to remove a variable without altering it? */
+
+ return OK;
+ }
+ }
+
+ /* Get a reference to the thread-private environ in the TCB.*/
+
+ sched_lock();
+ rtcb = (FAR _TCB*)g_readytorun.head;
+ envp = rtcb->envp;
+
+ /* Check if the variable alreay exists */
+
+ if ( envp && (pvar = env_findvar(envp, name)) != NULL)
+ {
+ /* It does! Do we have permission to overwrite the existing value? */
+
+ if (!overwrite)
+ {
+ /* No.. then just return success */
+
+ sched_unlock();
+ return OK;
+ }
+
+ /* Yes.. just remove the name=value pair from the environment. It will
+ * be added again below. Note that we are responsible for reallocating
+ * the environment buffer; this will happen below.
+ */
+
+ (void)env_removevar(envp, pvar);
+ }
+
+ /* Get the size of the new name=value string. The +2 is for the '=' and for
+ * null terminator
+ */
+
+ varlen = strlen(name) + strlen(value) + 2;
+
+ /* Then allocate or reallocate the environment buffer */
+
+ if (envp)
+ {
+ int alloc = envp->ev_alloc;
+ environ_t *tmp = (environ_t*)krealloc(envp, SIZEOF_ENVIRON_T(alloc + varlen));
+ if (!tmp)
+ {
+ ret = ENOMEM;
+ goto errout_with_lock;
+ }
+
+ envp = tmp;
+ envp->ev_alloc = alloc + varlen;
+ pvar = &envp->ev_env[alloc];
+ }
+ else
+ {
+ envp = (environ_t*)kmalloc(SIZEOF_ENVIRON_T(varlen));
+ if (!envp)
+ {
+ ret = ENOMEM;
+ goto errout_with_lock;
+ }
+
+ envp->ev_crefs = 1;
+ envp->ev_alloc = varlen;
+ pvar = envp->ev_env;
+ }
+
+ /* Now, put the new name=value string into the environment buffer */
+
+ sprintf(pvar, "%s=%s", name, value);
+
+ /* Save the new environment pointer (it might have changed due to allocation or
+ * reallocation.
+ */
+
+ rtcb->envp = envp;
+ sched_unlock();
+ return OK;
+
+errout_with_lock:
+ sched_unlock();
+errout:
+ errno = ret;
+ return ERROR;
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_share.c b/nuttx/sched/env_share.c
new file mode 100644
index 000000000..5f37a0219
--- /dev/null
+++ b/nuttx/sched/env_share.c
@@ -0,0 +1,117 @@
+/****************************************************************************
+ * sched/env_share.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <sched.h>
+#include <errno.h>
+
+#include "os_internal.h"
+#include "env_internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: env_share
+ *
+ * Description:
+ * Increment the reference count on the internal environment structure of
+ * a task. This is the action that is performed when a new pthread is
+ * created: The new pthread shares the environment with its parent.
+ *
+ * Parameters:
+ * ptcb The new TCB to receive the shared environment.
+ *
+ * Return Value:
+ * A pointer to a specified TCB's environment structure with an incremented
+ * reference count.
+ *
+ * Assumptions:
+ * Not called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+int env_share(FAR _TCB *ptcb)
+{
+ int ret = OK;
+ if (!ptcb)
+ {
+ ret = -EINVAL;
+ }
+ else
+ {
+ FAR _TCB *parent = (FAR _TCB*)g_readytorun.head;
+ environ_t *envp = parent->envp;
+
+ /* Pre-emption must be disabled throughout the following because the
+ * environment is shared.
+ */
+
+ sched_lock();
+
+ /* Does the parent task have an environment? */
+
+ if (envp)
+ {
+ /* Yes.. increment the reference count on the environment */
+
+ envp->ev_crefs++;
+ }
+
+ /* Then share the environment */
+
+ ptcb->envp = envp;
+ sched_unlock();
+ }
+
+ return ret;
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/env_unsetenv.c b/nuttx/sched/env_unsetenv.c
new file mode 100644
index 000000000..52469fac9
--- /dev/null
+++ b/nuttx/sched/env_unsetenv.c
@@ -0,0 +1,138 @@
+/****************************************************************************
+ * sched/env_unsetenv.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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>
+
+#ifndef CONFIG_DISABLE_ENVIRON
+
+#include <sched.h>
+#include <string.h>
+#include <errno.h>
+
+#include <nuttx/kmalloc.h>
+
+#include "os_internal.h"
+#include "env_internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: unsetenv
+ *
+ * Description:
+ * The unsetenv() function deletes the variable name from the environment.
+ *
+ * Parameters:
+ * name - The name of the variable to delete
+ *
+ * Return Value:
+ * Zero on success
+ *
+ * Assumptions:
+ * Not called from an interrupt handler
+ *
+ ****************************************************************************/
+
+int unsetenv(const char *name)
+{
+ FAR _TCB *rtcb;
+ FAR environ_t *envp;
+ FAR char *pvar;
+ int ret = OK;
+
+ /* Verify input parameter */
+
+ if (!name)
+ {
+ ret = EINVAL;
+ goto errout;
+ }
+
+ /* Get a reference to the thread-private environ in the TCB.*/
+
+ sched_lock();
+ rtcb = (FAR _TCB*)g_readytorun.head;
+ envp = rtcb->envp;
+
+ /* Check if the variable exists */
+
+ if ( envp && (pvar = env_findvar(envp, name)) != NULL)
+ {
+ int alloc;
+ environ_t *tmp;
+
+ /* It does! Remove the name=value pair from the environment. */
+
+ (void)env_removevar(envp, pvar);
+
+ /* Reallocate the new environment buffer */
+
+ alloc = envp->ev_alloc;
+ tmp = (environ_t*)krealloc(envp, SIZEOF_ENVIRON_T(alloc));
+ if (!tmp)
+ {
+ ret = ENOMEM;
+ goto errout_with_lock;
+ }
+
+ /* Save the new environment pointer (it might have changed due to reallocation. */
+
+ rtcb->envp = tmp;
+ }
+
+ sched_unlock();
+ return OK;
+
+errout_with_lock:
+ sched_unlock();
+errout:
+ errno = ret;
+ return ERROR;
+}
+
+#endif /* CONFIG_DISABLE_ENVIRON */
+
+
+
diff --git a/nuttx/sched/errno_get.c b/nuttx/sched/errno_get.c
new file mode 100644
index 000000000..cac041f64
--- /dev/null
+++ b/nuttx/sched/errno_get.c
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * sched/errno_get.c
+ *
+ * Copyright (C) 2011 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 <errno.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#undef get_errno_ptr
+#undef get_errno
+#undef errno
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: get_errno
+ *
+ * Description:
+ * Return the value of the thread specific errno. This function is only
+ * intended to provide a mechanism for user-mode programs to get the
+ * thread-specific errno value. It is #define'd to the symbol errno in
+ * include/errno.h.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * The current value of the thread specific errno.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int get_errno(void)
+{
+ return *get_errno_ptr();
+}
+
+
diff --git a/nuttx/sched/errno_getptr.c b/nuttx/sched/errno_getptr.c
new file mode 100644
index 000000000..0b27768da
--- /dev/null
+++ b/nuttx/sched/errno_getptr.c
@@ -0,0 +1,117 @@
+/****************************************************************************
+ * sched/errno_getptr.c
+ *
+ * Copyright (C) 2007, 2008, 2011 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 <sched.h>
+#include <errno.h>
+#include <nuttx/arch.h>
+#include "os_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#undef get_errno_ptr
+#undef errno
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static int g_irqerrno;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: get_errno_ptr
+ *
+ * Description:
+ * Return a pointer to the thread specific errno.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * A pointer to the per-thread errno variable.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+FAR int *get_errno_ptr(void)
+{
+ /* Check if this function was called from an interrupt handler. In that
+ * case, we have to do things a little differently to prevent the interrupt
+ * handler from modifying the tasks errno value.
+ */
+
+ if (!up_interrupt_context())
+ {
+ /* We were called from the normal tasking context. Verify that the
+ * task at the head of the ready-to-run list is actually running. It
+ * may not be running during very brief times during context switching
+ * logic (see, for example, task_deletecurrent.c).
+ */
+
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ if (rtcb->task_state == TSTATE_TASK_RUNNING)
+ {
+ /* Yes.. the task is running normally. Return a reference to the
+ * thread-private errno in the TCB of the running task.
+ */
+
+ return &rtcb->pterrno;
+ }
+ }
+
+ /* We were called either from (1) an interrupt handler or (2) from normally
+ * code but in an unhealthy state. In either event, do not permit access to
+ * the errno in the TCB of the task at the head of the ready-to-run list.
+ * Instead, use a separate errno just for interrupt handlers. Of course, this
+ * would have to change if we ever wanted to support nested interrupts or if
+ * we really cared about the stability of the errno during those "unhealthy
+ * states."
+ */
+
+ return &g_irqerrno;
+}
+
+
diff --git a/nuttx/sched/errno_set.c b/nuttx/sched/errno_set.c
new file mode 100644
index 000000000..eda680b64
--- /dev/null
+++ b/nuttx/sched/errno_set.c
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * sched/errno_set.c
+ *
+ * Copyright (C) 2011 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 <errno.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#undef get_errno_ptr
+#undef set_errno
+#undef errno
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: set_errno
+ *
+ * Description:
+ * Set the value of the thread specific errno. This function is only
+ * intended to provide a mechanism for user-mode programs to set the
+ * thread-specific errno value.
+ *
+ * Parameters:
+ * errcode - The thread specific errno will be set to this error code value.
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void set_errno(int errcode)
+{
+ *get_errno_ptr() = errcode;
+}
+
+
diff --git a/nuttx/sched/exit.c b/nuttx/sched/exit.c
new file mode 100644
index 000000000..7e50c273c
--- /dev/null
+++ b/nuttx/sched/exit.c
@@ -0,0 +1,108 @@
+/****************************************************************************
+ * sched/exit.c
+ *
+ * Copyright (C) 2007-2008, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/fs/fs.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: exit
+ *
+ * Description:
+ * The exit() function causes normal process termination and the value of
+ * status & 0377 to be returned to the parent.
+ *
+ * All functions registered with atexit() and on_exit() are called, in the
+ * reverse order of their registration.
+ *
+ * All open streams are flushed and closed.
+ *
+ ****************************************************************************/
+
+void exit(int status)
+{
+ _TCB *tcb = (_TCB*)g_readytorun.head;
+
+ /* Only the lower 8-bits of status are used */
+
+ status &= 0xff;
+
+ /* Perform common task termination logic */
+
+ task_exithook(tcb, status);
+
+ /* Then "really" exit. Only the lower 8 bits of the exit status are used. */
+
+ _exit(status);
+}
diff --git a/nuttx/sched/getpid.c b/nuttx/sched/getpid.c
new file mode 100644
index 000000000..f41467d9f
--- /dev/null
+++ b/nuttx/sched/getpid.c
@@ -0,0 +1,85 @@
+/************************************************************************
+ * sched/getpid.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sched.h>
+
+#include "os_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: getpid
+ *
+ * Description:
+ * Get the task ID of the currently executing task.
+ *
+ ************************************************************************/
+
+pid_t getpid(void)
+{
+ /* Return the task ID from the TCB at the head of the
+ * ready-to-run task list
+ */
+
+ return ((FAR _TCB*)g_readytorun.head)->pid;
+}
diff --git a/nuttx/sched/irq_attach.c b/nuttx/sched/irq_attach.c
new file mode 100644
index 000000000..3f27a0530
--- /dev/null
+++ b/nuttx/sched/irq_attach.c
@@ -0,0 +1,127 @@
+/****************************************************************************
+ * sched/irq_attach.c
+ *
+ * Copyright (C) 2007-2008, 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/irq.h>
+
+#include "irq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: irq_attach
+ *
+ * Description:
+ * Configure the IRQ subsystem so that IRQ number 'irq' is dispatched to
+ * 'isr'
+ *
+ ****************************************************************************/
+
+int irq_attach(int irq, xcpt_t isr)
+{
+#if NR_IRQS > 0
+ int ret = ERROR;
+
+ if ((unsigned)irq < NR_IRQS)
+ {
+ irqstate_t state;
+
+ /* If the new ISR is NULL, then the ISR is being detached.
+ * In this case, disable the ISR and direct any interrupts
+ * to the unexpected interrupt handler.
+ */
+
+ state = irqsave();
+ if (isr == NULL)
+ {
+ /* Disable the interrupt if we can before detaching it. We might
+ * not be able to do this if: (1) the device does not have a
+ * centralized interrupt controller (so up_disable_irq() is not
+ * supported). Or (2) if the device has different number for vector
+ * numbers and IRQ numbers (in that case, we don't know the correct
+ * IRQ number to use to disable the interrupt). In those cases, the
+ * code will just need to be careful that it disables all interrupt
+ * sources before detaching from the interrupt vector.
+ */
+
+#if !defined(CONFIG_ARCH_NOINTC) && !defined(CONFIG_ARCH_VECNOTIRQ)
+ up_disable_irq(irq);
+#endif
+ /* Detaching the ISR really means re-attaching it to the
+ * unexpected exception handler.
+ */
+
+ isr = irq_unexpected_isr;
+ }
+
+ /* Save the new ISR in the table. */
+
+ g_irqvector[irq] = isr;
+ irqrestore(state);
+ ret = OK;
+ }
+
+ return ret;
+#else
+ return OK;
+#endif
+}
diff --git a/nuttx/sched/irq_dispatch.c b/nuttx/sched/irq_dispatch.c
new file mode 100644
index 000000000..1c39f59d1
--- /dev/null
+++ b/nuttx/sched/irq_dispatch.c
@@ -0,0 +1,105 @@
+/****************************************************************************
+ * sched/irq_dispatch.c
+ *
+ * Copyright (C) 2007, 2008 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 <debug.h>
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include "irq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: irq_dispatch
+ *
+ * Description:
+ * This function must be called from the achitecture-specific logic in
+ * order to dispatch an interrupt to the appropriate, registered handling
+ * logic.
+ *
+ ***************************************************************************/
+
+void irq_dispatch(int irq, FAR void *context)
+{
+ xcpt_t vector;
+
+ /* Perform some sanity checks */
+
+#if NR_IRQS > 0
+ if ((unsigned)irq >= NR_IRQS || g_irqvector[irq] == NULL)
+ {
+ vector = irq_unexpected_isr;
+ }
+ else
+ {
+ vector = g_irqvector[irq];
+ }
+#else
+ vector = irq_unexpected_isr;
+#endif
+
+ /* Then dispatch to the interrupt handler */
+
+ vector(irq, context);
+}
+
diff --git a/nuttx/sched/irq_initialize.c b/nuttx/sched/irq_initialize.c
new file mode 100644
index 000000000..2053dcb83
--- /dev/null
+++ b/nuttx/sched/irq_initialize.c
@@ -0,0 +1,91 @@
+/****************************************************************************
+ * sched/irq_initialize.c
+ *
+ * Copyright (C) 2007-2008, 2010 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 <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#include "irq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+FAR xcpt_t g_irqvector[NR_IRQS+1];
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: irq_initialize
+ *
+ * Description:
+ * Configure the IRQ subsystem
+ *
+ ****************************************************************************/
+
+void irq_initialize(void)
+{
+ int i;
+
+ /* Point all interrupt vectors to the unexpected interrupt */
+
+ for (i = 0; i < NR_IRQS; i++)
+ {
+ g_irqvector[i] = irq_unexpected_isr;
+ }
+}
+
diff --git a/nuttx/sched/irq_internal.h b/nuttx/sched/irq_internal.h
new file mode 100644
index 000000000..28411f64f
--- /dev/null
+++ b/nuttx/sched/irq_internal.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * sched/irq_internal.h
+ *
+ * Copyright (C) 2007, 2008 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.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_IRQ_INTERNAL_H
+#define __SCHED_IRQ_INTERNAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/compiler.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Type Declarations
+ ****************************************************************************/
+
+extern FAR xcpt_t g_irqvector[NR_IRQS+1];
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+EXTERN void weak_function irq_initialize(void);
+EXTERN int irq_unexpected_isr(int irq, FAR void *context);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SCHED_IRQ_INTERNAL_H */
+
diff --git a/nuttx/sched/irq_unexpectedisr.c b/nuttx/sched/irq_unexpectedisr.c
new file mode 100644
index 000000000..c0090ead4
--- /dev/null
+++ b/nuttx/sched/irq_unexpectedisr.c
@@ -0,0 +1,88 @@
+/****************************************************************************
+ * sched/irq_unexpectedisr.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+
+#include <nuttx/irq.h>
+
+#include "os_internal.h"
+#include "irq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: irq_unexpected_isr
+ *
+ * Description:
+ * An interrupt has been received for an IRQ that was never registered
+ * with the system.
+ *
+ ****************************************************************************/
+
+int irq_unexpected_isr(int irq, FAR void *context)
+{
+ (void)irqsave();
+ lldbg("irq: %d\n", irq);
+ PANIC(OSERR_UNEXPECTEDISR);
+ return OK; /* Won't get here */
+}
diff --git a/nuttx/sched/kmm_addregion.c b/nuttx/sched/kmm_addregion.c
new file mode 100644
index 000000000..652367f5a
--- /dev/null
+++ b/nuttx/sched/kmm_addregion.c
@@ -0,0 +1,113 @@
+/************************************************************************
+ * sched/kmm_addregion.c
+ *
+ * Copyright (C) 2011 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 <nuttx/kmalloc.h>
+
+#ifdef CONFIG_NUTTX_KERNEL
+
+/* This logic is all tentatively and, hopefully, will grow in usability.
+ * For now, the kernel-mode build uses the memory manager that is
+ * provided in the user-space build. That is awkward but reasonable for
+ * the current level of support: At present, only memory protection is
+ * provided. Kernel-mode code may call into user-mode code, but not
+ * vice-versa. So hosting the memory manager in user-space allows the
+ * memory manager to be shared in both kernel- and user-mode spaces.
+ *
+ * In the longer run, if an MMU is support that can provide virtualized
+ * memory, then some SLAB memory manager will be required in kernel-space
+ * with some kind of brk() system call to obtain mapped heap space.
+ *
+ * In the current build model, the user-space module is built first. The
+ * file user_map.h is generated in the first pass and contains the
+ * addresses of the memory manager needed in this file:
+ */
+
+#include <arch/board/user_map.h>
+
+/************************************************************************
+ * Pre-processor definition
+ ************************************************************************/
+
+/* This value is obtained from user_map.h */
+
+#define KADDREGION(h,s) ((kmaddregion_t)CONFIG_USER_MMADDREGION)(h,s)
+
+/************************************************************************
+ * Private Types
+ ************************************************************************/
+
+typedef void (*kmaddregion_t)(FAR void*, size_t);
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: kmm_addregion
+ *
+ * Description:
+ * This is a simple redirection to the user-space mm_addregion()
+ * function.
+ *
+ * Parameters:
+ * heap_start - Address of the beginning of the memory region
+ * heap_size - The size (in bytes) if the memory region.
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * 1. mm_addregion() resides in user-space
+ * 2. The address of the user space mm_addregion() is provided in
+ * user_map.h
+ * 3. The user-space mm_addregion() is callable from kernel-space.
+ *
+ ************************************************************************/
+
+void kmm_addregion(FAR void *heap_start, size_t heap_size)
+{
+ return KADDREGION(heap_start, heap_size);
+}
+
+#endif /* CONFIG_NUTTX_KERNEL */
diff --git a/nuttx/sched/kmm_initialize.c b/nuttx/sched/kmm_initialize.c
new file mode 100644
index 000000000..6dd08951b
--- /dev/null
+++ b/nuttx/sched/kmm_initialize.c
@@ -0,0 +1,113 @@
+/************************************************************************
+ * sched/kmm_initialize.c
+ *
+ * Copyright (C) 2011 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 <nuttx/kmalloc.h>
+
+#ifdef CONFIG_NUTTX_KERNEL
+
+/* This logic is all tentatively and, hopefully, will grow in usability.
+ * For now, the kernel-mode build uses the memory manager that is
+ * provided in the user-space build. That is awkward but reasonable for
+ * the current level of support: At present, only memory protection is
+ * provided. Kernel-mode code may call into user-mode code, but not
+ * vice-versa. So hosting the memory manager in user-space allows the
+ * memory manager to be shared in both kernel- and user-mode spaces.
+ *
+ * In the longer run, if an MMU is support that can provide virtualized
+ * memory, then some SLAB memory manager will be required in kernel-space
+ * with some kind of brk() system call to obtain mapped heap space.
+ *
+ * In the current build model, the user-space module is built first. The
+ * file user_map.h is generated in the first pass and contains the
+ * addresses of the memory manager needed in this file:
+ */
+
+#include <arch/board/user_map.h>
+
+/************************************************************************
+ * Pre-processor definition
+ ************************************************************************/
+
+/* This value is obtained from user_map.h */
+
+#define KINITIALIZE(h,s) ((kminitialize_t)CONFIG_USER_MMINIT)(h,s)
+
+/************************************************************************
+ * Private Types
+ ************************************************************************/
+
+typedef void (*kminitialize_t)(FAR void*, size_t);
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: kmm_initialize
+ *
+ * Description:
+ * This is a simple redirection to the user-space mm_initialize()
+ * function.
+ *
+ * Parameters:
+ * heap_start - Address of the beginning of the (initial) memory region
+ * heap_size - The size (in bytes) if the (initial) memory region.
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * 1. mm_initialize() resides in user-space
+ * 2. The address of the user space mm_initialize() is provided in
+ * user_map.h
+ * 3. The user-space mm_initialize() is callable from kernel-space.
+ *
+ ************************************************************************/
+
+void kmm_initialize(FAR void *heap_start, size_t heap_size)
+{
+ return KINITIALIZE(heap_start, heap_size);
+}
+
+#endif /* CONFIG_NUTTX_KERNEL */
diff --git a/nuttx/sched/kmm_kfree.c b/nuttx/sched/kmm_kfree.c
new file mode 100644
index 000000000..0f0eaa6c2
--- /dev/null
+++ b/nuttx/sched/kmm_kfree.c
@@ -0,0 +1,110 @@
+/************************************************************************
+ * sched/kmm_kfree.c
+ *
+ * Copyright (C) 2011 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 <nuttx/kmalloc.h>
+
+#ifdef CONFIG_NUTTX_KERNEL
+
+/* This logic is all tentatively and, hopefully, will grow in usability.
+ * For now, the kernel-mode build uses the memory manager that is
+ * provided in the user-space build. That is awkward but reasonable for
+ * the current level of support: At present, only memory protection is
+ * provided. Kernel-mode code may call into user-mode code, but not
+ * vice-versa. So hosting the memory manager in user-space allows the
+ * memory manager to be shared in both kernel- and user-mode spaces.
+ *
+ * In the longer run, if an MMU is support that can provide virtualized
+ * memory, then some SLAB memory manager will be required in kernel-space
+ * with some kind of brk() system call to obtain mapped heap space.
+ *
+ * In the current build model, the user-space module is built first. The
+ * file user_map.h is generated in the first pass and contains the
+ * addresses of the memory manager needed in this file:
+ */
+
+#include <arch/board/user_map.h>
+
+/************************************************************************
+ * Pre-processor definition
+ ************************************************************************/
+
+/* This value is obtained from user_map.h */
+
+#define KFREE(p) ((kfree_t)CONFIG_USER_FREE)(p)
+
+/************************************************************************
+ * Private Types
+ ************************************************************************/
+
+typedef void (*kfree_t)(FAR void *);
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: kfree
+ *
+ * Description:
+ * This is a simple redirection to the user-space free() function.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * 1. free() resides in user-space
+ * 2. The address of the user space free() is provided in user_map.h
+ * 3. The user-space free() is callable from kernel-space.
+ *
+ ************************************************************************/
+
+void kfree(FAR void *mem)
+{
+ return KFREE(mem);
+}
+
+#endif /* CONFIG_NUTTX_KERNEL */
diff --git a/nuttx/sched/kmm_kmalloc.c b/nuttx/sched/kmm_kmalloc.c
new file mode 100644
index 000000000..5e34c157f
--- /dev/null
+++ b/nuttx/sched/kmm_kmalloc.c
@@ -0,0 +1,110 @@
+/************************************************************************
+ * sched/kmm_kmalloc.c
+ *
+ * Copyright (C) 2011 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 <nuttx/kmalloc.h>
+
+#ifdef CONFIG_NUTTX_KERNEL
+
+/* This logic is all tentatively and, hopefully, will grow in usability.
+ * For now, the kernel-mode build uses the memory manager that is
+ * provided in the user-space build. That is awkward but reasonable for
+ * the current level of support: At present, only memory protection is
+ * provided. Kernel-mode code may call into user-mode code, but not
+ * vice-versa. So hosting the memory manager in user-space allows the
+ * memory manager to be shared in both kernel- and user-mode spaces.
+ *
+ * In the longer run, if an MMU is support that can provide virtualized
+ * memory, then some SLAB memory manager will be required in kernel-space
+ * with some kind of brk() system call to obtain mapped heap space.
+ *
+ * In the current build model, the user-space module is built first. The
+ * file user_map.h is generated in the first pass and contains the
+ * addresses of the memory manager needed in this file:
+ */
+
+#include <arch/board/user_map.h>
+
+/************************************************************************
+ * Pre-processor definition
+ ************************************************************************/
+
+/* This value is obtained from user_map.h */
+
+#define KMALLOC(s) ((kmalloc_t)CONFIG_USER_MALLOC)(s)
+
+/************************************************************************
+ * Private Types
+ ************************************************************************/
+
+typedef FAR void *(*kmalloc_t)(size_t);
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: kmalloc
+ *
+ * Description:
+ * This is a simple redirection to the user-space malloc() function.
+ *
+ * Parameters:
+ * size - Size (in bytes) of the memory region to be allocated.
+ *
+ * Return Value:
+ * The address of the allocated memory (NULL on failure to allocate)
+ *
+ * Assumptions:
+ * 1. malloc() resides in user-space
+ * 2. The address of the user space malloc() is provided in user_map.h
+ * 3. The user-space malloc() is callable from kernel-space.
+ *
+ ************************************************************************/
+
+FAR void *kmalloc(size_t size)
+{
+ return KMALLOC(size);
+}
+
+#endif /* CONFIG_NUTTX_KERNEL */
diff --git a/nuttx/sched/kmm_krealloc.c b/nuttx/sched/kmm_krealloc.c
new file mode 100644
index 000000000..3d3726566
--- /dev/null
+++ b/nuttx/sched/kmm_krealloc.c
@@ -0,0 +1,111 @@
+/************************************************************************
+ * sched/kmm_krealloc.c
+ *
+ * Copyright (C) 2011 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 <nuttx/kmalloc.h>
+
+#ifdef CONFIG_NUTTX_KERNEL
+
+/* This logic is all tentatively and, hopefully, will grow in usability.
+ * For now, the kernel-mode build uses the memory manager that is
+ * provided in the user-space build. That is awkward but reasonable for
+ * the current level of support: At present, only memory protection is
+ * provided. Kernel-mode code may call into user-mode code, but not
+ * vice-versa. So hosting the memory manager in user-space allows the
+ * memory manager to be shared in both kernel- and user-mode spaces.
+ *
+ * In the longer run, if an MMU is support that can provide virtualized
+ * memory, then some SLAB memory manager will be required in kernel-space
+ * with some kind of brk() system call to obtain mapped heap space.
+ *
+ * In the current build model, the user-space module is built first. The
+ * file user_map.h is generated in the first pass and contains the
+ * addresses of the memory manager needed in this file:
+ */
+
+#include <arch/board/user_map.h>
+
+/************************************************************************
+ * Pre-processor definition
+ ************************************************************************/
+
+/* This value is obtained from user_map.h */
+
+#define KREALLOC(p,s) ((krealloc_t)CONFIG_USER_REALLOC)(p,s)
+
+/************************************************************************
+ * Private Types
+ ************************************************************************/
+
+typedef FAR void *(*krealloc_t)(FAR void*, size_t);
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: krealloc
+ *
+ * Description:
+ * This is a simple redirection to the user-space realloc() function.
+ *
+ * Parameters:
+ * oldmem - The old memory allocated
+ * size - Size (in bytes) of the new memory region to be re-allocated.
+ *
+ * Return Value:
+ * The address of the re-allocated memory (NULL on failure to re-allocate)
+ *
+ * Assumptions:
+ * 1. realloc() resides in user-space
+ * 2. The address of the user space realloc() is provided in user_map.h
+ * 3. The user-space realloc() is callable from kernel-space.
+ *
+ ************************************************************************/
+
+FAR void *krealloc(FAR void *oldmem, size_t size)
+{
+ return KREALLOC(oldmem, size);
+}
+
+#endif /* CONFIG_NUTTX_KERNEL */
diff --git a/nuttx/sched/kmm_kzalloc.c b/nuttx/sched/kmm_kzalloc.c
new file mode 100644
index 000000000..42bcfcc0f
--- /dev/null
+++ b/nuttx/sched/kmm_kzalloc.c
@@ -0,0 +1,110 @@
+/************************************************************************
+ * sched/kmm_kzalloc.c
+ *
+ * Copyright (C) 2011 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 <nuttx/kmalloc.h>
+
+#ifdef CONFIG_NUTTX_KERNEL
+
+/* This logic is all tentatively and, hopefully, will grow in usability.
+ * For now, the kernel-mode build uses the memory manager that is
+ * provided in the user-space build. That is awkward but reasonable for
+ * the current level of support: At present, only memory protection is
+ * provided. Kernel-mode code may call into user-mode code, but not
+ * vice-versa. So hosting the memory manager in user-space allows the
+ * memory manager to be shared in both kernel- and user-mode spaces.
+ *
+ * In the longer run, if an MMU is support that can provide virtualized
+ * memory, then some SLAB memory manager will be required in kernel-space
+ * with some kind of brk() system call to obtain mapped heap space.
+ *
+ * In the current build model, the user-space module is built first. The
+ * file user_map.h is generated in the first pass and contains the
+ * addresses of the memory manager needed in this file:
+ */
+
+#include <arch/board/user_map.h>
+
+/************************************************************************
+ * Pre-processor definition
+ ************************************************************************/
+
+/* This value is obtained from user_map.h */
+
+#define KZALLOC(s) ((kzalloc_t)CONFIG_USER_ZALLOC)(s)
+
+/************************************************************************
+ * Private Types
+ ************************************************************************/
+
+typedef FAR void *(*kzalloc_t)(size_t);
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: kzalloc
+ *
+ * Description:
+ * This is a simple redirection to the user-space zalloc() function.
+ *
+ * Parameters:
+ * size - Size (in bytes) of the memory region to be allocated.
+ *
+ * Return Value:
+ * The address of the allocated memory (NULL on failure to allocate)
+ *
+ * Assumptions:
+ * 1. zalloc() resides in user-space
+ * 2. The address of the user space zalloc() is provided in user_map.h
+ * 3. The user-space zalloc() is callable from kernel-space.
+ *
+ ************************************************************************/
+
+FAR void *kzalloc(size_t size)
+{
+ return KZALLOC(size);
+}
+
+#endif /* CONFIG_NUTTX_KERNEL */
diff --git a/nuttx/sched/kmm_semaphore.c b/nuttx/sched/kmm_semaphore.c
new file mode 100644
index 000000000..7fce747b6
--- /dev/null
+++ b/nuttx/sched/kmm_semaphore.c
@@ -0,0 +1,140 @@
+/************************************************************************
+ * sched/kmm_semaphore.c
+ *
+ * Copyright (C) 2011 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 <nuttx/kmalloc.h>
+
+#ifdef CONFIG_NUTTX_KERNEL
+
+/* This logic is all tentatively and, hopefully, will grow in usability.
+ * For now, the kernel-mode build uses the memory manager that is
+ * provided in the user-space build. That is awkward but reasonable for
+ * the current level of support: At present, only memory protection is
+ * provided. Kernel-mode code may call into user-mode code, but not
+ * vice-versa. So hosting the memory manager in user-space allows the
+ * memory manager to be shared in both kernel- and user-mode spaces.
+ *
+ * In the longer run, if an MMU is support that can provide virtualized
+ * memory, then some SLAB memory manager will be required in kernel-space
+ * with some kind of brk() system call to obtain mapped heap space.
+ *
+ * In the current build model, the user-space module is built first. The
+ * file user_map.h is generated in the first pass and contains the
+ * addresses of the memory manager needed in this file:
+ */
+
+#include <arch/board/user_map.h>
+
+/************************************************************************
+ * Pre-processor definition
+ ************************************************************************/
+
+/* These values are obtained from user_map.h */
+
+#define KTRYSEMAPHORE() ((kmtrysemaphore_t) CONFIG_USER_MMTRYSEM )()
+#define KGIVESEMAPHORE() ((kmgivesemaphore_t)CONFIG_USER_MMGIVESEM)()
+
+/************************************************************************
+ * Private Types
+ ************************************************************************/
+
+typedef int (*kmtrysemaphore_t)(void);
+typedef void (*kmgivesemaphore_t)(void);
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: kmm_trysemaphore
+ *
+ * Description:
+ * This is a simple redirection to the user-space mm_trysemaphore()
+ * function.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ * 1. mm_trysemaphore() resides in user-space
+ * 2. The address of the user space mm_trysemaphore() is provided in
+ * user_map.h
+ * 3. The user-space mm_semaphore() is callable from kernel-space.
+ *
+ ************************************************************************/
+
+int kmm_trysemaphore(void)
+{
+ return KTRYSEMAPHORE();
+}
+
+/************************************************************************
+ * Name: kmm_givesemaphore
+ *
+ * Description:
+ * This is a simple redirection to the user-space mm_givesemaphore()
+ * function.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ * 1. mm_givesemaphore() resides in user-space
+ * 2. The address of the user space mm_givesemaphore() is provided in
+ * user_map.h
+ * 3. The user-space mm_semaphore() is callable from kernel-space.
+ *
+ ************************************************************************/
+
+void kmm_givesemaphore(void)
+{
+ KGIVESEMAPHORE();
+}
+
+#endif /* CONFIG_NUTTX_KERNEL */
diff --git a/nuttx/sched/mq_close.c b/nuttx/sched/mq_close.c
new file mode 100644
index 000000000..57780a8e6
--- /dev/null
+++ b/nuttx/sched/mq_close.c
@@ -0,0 +1,187 @@
+/****************************************************************************
+ * sched/mq_close.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <mqueue.h>
+#include <sched.h>
+
+#include "os_internal.h"
+#include "mq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_desfree
+ *
+ * Description:
+ * Deallocate a message queue descriptor but returning it to the free list
+ *
+ * Inputs:
+ * mqdes - message queue descriptor to free
+ *
+ ****************************************************************************/
+
+#define mq_desfree(mqdes) sq_addlast((FAR sq_entry_t*)mqdes, &g_desfree)
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_close
+ *
+ * Description:
+ * This function is used to indicate that the calling task is finished
+ * with the specified message queued mqdes. The mq_close() deallocates
+ * any system resources allocated by the system for use by this task for
+ * its message queue.
+ *
+ * If the calling task has attached a notification to the message queue
+ * via this mqdes, this attachment will be removed and the message queue
+ * is available for another process to attach a notification.
+ *
+ * Parameters:
+ * mqdes - Message queue descriptor.
+ *
+ * Return Value:
+ * 0 (OK) if the message queue is closed successfully,
+ * otherwise, -1 (ERROR).
+ *
+ * Assumptions:
+ * - The behavior of a task that is blocked on either a mq_send() or
+ * mq_receive() is undefined when mq_close() is called.
+ * - The results of using this message queue descriptor after a successful
+ * return from mq_close() is undefined.
+ *
+ ****************************************************************************/
+
+int mq_close(mqd_t mqdes)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ FAR msgq_t *msgq;
+ irqstate_t saved_state;
+ int ret = ERROR;
+
+ /* Verify the inputs */
+
+ if (mqdes)
+ {
+ sched_lock();
+
+ /* Remove the message descriptor from the current task's
+ * list of message descriptors.
+ */
+
+ sq_rem((FAR sq_entry_t*)mqdes, &rtcb->msgdesq);
+
+ /* Find the message queue associated with the message descriptor */
+
+ msgq = mqdes->msgq;
+
+ /* Check if the calling task has a notification attached to
+ * the message queue via this mqdes.
+ */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ if (msgq->ntmqdes == mqdes)
+ {
+ msgq->ntpid = INVALID_PROCESS_ID;
+ msgq->ntsigno = 0;
+ msgq->ntvalue.sival_int = 0;
+ msgq->ntmqdes = NULL;
+ }
+#endif
+
+ /* Decrement the connection count on the message queue. */
+
+ if (msgq->nconnect)
+ {
+ msgq->nconnect--;
+ }
+
+ /* If it is no longer connected to any message descriptor and if the
+ * message queue has already been unlinked, then we can discard the
+ * message queue.
+ */
+
+ if (!msgq->nconnect && msgq->unlinked)
+ {
+ /* Remove the message queue from the list of all
+ * message queues
+ */
+
+ saved_state = irqsave();
+ (void)sq_rem((FAR sq_entry_t*)msgq, &g_msgqueues);
+ irqrestore(saved_state);
+
+ /* Then deallocate it (and any messages left in it) */
+
+ mq_msgqfree(msgq);
+ }
+
+ /* Deallocate the message descriptor */
+
+ mq_desfree(mqdes);
+
+ sched_unlock();
+ ret = OK;
+ }
+
+ return ret;
+}
+
diff --git a/nuttx/sched/mq_descreate.c b/nuttx/sched/mq_descreate.c
new file mode 100644
index 000000000..14937888c
--- /dev/null
+++ b/nuttx/sched/mq_descreate.c
@@ -0,0 +1,159 @@
+/****************************************************************************
+ * sched/mq_descreate.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <mqueue.h>
+#include <sched.h>
+#include <queue.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/kmalloc.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+#include "mq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_desalloc
+ *
+ * Description:
+ * Allocate a message queue descriptor.
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * Reference to the allocated mq descriptor.
+ *
+ ****************************************************************************/
+
+static mqd_t mq_desalloc(void)
+{
+ mqd_t mqdes;
+
+ /* Try to get the message descriptorfrom the free list */
+
+ mqdes = (mqd_t)sq_remfirst(&g_desfree);
+
+ /* Check if we got one. */
+
+ if (!mqdes)
+ {
+ /* Add another block of message descriptors to the list */
+
+ mq_desblockalloc();
+
+ /* And try again */
+
+ mqdes = (mqd_t)sq_remfirst(&g_desfree);
+ }
+
+ return mqdes;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_descreate
+ *
+ * Description:
+ * Create a message queue descriptor for the specified TCB
+ *
+ * Inputs:
+ * TCB - task that needs the descriptor.
+ * msgq - Named message queue containing the message
+ * oflags - access rights for the descriptor
+ *
+ * Return Value:
+ * On success, the message queue descriptor is returned. NULL is returned
+ * on a failure to allocate.
+ *
+ ****************************************************************************/
+
+mqd_t mq_descreate(FAR _TCB* mtcb, FAR msgq_t* msgq, int oflags)
+{
+ mqd_t mqdes;
+
+ /* Create a message queue descriptor for the TCB */
+
+ mqdes = mq_desalloc();
+ if (mqdes)
+ {
+ /* Initialize the MQ descriptor */
+
+ memset(mqdes, 0, sizeof(struct mq_des));
+ mqdes->msgq = msgq;
+ mqdes->oflags = oflags;
+
+ /* And add it to the specified tasks's TCB */
+
+ sq_addlast((FAR sq_entry_t*)mqdes, &mtcb->msgdesq);
+ }
+
+ return mqdes;
+}
diff --git a/nuttx/sched/mq_findnamed.c b/nuttx/sched/mq_findnamed.c
new file mode 100644
index 000000000..d23b81c5e
--- /dev/null
+++ b/nuttx/sched/mq_findnamed.c
@@ -0,0 +1,105 @@
+/************************************************************************
+ * sched/mq_findnamed.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+
+#include "mq_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: mq_findnamed
+ *
+ * Description:
+ * This function finds the named message queue with the specified name
+ * in the list of message queues.
+ *
+ * Inputs:
+ * mq_name - the name of the message queue to find
+ *
+ * Return Value:
+ * A reference to the matching named message queue structure (or NULL
+ * if none was found).
+ *
+ ************************************************************************/
+
+FAR msgq_t *mq_findnamed(const char *mq_name)
+{
+ FAR msgq_t *msgq;
+
+ /* Search the list of named message queues */
+
+ for (msgq = (FAR msgq_t*)g_msgqueues.head; (msgq); msgq = msgq->flink)
+ {
+ /* Break out of the lloop with a non-NULL msgq if the
+ * name matches.
+ */
+
+ if (!strcmp(mq_name, msgq->name))
+ {
+ break;
+ }
+ }
+
+ return msgq;
+}
diff --git a/nuttx/sched/mq_initialize.c b/nuttx/sched/mq_initialize.c
new file mode 100644
index 000000000..5b03a1120
--- /dev/null
+++ b/nuttx/sched/mq_initialize.c
@@ -0,0 +1,243 @@
+/************************************************************************
+ * sched/mq_initialize.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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 <stdint.h>
+#include <queue.h>
+#include <nuttx/kmalloc.h>
+
+#include "mq_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/* This is a container for a list of message queue descriptors. */
+
+struct mq_des_block_s
+{
+ sq_entry_t queue;
+ struct mq_des mqdes[NUM_MSG_DESCRIPTORS];
+};
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/* This is a list of all opened message queues */
+
+sq_queue_t g_msgqueues;
+
+/* The g_msgfree is a list of messages that are available for general
+ * use. The number of messages in this list is a system configuration
+ * item.
+ */
+
+sq_queue_t g_msgfree;
+
+/* The g_msgfreeInt is a list of messages that are reserved for use by
+ * interrupt handlers.
+ */
+
+sq_queue_t g_msgfreeirq;
+
+/* The g_desfree data structure is a list of message descriptors available
+ * to the operating system for general use. The number of messages in the
+ * pool is a constant.
+ */
+
+sq_queue_t g_desfree;
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/* g_msgalloc is a pointer to the start of the allocated block of
+ * messages.
+ */
+
+static mqmsg_t *g_msgalloc;
+
+/* g_msgfreeirqalloc is a pointer to the start of the allocated block of
+ * messages.
+ */
+
+static mqmsg_t *g_msgfreeirqalloc;
+
+/* g_desalloc is a list of allocated block of message queue descriptors. */
+
+static sq_queue_t g_desalloc;
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: mq_msgblockalloc
+ *
+ * Description:
+ * Allocate a block of messages and place them on the free list.
+ *
+ * Inputs Parameters:
+ * queue
+ *
+ ************************************************************************/
+
+static mqmsg_t *mq_msgblockalloc(sq_queue_t *queue, uint16_t nmsgs,
+ uint8_t alloc_type)
+{
+ mqmsg_t *mqmsgblock;
+
+ /* The g_msgfree must be loaded at initialization time to hold the
+ * configured number of messages.
+ */
+
+ mqmsgblock = (mqmsg_t*)kmalloc(sizeof(mqmsg_t) * nmsgs);
+ if (mqmsgblock)
+ {
+ mqmsg_t *mqmsg = mqmsgblock;
+ int i;
+
+ for (i = 0; i < nmsgs; i++)
+ {
+ mqmsg->type = alloc_type;
+ sq_addlast((FAR sq_entry_t*)mqmsg++, queue);
+ }
+ }
+
+ return mqmsgblock;
+}
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: mq_initialize
+ *
+ * Description:
+ * This function initializes the messasge system. This function must
+ * be called early in the initialization sequence before any of the
+ * other message interfaces execute.
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ ************************************************************************/
+
+void mq_initialize(void)
+{
+ /* Initialize the list of message queues */
+
+ sq_init(&g_msgqueues);
+
+ /* Initialize the message free lists */
+
+ sq_init(&g_msgfree);
+ sq_init(&g_msgfreeirq);
+ sq_init(&g_desalloc);
+
+ /* Allocate a block of messages for general use */
+
+ g_msgalloc =
+ mq_msgblockalloc(&g_msgfree, CONFIG_PREALLOC_MQ_MSGS,
+ MQ_ALLOC_FIXED);
+
+ /* Allocate a block of messages for use exclusively by
+ * interrupt handlers
+ */
+
+ g_msgfreeirqalloc =
+ mq_msgblockalloc(&g_msgfreeirq, NUM_INTERRUPT_MSGS,
+ MQ_ALLOC_IRQ);
+
+ /* Allocate a block of message queue descriptors */
+
+ mq_desblockalloc();
+}
+
+/************************************************************************
+ * Name: mq_desblockalloc
+ *
+ * Description:
+ * Allocate a block of message descriptors and place them on the free
+ * list.
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ ************************************************************************/
+
+void mq_desblockalloc(void)
+{
+ struct mq_des_block_s *mqdesblock;
+
+ /* Allocate a block of message descriptors */
+
+ mqdesblock = (struct mq_des_block_s *)kmalloc(sizeof(struct mq_des_block_s));
+ if (mqdesblock)
+ {
+ int i;
+
+ /* Add the block to the list of allocated blocks (in case
+ * we ever need to reclaim the memory.
+ */
+
+ sq_addlast((FAR sq_entry_t*)&mqdesblock->queue, &g_desalloc);
+
+ /* Then add each message queue descriptor to the free list */
+
+ for (i = 0; i < NUM_MSG_DESCRIPTORS; i++)
+ {
+ sq_addlast((FAR sq_entry_t*)&mqdesblock->mqdes[i], &g_desfree);
+ }
+ }
+}
+
diff --git a/nuttx/sched/mq_internal.h b/nuttx/sched/mq_internal.h
new file mode 100644
index 000000000..6135bfaef
--- /dev/null
+++ b/nuttx/sched/mq_internal.h
@@ -0,0 +1,183 @@
+/****************************************************************************
+ * sched/mq_internal.h
+ *
+ * Copyright (C) 2007, 2009, 2011 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.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_MQ_INTERNAL_H
+#define __SCHED_MQ_INTERNAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <limits.h>
+#include <mqueue.h>
+#include <sched.h>
+#include <signal.h>
+
+#include <nuttx/mqueue.h>
+
+#if CONFIG_MQ_MAXMSGSIZE > 0
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#define MQ_MAX_BYTES CONFIG_MQ_MAXMSGSIZE
+#define MQ_MAX_MSGS 16
+#define MQ_PRIO_MAX _POSIX_MQ_PRIO_MAX
+
+/* This defines the number of messages descriptors to allocate at each
+ * "gulp."
+ */
+
+#define NUM_MSG_DESCRIPTORS 24
+
+/* This defines the number of messages to set aside for exclusive use by
+ * interrupt handlers
+ */
+
+#define NUM_INTERRUPT_MSGS 8
+
+/****************************************************************************
+ * Global Type Declarations
+ ****************************************************************************/
+
+enum mqalloc_e
+{
+ MQ_ALLOC_FIXED = 0, /* pre-allocated; never freed */
+ MQ_ALLOC_DYN, /* dynamically allocated; free when unused */
+ MQ_ALLOC_IRQ /* Preallocated, reserved for interrupt handling */
+};
+
+typedef enum mqalloc_e mqalloc_t;
+
+/* This structure describes one buffered POSIX message. */
+
+struct mqmsg
+{
+ FAR struct mqmsg *next; /* Forward link to next message */
+ uint8_t type; /* (Used to manage allocations) */
+ uint8_t priority; /* priority of message */
+#if MQ_MAX_BYTES < 256
+ uint8_t msglen; /* Message data length */
+#else
+ uint16_t msglen; /* Message data length */
+#endif
+ uint8_t mail[MQ_MAX_BYTES]; /* Message data */
+};
+
+typedef struct mqmsg mqmsg_t;
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/* This is a list of all opened message queues */
+
+extern sq_queue_t g_msgqueues;
+
+/* The g_msgfree is a list of messages that are available for general use.
+ * The number of messages in this list is a system configuration item.
+ */
+
+extern sq_queue_t g_msgfree;
+
+/* The g_msgfreeInt is a list of messages that are reserved for use by
+ * interrupt handlers.
+ */
+
+extern sq_queue_t g_msgfreeirq;
+
+/* The g_desfree data structure is a list of message descriptors available
+ * to the operating system for general use. The number of messages in the
+ * pool is a constant.
+ */
+
+extern sq_queue_t g_desfree;
+
+/****************************************************************************
+ * Global Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/* Functions defined in mq_initialize.c ************************************/
+
+EXTERN void weak_function mq_initialize(void);
+EXTERN void mq_desblockalloc(void);
+
+EXTERN mqd_t mq_descreate(FAR _TCB* mtcb, FAR msgq_t* msgq, int oflags);
+EXTERN FAR msgq_t *mq_findnamed(const char *mq_name);
+EXTERN void mq_msgfree(FAR mqmsg_t *mqmsg);
+EXTERN void mq_msgqfree(FAR msgq_t *msgq);
+
+/* mq_waitirq.c ************************************************************/
+
+EXTERN void mq_waitirq(FAR _TCB *wtcb, int errcode);
+
+/* mq_rcvinternal.c ********************************************************/
+
+EXTERN int mq_verifyreceive(mqd_t mqdes, void *msg, size_t msglen);
+EXTERN FAR mqmsg_t *mq_waitreceive(mqd_t mqdes);
+EXTERN ssize_t mq_doreceive(mqd_t mqdes, mqmsg_t *mqmsg, void *ubuffer,
+ int *prio);
+
+/* mq_sndinternal.c ********************************************************/
+
+EXTERN int mq_verifysend(mqd_t mqdes, const void *msg, size_t msglen,
+ int prio);
+EXTERN FAR mqmsg_t *mq_msgalloc(void);
+EXTERN int mq_waitsend(mqd_t mqdes);
+EXTERN int mq_dosend(mqd_t mqdes, FAR mqmsg_t *mqmsg, const void *msg,
+ size_t msglen, int prio);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONFIG_MQ_MAXMSGSIZE > 0 */
+#endif /* __SCHED_MQ_INTERNAL_H */
+
diff --git a/nuttx/sched/mq_msgfree.c b/nuttx/sched/mq_msgfree.c
new file mode 100644
index 000000000..91322fbf3
--- /dev/null
+++ b/nuttx/sched/mq_msgfree.c
@@ -0,0 +1,134 @@
+/************************************************************************
+ * sched/mq_msgfree.c
+ *
+ * Copyright (C) 2007 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 <queue.h>
+#include <nuttx/arch.h>
+#include "os_internal.h"
+#include "mq_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: mq_msgfree
+ *
+ * Description:
+ * The mq_msgfree function will return a message to the free pool of
+ * messages if it was a pre-allocated message. If the message was
+ * allocated dynamically it will be deallocated.
+ *
+ * Inputs:
+ * mqmsg - message to free
+ *
+ * Return Value:
+ * None
+ *
+ ************************************************************************/
+
+void mq_msgfree(FAR mqmsg_t *mqmsg)
+{
+ irqstate_t saved_state;
+
+ /* If this is a generally available pre-allocated message,
+ * then just put it back in the free list.
+ */
+
+ if (mqmsg->type == MQ_ALLOC_FIXED)
+ {
+ /* Make sure we avoid concurrent access to the free
+ * list from interrupt handlers.
+ */
+
+ saved_state = irqsave();
+ sq_addlast((FAR sq_entry_t*)mqmsg, &g_msgfree);
+ irqrestore(saved_state);
+ }
+
+ /* If this is a message pre-allocated for interrupts,
+ * then put it back in the correct free list.
+ */
+
+ else if (mqmsg->type == MQ_ALLOC_IRQ)
+ {
+ /* Make sure we avoid concurrent access to the free
+ * list from interrupt handlers.
+ */
+
+ saved_state = irqsave();
+ sq_addlast((FAR sq_entry_t*)mqmsg, &g_msgfreeirq);
+ irqrestore(saved_state);
+ }
+
+ /* Otherwise, deallocate it. Note: interrupt handlers
+ * will never deallocate messages because they will not
+ * received them.
+ */
+
+ else if (mqmsg->type == MQ_ALLOC_DYN)
+ {
+ sched_free(mqmsg);
+ }
+ else
+ {
+ PANIC(OSERR_BADMSGTYPE);
+ }
+}
diff --git a/nuttx/sched/mq_msgqfree.c b/nuttx/sched/mq_msgqfree.c
new file mode 100644
index 000000000..d7d87db3d
--- /dev/null
+++ b/nuttx/sched/mq_msgqfree.c
@@ -0,0 +1,108 @@
+/************************************************************************
+ * sched/mq_msgqfree.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+#include <nuttx/kmalloc.h>
+#include "mq_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: mq_msgqfree
+ *
+ * Description:
+ * This function deallocates an initialized message queue
+ * structure. First, it deallocates all of the queued
+ * messages in the message Q. It is assumed that this
+ * message is fully unlinked and closed so that not thread
+ * will attempt access it while it is being deleted.
+ *
+ * Inputs:
+ * msgq - Named essage queue to be freed
+ *
+ * Return Value:
+ * None
+ *
+ ************************************************************************/
+
+void mq_msgqfree(FAR msgq_t *msgq)
+{
+ FAR mqmsg_t *curr;
+ FAR mqmsg_t *next;
+
+ /* Deallocate any stranded messages in the message queue. */
+
+ curr = (FAR mqmsg_t*)msgq->msglist.head;
+ while (curr)
+ {
+ /* Deallocate the message structure. */
+
+ next = curr->next;
+ mq_msgfree(curr);
+ curr = next;
+ }
+
+ /* Then deallocate the message queue itself */
+
+ sched_free(msgq);
+}
diff --git a/nuttx/sched/mq_notify.c b/nuttx/sched/mq_notify.c
new file mode 100644
index 000000000..589bee312
--- /dev/null
+++ b/nuttx/sched/mq_notify.c
@@ -0,0 +1,211 @@
+/************************************************************************
+ * sched/mq_notify.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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 <signal.h>
+#include <mqueue.h>
+#include <sched.h>
+#include <errno.h>
+
+#include "os_internal.h"
+#include "mq_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: mq_notify
+ *
+ * Description:
+ * If "notification" is not NULL, this function connects the task with
+ * the message queue such that the specified signal will be sent to the
+ * task whenever the message changes from empty to non-empty. Only one
+ * notification can be attached to a message queue.
+ *
+ * If "notification" is NULL, the attached notification is detached (if
+ * it was held by the calling task) and the queue is available to attach
+ * another notification.
+ *
+ * When the notification is sent to the registered process, its
+ * registration will be removed. The message queue will then be
+ * available for registration.
+ *
+ * Parameters:
+ * mqdes - Message queue descriptor
+ * notification - Real-time signal structure containing:
+ * sigev_notify - Should be SIGEV_SIGNAL (but actually ignored)
+ * sigev_signo - The signo to use for the notification
+ * sigev_value - Value associated with the signal
+ *
+ * Return Value:
+ * On success mq_notify() returns 0; on error, -1 is returned, with
+ * errno set to indicate the error.
+ *
+ * EBADF The descriptor specified in mqdes is invalid.
+ * EBUSY Another process has already registered to receive notification
+ * for this message queue.
+ * EINVAL sevp->sigev_notify is not one of the permitted values; or
+ * sevp->sigev_notify is SIGEV_SIGNAL and sevp->sigev_signo is not a
+ * valid signal number.
+ * ENOMEM
+ * Insufficient memory.
+ *
+ * Assumptions:
+ *
+ * POSIX Compatibility:
+ * int mq_notify(mqd_t mqdes, const struct sigevent *notification);
+ *
+ * The notification will be sent to the registered task even if another
+ * task is waiting for the message queue to become non-empty. This is
+ * inconsistent with the POSIX specification which says, "If a process
+ * has registered for notification of message a arrival at a message
+ * queue and some process is blocked in mq_receive() waiting to receive
+ * a message when a message arrives at the queue, the arriving message
+ * message shall satisfy mq_receive()... The resulting behavior is as if
+ * the message queue remains empty, and no notification shall be sent."
+ *
+ ************************************************************************/
+
+int mq_notify(mqd_t mqdes, const struct sigevent *notification)
+{
+ _TCB *rtcb;
+ msgq_t *msgq;
+ int errval;
+
+ /* Was a valid message queue descriptor provided? */
+
+ if (!mqdes)
+ {
+ /* No.. return EBADF */
+
+ errval = EBADF;
+ goto errout;
+ }
+
+ /* Get a pointer to the message queue */
+
+ sched_lock();
+ msgq = mqdes->msgq;
+
+ /* Get the current process ID */
+
+ rtcb = (_TCB*)g_readytorun.head;
+
+ /* Is there already a notification attached */
+
+ if (!msgq->ntmqdes)
+ {
+ /* No... Have we been asked to establish one? */
+
+ if (notification)
+ {
+ /* Yes... Was a valid signal number supplied? */
+
+ if (!GOOD_SIGNO(notification->sigev_signo))
+ {
+ /* No... Return EINVAL */
+
+ errval = EINVAL;
+ goto errout;
+ }
+
+ /* Yes... Assign it to the current task. */
+
+ msgq->ntvalue.sival_ptr = notification->sigev_value.sival_ptr;
+ msgq->ntsigno = notification->sigev_signo;
+ msgq->ntpid = rtcb->pid;
+ msgq->ntmqdes = mqdes;
+ }
+ }
+
+ /* Yes... a notification is attached. Does this task own it?
+ * Is it trying to remove it?
+ */
+
+ else if ((msgq->ntpid != rtcb->pid) || (notification))
+ {
+ /* This thread does not own the notification OR it is
+ * not trying to remove it. Return EBUSY.
+ */
+
+ errval = EBUSY;
+ goto errout;
+ }
+ else
+ {
+ /* Yes, the notification belongs to this thread. Allow the
+ * thread to detach the notification.
+ */
+
+ msgq->ntpid = INVALID_PROCESS_ID;
+ msgq->ntsigno = 0;
+ msgq->ntvalue.sival_ptr = NULL;
+ msgq->ntmqdes = NULL;
+ }
+
+ sched_unlock();
+ return OK;
+
+errout:
+ set_errno(errval);
+ sched_unlock();
+ return ERROR;
+}
diff --git a/nuttx/sched/mq_open.c b/nuttx/sched/mq_open.c
new file mode 100644
index 000000000..5e1b9b137
--- /dev/null
+++ b/nuttx/sched/mq_open.c
@@ -0,0 +1,236 @@
+/****************************************************************************
+ * sched/mq_open.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <mqueue.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+
+#include "os_internal.h"
+#include "mq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_open
+ *
+ * Description:
+ * This function establish a connection between a named message queue and
+ * the calling task. After a successful call of mq_open(), the task can
+ * reference the message queue using the address returned by the call. The
+ * message queue remains usable until it is closed by a successful call to
+ * mq_close().
+ *
+ * Parameters:
+ * mq_name - Name of the queue to open
+ * oflags - open flags
+ * Optional parameters. When the O_CREAT flag is specified, two optional
+ * parameters are expected:
+ *
+ * 1. mode_t mode (ignored), and
+ * 2. struct mq_attr *attr. The mq_maxmsg attribute
+ * is used at the time that the message queue is
+ * created to determine the maximum number of
+ * messages that may be placed in the message queue.
+ *
+ * Return Value:
+ * A message queue descriptor or -1 (ERROR)
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+mqd_t mq_open(const char *mq_name, int oflags, ...)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ FAR msgq_t *msgq;
+ mqd_t mqdes = NULL;
+ va_list arg; /* Points to each un-named argument */
+ mode_t mode; /* MQ creation mode parameter (ignored) */
+ struct mq_attr *attr; /* MQ creation attributes */
+ int namelen; /* Length of MQ name */
+
+ /* Make sure that a non-NULL name is supplied */
+
+ if (mq_name)
+ {
+ sched_lock();
+ namelen = strlen(mq_name);
+ if (namelen > 0)
+ {
+ /* See if the message queue already exists */
+
+ msgq = mq_findnamed(mq_name);
+ if (msgq)
+ {
+ /* It does. Check if the caller wanted to create a new
+ * message queue with this name (i.e., O_CREAT|O_EXCL)
+ */
+
+ if ((oflags & O_CREAT) == 0 || (oflags & O_EXCL) == 0)
+ {
+ /* Create a message queue descriptor for the TCB */
+
+ mqdes = mq_descreate(rtcb, msgq, oflags);
+ if (mqdes)
+ {
+ /* Allow a new connection to the message queue */
+
+ msgq->nconnect++;
+ }
+ }
+ }
+
+ /* It doesn't exist. Should we create one? */
+
+ else if ((oflags & O_CREAT) != 0)
+ {
+ /* Allocate memory for the new message queue. The size to
+ * allocate is the size of the msgq_t header plus the size
+ * of the message queue name+1.
+ */
+
+ msgq = (FAR msgq_t*)kzalloc(SIZEOF_MQ_HEADER + namelen + 1);
+ if (msgq)
+ {
+ /* Create a message queue descriptor for the TCB */
+
+ mqdes = mq_descreate(rtcb, msgq, oflags);
+ if (mqdes)
+ {
+ /* Set up to get the optional arguments needed to create
+ * a message queue.
+ */
+
+ va_start(arg, oflags);
+ mode = va_arg(arg, mode_t);
+ attr = va_arg(arg, struct mq_attr*);
+
+ /* Initialize the new named message queue */
+
+ sq_init(&msgq->msglist);
+ if (attr)
+ {
+ msgq->maxmsgs = (int16_t)attr->mq_maxmsg;
+ if (attr->mq_msgsize <= MQ_MAX_BYTES)
+ {
+ msgq->maxmsgsize = (int16_t)attr->mq_msgsize;
+ }
+ else
+ {
+ msgq->maxmsgsize = MQ_MAX_BYTES;
+ }
+ }
+ else
+ {
+ msgq->maxmsgs = MQ_MAX_MSGS;
+ msgq->maxmsgsize = MQ_MAX_BYTES;
+ }
+
+ msgq->nconnect = 1;
+#ifndef CONFIG_DISABLE_SIGNALS
+ msgq->ntpid = INVALID_PROCESS_ID;
+#endif
+ strcpy(msgq->name, mq_name);
+
+ /* Add the new message queue to the list of
+ * message queues
+ */
+
+ sq_addlast((FAR sq_entry_t*)msgq, &g_msgqueues);
+
+ /* Clean-up variable argument stuff */
+
+ va_end(arg);
+ }
+ else
+ {
+ /* Deallocate the msgq structure. Since it is
+ * uninitialized, mq_deallocate() is not used.
+ */
+
+ sched_free(msgq);
+ }
+ }
+ }
+ }
+
+ sched_unlock();
+ }
+
+ if (mqdes == NULL)
+ {
+ return (mqd_t)ERROR;
+ }
+ else
+ {
+ return mqdes;
+ }
+}
diff --git a/nuttx/sched/mq_rcvinternal.c b/nuttx/sched/mq_rcvinternal.c
new file mode 100644
index 000000000..e80685e87
--- /dev/null
+++ b/nuttx/sched/mq_rcvinternal.c
@@ -0,0 +1,312 @@
+/****************************************************************************
+ * sched/mq_rcvinternal.c
+ *
+ * Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <mqueue.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "mq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_verifyreceive
+ *
+ * Description:
+ * This is internal, common logic shared by both mq_receive and
+ * mq_timedreceive. This function verifies the input parameters that are
+ * common to both functions.
+ *
+ * Parameters:
+ * mqdes - Message Queue Descriptor
+ * msg - Buffer to receive the message
+ * msglen - Size of the buffer in bytes
+ *
+ * Return Value:
+ * One success, 0 (OK) is returned. On failure, -1 (ERROR) is returned and
+ * the errno is set appropriately:
+ *
+ * EPERM Message queue opened not opened for reading.
+ * EMSGSIZE 'msglen' was less than the maxmsgsize attribute of the message
+ * queue.
+ * EINVAL Invalid 'msg' or 'mqdes'
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int mq_verifyreceive(mqd_t mqdes, void *msg, size_t msglen)
+{
+ /* Verify the input parameters */
+
+ if (!msg || !mqdes)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ if ((mqdes->oflags & O_RDOK) == 0)
+ {
+ set_errno(EPERM);
+ return ERROR;
+ }
+
+ if (msglen < (size_t)mqdes->msgq->maxmsgsize)
+ {
+ set_errno(EMSGSIZE);
+ return ERROR;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: mq_waitreceive
+ *
+ * Description:
+ * This is internal, common logic shared by both mq_receive and
+ * mq_timedreceive. This function waits for a message to be received on
+ * the specified message queue, removes the message from the queue, and
+ * returns it.
+ *
+ * Parameters:
+ * mqdes - Message queue descriptor
+ *
+ * Return Value:
+ * On success, a reference to the received message. If the wait was
+ * interrupted by a signal or a timeout, then the errno will be set
+ * appropriately and NULL will be returned.
+ *
+ * Assumptions:
+ * - The caller has provided all validity checking of the input parameters
+ * using mq_verifyreceive.
+ * - Interrupts should be disabled throughout this call. This is necessary
+ * because messages can be sent from interrupt level processing.
+ * - For mq_timedreceive, setting of the timer and this wait must be atomic.
+ *
+ ****************************************************************************/
+
+FAR mqmsg_t *mq_waitreceive(mqd_t mqdes)
+{
+ FAR _TCB *rtcb;
+ FAR msgq_t *msgq;
+ FAR mqmsg_t *rcvmsg;
+
+ /* Get a pointer to the message queue */
+
+ msgq = mqdes->msgq;
+
+ /* Get the message from the head of the queue */
+
+ while ((rcvmsg = (FAR mqmsg_t*)sq_remfirst(&msgq->msglist)) == NULL)
+ {
+ /* The queue is empty! Should we block until there the above condition
+ * has been satisfied?
+ */
+
+ if ((mqdes->oflags & O_NONBLOCK) == 0)
+ {
+ /* Yes.. Block and try again */
+
+ rtcb = (FAR _TCB*)g_readytorun.head;
+ rtcb->msgwaitq = msgq;
+ msgq->nwaitnotempty++;
+
+ set_errno(OK);
+ up_block_task(rtcb, TSTATE_WAIT_MQNOTEMPTY);
+
+ /* When we resume at this point, either (1) the message queue
+ * is no longer empty, or (2) the wait has been interrupted by
+ * a signal. We can detect the latter case be examining the
+ * errno value (should be either EINTR or ETIMEDOUT).
+ */
+
+ if (get_errno() != OK)
+ {
+ break;
+ }
+ }
+ else
+ {
+ /* The queue was empty, and the O_NONBLOCK flag was set for the
+ * message queue description referred to by 'mqdes'.
+ */
+
+ set_errno(EAGAIN);
+ break;
+ }
+ }
+
+ /* If we got message, then decrement the number of messages in
+ * the queue while we are still in the critical section
+ */
+
+ if (rcvmsg)
+ {
+ msgq->nmsgs--;
+ }
+
+ return rcvmsg;
+}
+
+/****************************************************************************
+ * Name: mq_doreceive
+ *
+ * Description:
+ * This is internal, common logic shared by both mq_receive and
+ * mq_timedreceive. This function accepts the message obtained by
+ * mq_waitmsg, provides the message content to the user, notifies any
+ * threads that were waiting for the message queue to become non-full,
+ * and disposes of the message structure
+ *
+ * Parameters:
+ * mqdes - Message queue descriptor
+ * mqmsg - The message obtained by mq_waitmsg()
+ * ubuffer - The address of the user provided buffer to receive the message
+ * prio - The user-provided location to return the message priority.
+ *
+ * Return Value:
+ * Returns the length of the received message. This function does not fail.
+ *
+ * Assumptions:
+ * - The caller has provided all validity checking of the input parameters
+ * using mq_verifyreceive.
+ * - The user buffer, ubuffer, is known to be large enough to accept the
+ * largest message that an be sent on this message queue
+ * - Pre-emption should be disabled throughout this call.
+ *
+ ****************************************************************************/
+
+ssize_t mq_doreceive(mqd_t mqdes, mqmsg_t *mqmsg, void *ubuffer, int *prio)
+{
+ FAR _TCB *btcb;
+ irqstate_t saved_state;
+ FAR msgq_t *msgq;
+ ssize_t rcvmsglen;
+
+ /* Get the length of the message (also the return value) */
+
+ rcvmsglen = mqmsg->msglen;
+
+ /* Copy the message into the caller's buffer */
+
+ memcpy(ubuffer, (const void*)mqmsg->mail, rcvmsglen);
+
+ /* Copy the message priority as well (if a buffer is provided) */
+
+ if (prio)
+ {
+ *prio = mqmsg->priority;
+ }
+
+ /* We are done with the message. Deallocate it now. */
+
+ mq_msgfree(mqmsg);
+
+ /* Check if any tasks are waiting for the MQ not full event. */
+
+ msgq = mqdes->msgq;
+ if (msgq->nwaitnotfull > 0)
+ {
+ /* Find the highest priority task that is waiting for
+ * this queue to be not-full in g_waitingformqnotfull list.
+ * This must be performed in a critical section because
+ * messages can be sent from interrupt handlers.
+ */
+
+ saved_state = irqsave();
+ for (btcb = (FAR _TCB*)g_waitingformqnotfull.head;
+ btcb && btcb->msgwaitq != msgq;
+ btcb = btcb->flink);
+
+ /* If one was found, unblock it. NOTE: There is a race
+ * condition here: the queue might be full again by the
+ * time the task is unblocked
+ */
+
+ if (!btcb)
+ {
+ PANIC(OSERR_MQNOTFULLCOUNT);
+ }
+ else
+ {
+ btcb->msgwaitq = NULL;
+ msgq->nwaitnotfull--;
+ up_unblock_task(btcb);
+ }
+
+ irqrestore(saved_state);
+ }
+
+ /* Return the length of the message transferred to the user buffer */
+
+ return rcvmsglen;
+}
diff --git a/nuttx/sched/mq_receive.c b/nuttx/sched/mq_receive.c
new file mode 100644
index 000000000..760433446
--- /dev/null
+++ b/nuttx/sched/mq_receive.c
@@ -0,0 +1,166 @@
+/************************************************************************
+ * sched/mq_receive.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <mqueue.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "mq_internal.h"
+
+/************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: mq_receive
+ *
+ * Description:
+ * This function receives the oldest of the highest priority messages
+ * from the message queue specified by "mqdes." If the size of the
+ * buffer in bytes (msglen) is less than the "mq_msgsize" attribute of
+ * the message queue, mq_receive will return an error. Otherwise, the
+ * selected message is removed from the queue and copied to "msg."
+ *
+ * If the message queue is empty and O_NONBLOCK was not set,
+ * mq_receive() will block until a message is added to the message
+ * queue. If more than one task is waiting to receive a message, only
+ * the task with the highest priority that has waited the longest will
+ * be unblocked.
+ *
+ * If the queue is empty and O_NONBLOCK is set, ERROR will be returned.
+ *
+ * Parameters:
+ * mqdes - Message Queue Descriptor
+ * msg - Buffer to receive the message
+ * msglen - Size of the buffer in bytes
+ * prio - If not NULL, the location to store message priority.
+ *
+ * Return Value:
+ * One success, the length of the selected message in bytes is returned.
+ * On failure, -1 (ERROR) is returned and the errno is set appropriately:
+ *
+ * EAGAIN The queue was empty, and the O_NONBLOCK flag was set
+ * for the message queue description referred to by 'mqdes'.
+ * EPERM Message queue opened not opened for reading.
+ * EMSGSIZE 'msglen' was less than the maxmsgsize attribute of the
+ * message queue.
+ * EINTR The call was interrupted by a signal handler.
+ * EINVAL Invalid 'msg' or 'mqdes'
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+ssize_t mq_receive(mqd_t mqdes, void *msg, size_t msglen, int *prio)
+{
+ FAR mqmsg_t *mqmsg;
+ irqstate_t saved_state;
+ ssize_t ret = ERROR;
+
+ DEBUGASSERT(up_interrupt_context() == false);
+
+ /* Verify the input parameters and, in case of an error, set
+ * errno appropriately.
+ */
+
+ if (mq_verifyreceive(mqdes, msg, msglen) != OK)
+ {
+ return ERROR;
+ }
+
+ /* Get the next mesage from the message queue. We will disable
+ * pre-emption until we have completed the message received. This
+ * is not too bad because if the receipt takes a long time, it will
+ * be because we are blocked waiting for a message and pre-emption
+ * will be re-enabled while we are blocked
+ */
+
+ sched_lock();
+
+ /* Furthermore, mq_waitreceive() expects to have interrupts disabled
+ * because messages can be sent from interrupt level.
+ */
+
+ saved_state = irqsave();
+
+ /* Get the message from the message queue */
+
+ mqmsg = mq_waitreceive(mqdes);
+ irqrestore(saved_state);
+
+ /* Check if we got a message from the message queue. We might
+ * not have a message if:
+ *
+ * - The message queue is empty and O_NONBLOCK is set in the mqdes
+ * - The wait was interrupted by a signal
+ */
+
+ if (mqmsg)
+ {
+ ret = mq_doreceive(mqdes, mqmsg, msg, prio);
+ }
+
+ sched_unlock();
+ return ret;
+}
diff --git a/nuttx/sched/mq_send.c b/nuttx/sched/mq_send.c
new file mode 100644
index 000000000..40628e924
--- /dev/null
+++ b/nuttx/sched/mq_send.c
@@ -0,0 +1,184 @@
+/****************************************************************************
+ * sched/mq_send.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <mqueue.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "mq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_send
+ *
+ * Description:
+ * This function adds the specificied message (msg) to the message queue
+ * (mqdes). The "msglen" parameter specifies the length of the message
+ * in bytes pointed to by "msg." This length must not exceed the maximum
+ * message length from the mq_getattr().
+ *
+ * If the message queue is not full, mq_send() place the message in the
+ * message queue at the position indicated by the "prio" argrument.
+ * Messages with higher priority will be inserted before lower priority
+ * messages. The value of "prio" must not exceed MQ_PRIO_MAX.
+ *
+ * If the specified message queue is full and O_NONBLOCK is not set in the
+ * message queue, then mq_send() will block until space becomes available
+ * to the queue the message.
+ *
+ * If the message queue is full and O_NONBLOCK is set, the message is not
+ * queued and ERROR is returned.
+ *
+ * Parameters:
+ * mqdes - Message queue descriptor
+ * msg - Message to send
+ * msglen - The length of the message in bytes
+ * prio - The priority of the message
+ *
+ * Return Value:
+ * On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
+ * is returned, with errno set to indicate the error:
+ *
+ * EAGAIN The queue was empty, and the O_NONBLOCK flag was set for the
+ * message queue description referred to by mqdes.
+ * EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
+ * EPERM Message queue opened not opened for writing.
+ * EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
+ * message queue.
+ * EINTR The call was interrupted by a signal handler.
+ *
+ * Assumptions/restrictions:
+ *
+ ****************************************************************************/
+
+int mq_send(mqd_t mqdes, const void *msg, size_t msglen, int prio)
+{
+ FAR msgq_t *msgq;
+ FAR mqmsg_t *mqmsg = NULL;
+ irqstate_t saved_state;
+ int ret = ERROR;
+
+ /* Verify the input parameters -- setting errno appropriately
+ * on any failures to verify.
+ */
+
+ if (mq_verifysend(mqdes, msg, msglen, prio) != OK)
+ {
+ return ERROR;
+ }
+
+ /* Get a pointer to the message queue */
+
+ sched_lock();
+ msgq = mqdes->msgq;
+
+ /* Allocate a message structure:
+ * - Immediately if we are called from an interrupt handler.
+ * - Immediately if the message queue is not full, or
+ * - After successfully waiting for the message queue to become
+ * non-FULL. This would fail with EAGAIN, EINTR, or ETIMEOUT.
+ */
+
+ saved_state = irqsave();
+ if (up_interrupt_context() || /* In an interrupt handler */
+ msgq->nmsgs < msgq->maxmsgs || /* OR Message queue not full */
+ mq_waitsend(mqdes) == OK) /* OR Successfully waited for mq not full */
+ {
+ /* Allocate the message */
+
+ irqrestore(saved_state);
+ mqmsg = mq_msgalloc();
+ }
+ else
+ {
+ /* We cannot send the message (and didn't even try to allocate it)
+ * because:
+ * - We are not in an interrupt handler AND
+ * - The message queue is full AND
+ * - When we tried waiting, the wait was unsuccessful.
+ */
+
+ irqrestore(saved_state);
+ }
+
+ /* Check if we were able to get a message structure -- this can fail
+ * either because we cannot send the message (and didn't bother trying
+ * to allocate it) or because the allocation failed.
+ */
+
+ if (mqmsg)
+ {
+ /* Yes, perform the message send. */
+
+ ret = mq_dosend(mqdes, mqmsg, msg, msglen, prio);
+ }
+
+ sched_unlock();
+ return ret;
+}
+
diff --git a/nuttx/sched/mq_sndinternal.c b/nuttx/sched/mq_sndinternal.c
new file mode 100644
index 000000000..51f898875
--- /dev/null
+++ b/nuttx/sched/mq_sndinternal.c
@@ -0,0 +1,455 @@
+/****************************************************************************
+ * sched/mq_send.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <mqueue.h>
+#include <string.h>
+#include <errno.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#ifndef CONFIG_DISABLE_SIGNALS
+# include "sig_internal.h"
+#endif
+#include "mq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_verifysend
+ *
+ * Description:
+ * This is internal, common logic shared by both mq_send and mq_timesend.
+ * This function verifies the input parameters that are common to both
+ * functions.
+ *
+ * Parameters:
+ * mqdes - Message queue descriptor
+ * msg - Message to send
+ * msglen - The length of the message in bytes
+ * prio - The priority of the message
+ *
+ * Return Value:
+ * One success, 0 (OK) is returned. On failure, -1 (ERROR) is returned and
+ * the errno is set appropriately:
+ *
+ * EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
+ * EPERM Message queue opened not opened for writing.
+ * EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
+ * message queue.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int mq_verifysend(mqd_t mqdes, const void *msg, size_t msglen, int prio)
+{
+ /* Verify the input parameters */
+
+ if (!msg || !mqdes || prio < 0 || prio > MQ_PRIO_MAX)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ if ((mqdes->oflags & O_WROK) == 0)
+ {
+ set_errno(EPERM);
+ return ERROR;
+ }
+
+ if (msglen < 0 || msglen > (size_t)mqdes->msgq->maxmsgsize)
+ {
+ set_errno(EMSGSIZE);
+ return ERROR;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: mq_msgalloc
+ *
+ * Description:
+ * The mq_msgalloc function will get a free message for use by the
+ * operating system. The message will be allocated from the g_msgfree
+ * list.
+ *
+ * If the list is empty AND the message is NOT being allocated from the
+ * interrupt level, then the message will be allocated. If a message
+ * cannot be obtained, the operating system is dead and therefore cannot
+ * continue.
+ *
+ * If the list is empty AND the message IS being allocated from the
+ * interrupt level. This function will attempt to get a message from
+ * the g_msgfreeirq list. If this is unsuccessful, the calling interrupt
+ * handler will be notified.
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * A reference to the allocated msg structure. On a failure to allocate,
+ * this function PANICs.
+ *
+ ****************************************************************************/
+
+FAR mqmsg_t *mq_msgalloc(void)
+{
+ FAR mqmsg_t *mqmsg;
+ irqstate_t saved_state;
+
+ /* If we were called from an interrupt handler, then try to get the message
+ * from generally available list of messages. If this fails, then try the
+ * list of messages reserved for interrupt handlers
+ */
+
+ if (up_interrupt_context())
+ {
+ /* Try the general free list */
+
+ mqmsg = (FAR mqmsg_t*)sq_remfirst(&g_msgfree);
+ if (!mqmsg)
+ {
+ /* Try the free list reserved for interrupt handlers */
+
+ mqmsg = (FAR mqmsg_t*)sq_remfirst(&g_msgfreeirq);
+ }
+ }
+
+ /* We were not called from an interrupt handler. */
+
+ else
+ {
+ /* Try to get the message from the generally available free list.
+ * Disable interrupts -- we might be called from an interrupt handler.
+ */
+
+ saved_state = irqsave();
+ mqmsg = (FAR mqmsg_t*)sq_remfirst(&g_msgfree);
+ irqrestore(saved_state);
+
+ /* If we cannot a message from the free list, then we will have to allocate one. */
+
+ if (!mqmsg)
+ {
+ mqmsg = (FAR mqmsg_t *)kmalloc((sizeof (mqmsg_t)));
+
+ /* Check if we got an allocated message */
+
+ if (mqmsg)
+ {
+ mqmsg->type = MQ_ALLOC_DYN;
+ }
+
+ /* No? We are dead */
+
+ else
+ {
+ sdbg("Out of messages\n");
+ PANIC((uint32_t)OSERR_OUTOFMESSAGES);
+ }
+ }
+ }
+
+ return mqmsg;
+}
+
+/****************************************************************************
+ * Name: mq_waitsend
+ *
+ * Description:
+ * This is internal, common logic shared by both mq_send and mq_timesend.
+ * This function waits until the message queue is not full.
+ *
+ * Parameters:
+ * mqdes - Message queue descriptor
+ *
+ * Return Value:
+ * On success, mq_send() returns 0 (OK); on error, -1 (ERROR) is
+ * returned, with errno set to indicate the error:
+ *
+ * EAGAIN The queue was empty, and the O_NONBLOCK flag was set for the
+ * message queue description referred to by mqdes.
+ * EINTR The call was interrupted by a signal handler.
+ * ETIMEOUT A timeout expired before the message queue became non-full
+ * (mq_timedsend only).
+ *
+ * Assumptions/restrictions:
+ * - The caller has verified the input parameters using mq_verifysend().
+ * - Interrupts are disabled.
+ *
+ ****************************************************************************/
+
+int mq_waitsend(mqd_t mqdes)
+{
+ FAR _TCB *rtcb;
+ FAR msgq_t *msgq;
+
+ /* Get a pointer to the message queue */
+
+ msgq = mqdes->msgq;
+
+ /* Verify that the queue is indeed full as the caller thinks */
+
+ if (msgq->nmsgs >= msgq->maxmsgs)
+ {
+ /* Should we block until there is sufficient space in the
+ * message queue?
+ */
+
+ if ((mqdes->oflags & O_NONBLOCK) != 0)
+ {
+ /* No... We will return an error to the caller. */
+
+ set_errno(EAGAIN);
+ return ERROR;
+ }
+
+ /* Yes... We will not return control until the message queue is
+ * available or we receive a signal or at timout occurs.
+ */
+
+ else
+ {
+ /* Loop until there are fewer than max allowable messages in the
+ * receiving message queue
+ */
+
+ while (msgq->nmsgs >= msgq->maxmsgs)
+ {
+ /* Block until the message queue is no longer full.
+ * When we are unblocked, we will try again
+ */
+
+ rtcb = (FAR _TCB*)g_readytorun.head;
+ rtcb->msgwaitq = msgq;
+ msgq->nwaitnotfull++;
+
+ set_errno(OK);
+ up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
+
+ /* When we resume at this point, either (1) the message queue
+ * is no longer empty, or (2) the wait has been interrupted by
+ * a signal. We can detect the latter case be examining the
+ * errno value (should be EINTR or ETIMEOUT).
+ */
+
+ if (get_errno() != OK)
+ {
+ return ERROR;
+ }
+ }
+ }
+ }
+ return OK;
+}
+
+/****************************************************************************
+ * Name: mq_dosend
+ *
+ * Description:
+ * This is internal, common logic shared by both mq_send and mq_timesend.
+ * This function adds the specificied message (msg) to the message queue
+ * (mqdes). Then it notifies any tasks that were waiting for message
+ * queue notifications setup by mq_notify. And, finally, it awakens any
+ * tasks that were waiting for the message not empty event.
+ *
+ * Parameters:
+ * mqdes - Message queue descriptor
+ * msg - Message to send
+ * msglen - The length of the message in bytes
+ * prio - The priority of the message
+ *
+ * Return Value:
+ * This function always returns OK.
+ *
+ * Assumptions/restrictions:
+ *
+ ****************************************************************************/
+
+int mq_dosend(mqd_t mqdes, FAR mqmsg_t *mqmsg, const void *msg, size_t msglen, int prio)
+{
+ FAR _TCB *btcb;
+ FAR msgq_t *msgq;
+ FAR mqmsg_t *next;
+ FAR mqmsg_t *prev;
+ irqstate_t saved_state;
+
+ /* Get a pointer to the message queue */
+
+ sched_lock();
+ msgq = mqdes->msgq;
+
+ /* Construct the message header info */
+
+ mqmsg->priority = prio;
+ mqmsg->msglen = msglen;
+
+ /* Copy the message data into the message */
+
+ memcpy((void*)mqmsg->mail, (const void*)msg, msglen);
+
+ /* Insert the new message in the message queue */
+
+ saved_state = irqsave();
+
+ /* Search the message list to find the location to insert the new
+ * message. Each is list is maintained in ascending priority order.
+ */
+
+ for (prev = NULL, next = (FAR mqmsg_t*)msgq->msglist.head;
+ next && prio <= next->priority;
+ prev = next, next = next->next);
+
+ /* Add the message at the right place */
+
+ if (prev)
+ {
+ sq_addafter((FAR sq_entry_t*)prev, (FAR sq_entry_t*)mqmsg,
+ &msgq->msglist);
+ }
+ else
+ {
+ sq_addfirst((FAR sq_entry_t*)mqmsg, &msgq->msglist);
+ }
+
+ /* Increment the count of messages in the queue */
+
+ msgq->nmsgs++;
+ irqrestore(saved_state);
+
+ /* Check if we need to notify any tasks that are attached to the
+ * message queue
+ */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ if (msgq->ntmqdes)
+ {
+ /* Remove the message notification data from the message queue. */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ union sigval value = msgq->ntvalue;
+#else
+ void *sival_ptr = msgq->ntvalue.sival_ptr;
+#endif
+ int signo = msgq->ntsigno;
+ int pid = msgq->ntpid;
+
+ /* Detach the notification */
+
+ msgq->ntpid = INVALID_PROCESS_ID;
+ msgq->ntsigno = 0;
+ msgq->ntvalue.sival_int = 0;
+ msgq->ntmqdes = NULL;
+
+ /* Queue the signal -- What if this returns an error? */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ sig_mqnotempty(pid, signo, value);
+#else
+ sig_mqnotempty(pid, signo, sival_ptr);
+#endif
+ }
+#endif
+
+ /* Check if any tasks are waiting for the MQ not empty event. */
+
+ saved_state = irqsave();
+ if (msgq->nwaitnotempty > 0)
+ {
+ /* Find the highest priority task that is waiting for
+ * this queue to be non-empty in g_waitingformqnotempty
+ * list. sched_lock() should give us sufficent protection since
+ * interrupts should never cause a change in this list
+ */
+
+ for (btcb = (FAR _TCB*)g_waitingformqnotempty.head;
+ btcb && btcb->msgwaitq != msgq;
+ btcb = btcb->flink);
+
+ /* If one was found, unblock it */
+
+ if (!btcb)
+ {
+ PANIC(OSERR_MQNONEMPTYCOUNT);
+ }
+ else
+ {
+ btcb->msgwaitq = NULL;
+ msgq->nwaitnotempty--;
+ up_unblock_task(btcb);
+ }
+ }
+
+ irqrestore(saved_state);
+ sched_unlock();
+ return OK;
+}
+
diff --git a/nuttx/sched/mq_timedreceive.c b/nuttx/sched/mq_timedreceive.c
new file mode 100644
index 000000000..0df904830
--- /dev/null
+++ b/nuttx/sched/mq_timedreceive.c
@@ -0,0 +1,303 @@
+/****************************************************************************
+ * sched/mq_timedreceive.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+#include <mqueue.h>
+#include <wdog.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "clock_internal.h"
+#include "mq_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_rcvtimeout
+ *
+ * Description:
+ * This function is called if the timeout elapses before the message queue
+ * becomes non-empty.
+ *
+ * Parameters:
+ * argc - the number of arguments (should be 1)
+ * pid - the task ID of the task to wakeup
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void mq_rcvtimeout(int argc, uint32_t pid)
+{
+ FAR _TCB *wtcb;
+ irqstate_t saved_state;
+
+ /* Disable interrupts. This is necessary because an interrupt handler may
+ * attempt to send a message while we are doing this.
+ */
+
+ saved_state = irqsave();
+
+ /* Get the TCB associated with this pid. It is possible that task may no
+ * longer be active when this watchdog goes off.
+ */
+
+ wtcb = sched_gettcb((pid_t)pid);
+
+ /* It is also possible that an interrupt/context switch beat us to the
+ * punch and already changed the task's state.
+ */
+
+ if (wtcb && wtcb->task_state == TSTATE_WAIT_MQNOTEMPTY)
+ {
+ /* Restart with task with a timeout error */
+
+ mq_waitirq(wtcb, ETIMEDOUT);
+ }
+
+ /* Interrupts may now be re-enabled. */
+
+ irqrestore(saved_state);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_timedreceive
+ *
+ * Description:
+ * This function receives the oldest of the highest priority messages from
+ * the message queue specified by "mqdes." If the size of the buffer in
+ * bytes (msglen) is less than the "mq_msgsize" attribute of the message
+ * queue, mq_timedreceive will return an error. Otherwise, the selected
+ * message is removed from the queue and copied to "msg."
+ *
+ * If the message queue is empty and O_NONBLOCK was not set,
+ * mq_timedreceive() will block until a message is added to the message
+ * queue (or until a timeout occurs). If more than one task is waiting
+ * to receive a message, only the task with the highest priority that has
+ * waited the longest will be unblocked.
+ *
+ * mq_timedreceive() behaves just like mq_receive(), except that if the
+ * queue is empty and the O_NONBLOCK flag is not enabled for the message
+ * queue description, then abstime points to a structure which specifies a
+ * ceiling on the time for which the call will block. This ceiling is an
+ * absolute timeout in seconds and nanoseconds since the Epoch (midnight
+ * on the morning of 1 January 1970).
+ *
+ * If no message is available, and the timeout has already expired by the
+ * time of the call, mq_timedreceive() returns immediately.
+ *
+ * Parameters:
+ * mqdes - Message Queue Descriptor
+ * msg - Buffer to receive the message
+ * msglen - Size of the buffer in bytes
+ * prio - If not NULL, the location to store message priority.
+ * abstime - the absolute time to wait until a timeout is declared.
+ *
+ * Return Value:
+ * One success, the length of the selected message in bytes is returned.
+ * On failure, -1 (ERROR) is returned and the errno is set appropriately:
+ *
+ * EAGAIN The queue was empty, and the O_NONBLOCK flag was set
+ * for the message queue description referred to by 'mqdes'.
+ * EPERM Message queue opened not opened for reading.
+ * EMSGSIZE 'msglen' was less than the maxmsgsize attribute of the
+ * message queue.
+ * EINTR The call was interrupted by a signal handler.
+ * EINVAL Invalid 'msg' or 'mqdes' or 'abstime'
+ * ETIMEDOUT The call timed out before a message could be transferred.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+ssize_t mq_timedreceive(mqd_t mqdes, void *msg, size_t msglen,
+ int *prio, const struct timespec *abstime)
+{
+ WDOG_ID wdog;
+ FAR mqmsg_t *mqmsg;
+ irqstate_t saved_state;
+ int ret = ERROR;
+
+ DEBUGASSERT(up_interrupt_context() == false);
+
+ /* Verify the input parameters and, in case of an error, set
+ * errno appropriately.
+ */
+
+ if (mq_verifyreceive(mqdes, msg, msglen) != OK)
+ {
+ return ERROR;
+ }
+
+ if (!abstime || abstime->tv_sec < 0 || abstime->tv_nsec > 1000000000)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ /* Create a watchdog. We will not actually need this watchdog
+ * unless the queue is not empty, but we will reserve it up front
+ * before we enter the following critical section.
+ */
+
+ wdog = wd_create();
+ if (!wdog)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ /* Get the next mesage from the message queue. We will disable
+ * pre-emption until we have completed the message received. This
+ * is not too bad because if the receipt takes a long time, it will
+ * be because we are blocked waiting for a message and pre-emption
+ * will be re-enabled while we are blocked
+ */
+
+ sched_lock();
+
+ /* Furthermore, mq_waitreceive() expects to have interrupts disabled
+ * because messages can be sent from interrupt level.
+ */
+
+ saved_state = irqsave();
+
+ /* Check if the message queue is empty. If it is NOT empty, then we
+ * will not need to start timer.
+ */
+
+ if (mqdes->msgq->msglist.head == NULL)
+ {
+ int ticks;
+
+ /* Convert the timespec to clock ticks. We must have interrupts
+ * disabled here so that this time stays valid until the wait begins.
+ */
+
+ int result = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
+
+ /* If the time has already expired and the message queue is empty,
+ * return immediately.
+ */
+
+ if (result == OK && ticks <= 0)
+ {
+ result = ETIMEDOUT;
+ }
+
+ /* Handle any time-related errors */
+
+ if (result != OK)
+ {
+ set_errno(result);
+ irqrestore(saved_state);
+ sched_unlock();
+ wd_delete(wdog);
+ return ERROR;
+ }
+
+ /* Start the watchdog */
+
+ wd_start(wdog, ticks, (wdentry_t)mq_rcvtimeout, 1, getpid());
+ }
+
+ /* Get the message from the message queue */
+
+ mqmsg = mq_waitreceive(mqdes);
+
+ /* Stop the watchdog timer (this is not harmful in the case where
+ * it was never started)
+ */
+
+ wd_cancel(wdog);
+
+ /* We can now restore interrupts */
+
+ irqrestore(saved_state);
+
+ /* Check if we got a message from the message queue. We might
+ * not have a message if:
+ *
+ * - The message queue is empty and O_NONBLOCK is set in the mqdes
+ * - The wait was interrupted by a signal
+ * - The watchdog timeout expired
+ */
+
+ if (mqmsg)
+ {
+ ret = mq_doreceive(mqdes, mqmsg, msg, prio);
+ }
+
+ sched_unlock();
+ wd_delete(wdog);
+ return ret;
+}
diff --git a/nuttx/sched/mq_timedsend.c b/nuttx/sched/mq_timedsend.c
new file mode 100644
index 000000000..745cc6272
--- /dev/null
+++ b/nuttx/sched/mq_timedsend.c
@@ -0,0 +1,319 @@
+/****************************************************************************
+ * sched/mq_timedsend.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <mqueue.h>
+#include <wdog.h>
+#include <errno.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "clock_internal.h"
+#include "os_internal.h"
+#include "mq_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_sndtimeout
+ *
+ * Description:
+ * This function is called if the timeout elapses before the message queue
+ * becomes non-full.
+ *
+ * Parameters:
+ * argc - the number of arguments (should be 1)
+ * pid - the task ID of the task to wakeup
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void mq_sndtimeout(int argc, uint32_t pid)
+{
+ FAR _TCB *wtcb;
+ irqstate_t saved_state;
+
+ /* Disable interrupts. This is necessary because an interrupt handler may
+ * attempt to send a message while we are doing this.
+ */
+
+ saved_state = irqsave();
+
+ /* Get the TCB associated with this pid. It is possible that task may no
+ * longer be active when this watchdog goes off.
+ */
+
+ wtcb = sched_gettcb((pid_t)pid);
+
+ /* It is also possible that an interrupt/context switch beat us to the
+ * punch and already changed the task's state.
+ */
+
+ if (wtcb && wtcb->task_state == TSTATE_WAIT_MQNOTFULL)
+ {
+ /* Restart with task with a timeout error */
+
+ mq_waitirq(wtcb, ETIMEDOUT);
+ }
+
+ /* Interrupts may now be re-enabled. */
+
+ irqrestore(saved_state);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mq_send
+ *
+ * Description:
+ * This function adds the specificied message (msg) to the message queue
+ * (mqdes). The "msglen" parameter specifies the length of the message
+ * in bytes pointed to by "msg." This length must not exceed the maximum
+ * message length from the mq_getattr().
+ *
+ * If the message queue is not full, mq_timedsend() place the message in the
+ * message queue at the position indicated by the "prio" argrument.
+ * Messages with higher priority will be inserted before lower priority
+ * messages. The value of "prio" must not exceed MQ_PRIO_MAX.
+ *
+ * If the specified message queue is full and O_NONBLOCK is not set in the
+ * message queue, then mq_timedsend() will block until space becomes available
+ * to the queue the message or a timeout occurs.
+ *
+ * mq_timedsend() behaves just like mq_send(), except that if the queue
+ * is full and the O_NONBLOCK flag is not enabled for the message queue
+ * description, then abstime points to a structure which specifies a
+ * ceiling on the time for which the call will block. This ceiling is an
+ * absolute timeout in seconds and nanoseconds since the Epoch (midnight
+ * on the morning of 1 January 1970).
+ *
+ * If the message queue is full, and the timeout has already expired by
+ * the time of the call, mq_timedsend() returns immediately.
+ *
+ * Parameters:
+ * mqdes - Message queue descriptor
+ * msg - Message to send
+ * msglen - The length of the message in bytes
+ * prio - The priority of the message
+ * abstime - the absolute time to wait until a timeout is decleared
+ *
+ * Return Value:
+ * On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
+ * is returned, with errno set to indicate the error:
+ *
+ * EAGAIN The queue was empty, and the O_NONBLOCK flag was set for the
+ * message queue description referred to by mqdes.
+ * EINVAL Either msg or mqdes is NULL or the value of prio is invalid.
+ * EPERM Message queue opened not opened for writing.
+ * EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
+ * message queue.
+ * EINTR The call was interrupted by a signal handler.
+ *
+ * Assumptions/restrictions:
+ *
+ ****************************************************************************/
+
+int mq_timedsend(mqd_t mqdes, const char *msg, size_t msglen, int prio,
+ const struct timespec *abstime)
+{
+ WDOG_ID wdog;
+ FAR msgq_t *msgq;
+ FAR mqmsg_t *mqmsg = NULL;
+ irqstate_t saved_state;
+ int ret = ERROR;
+
+ DEBUGASSERT(up_interrupt_context() == false);
+
+ /* Verify the input parameters -- setting errno appropriately
+ * on any failures to verify.
+ */
+
+ if (mq_verifysend(mqdes, msg, msglen, prio) != OK)
+ {
+ return ERROR;
+ }
+
+ if (!abstime || abstime->tv_sec < 0 || abstime->tv_nsec > 1000000000)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ /* Get a pointer to the message queue */
+
+ msgq = mqdes->msgq;
+
+ /* Create a watchdog. We will not actually need this watchdog
+ * unless the queue is full, but we will reserve it up front
+ * before we enter the following critical section.
+ */
+
+ wdog = wd_create();
+ if (!wdog)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ /* Allocate a message structure:
+ * - If we are called from an interrupt handler, or
+ * - If the message queue is not full, or
+ */
+
+ sched_lock();
+ saved_state = irqsave();
+ if (up_interrupt_context() || /* In an interrupt handler */
+ msgq->nmsgs < msgq->maxmsgs) /* OR Message queue not full */
+ {
+ /* Allocate the message */
+
+ irqrestore(saved_state);
+ mqmsg = mq_msgalloc();
+ }
+ else
+ {
+ int ticks;
+
+ /* We are not in an interupt handler and the message queue is full.
+ * set up a timed wait for the message queue to become non-full.
+ *
+ * Convert the timespec to clock ticks. We must have interrupts
+ * disabled here so that this time stays valid until the wait begins.
+ */
+
+ int result = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
+
+ /* If the time has already expired and the message queue is empty,
+ * return immediately.
+ */
+
+ if (result == OK && ticks <= 0)
+ {
+ result = ETIMEDOUT;
+ }
+
+ /* Handle any time-related errors */
+
+ if (result != OK)
+ {
+ set_errno(result);
+ ret = ERROR;
+ }
+
+ /* Start the watchdog and begin the wait for MQ not full */
+
+ if (result == OK)
+ {
+ /* Start the watchdog */
+
+ wd_start(wdog, ticks, (wdentry_t)mq_sndtimeout, 1, getpid());
+
+ /* And wait for the message queue to be non-empty */
+
+ ret = mq_waitsend(mqdes);
+
+ /* This may return with an error and errno set to either EINTR
+ * or ETIMEOUT. Cancel the watchdog timer in any event.
+ */
+
+ wd_cancel(wdog);
+ }
+
+ /* That is the end of the atomic operations */
+
+ irqrestore(saved_state);
+
+ /* If any of the above failed, set the errno. Otherwise, there should
+ * be space for another message in the message queue. NOW we can allocate
+ * the message structure.
+ */
+
+ if (ret == OK)
+ {
+ mqmsg = mq_msgalloc();
+ }
+ }
+
+ /* Check if we were able to get a message structure -- this can fail
+ * either because we cannot send the message (and didn't bother trying
+ * to allocate it) or because the allocation failed.
+ */
+
+ if (mqmsg)
+ {
+ /* Yes, peform the message send. */
+
+ ret = mq_dosend(mqdes, mqmsg, msg, msglen, prio);
+ }
+
+ sched_unlock();
+ wd_delete(wdog);
+ return ret;
+}
+
diff --git a/nuttx/sched/mq_unlink.c b/nuttx/sched/mq_unlink.c
new file mode 100644
index 000000000..1fa25dfa8
--- /dev/null
+++ b/nuttx/sched/mq_unlink.c
@@ -0,0 +1,146 @@
+/************************************************************************
+ * sched.mq_unlink.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <mqueue.h>
+#include <sched.h>
+
+#include "os_internal.h"
+#include "mq_internal.h"
+
+/************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: mq_unlink
+ *
+ * Description:
+ * This function removes the message queue named by "mq_name." If one
+ * or more tasks have the message queue open when mq_unlink() is called,
+ * removal of the message queue is postponed until all references to the
+ * message queue have been closed.
+ *
+ * Parameters:
+ * mq_name - Name of the message queue
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+int mq_unlink(const char *mq_name)
+{
+ FAR msgq_t *msgq;
+ irqstate_t saved_state;
+ int ret = ERROR;
+
+ /* Verify the input values */
+
+ if (mq_name)
+ {
+ sched_lock();
+
+ /* Find the named message queue */
+
+ msgq = mq_findnamed(mq_name);
+ if (msgq)
+ {
+ /* If it is no longer connected, then we can just
+ * discard the message queue now.
+ */
+
+ if (!msgq->nconnect)
+ {
+ /* Remove the message queue from the list of all
+ * message queues
+ */
+
+ saved_state = irqsave();
+ (void)sq_rem((FAR sq_entry_t*)msgq, &g_msgqueues);
+ irqrestore(saved_state);
+
+ /* Then deallocate it (and any messages left in it) */
+
+ mq_msgqfree(msgq);
+ }
+
+ /* If the message queue is still connected to a message descriptor,
+ * then mark it for deletion when the last message descriptor is
+ * closed
+ */
+
+ else
+ {
+ msgq->unlinked = true;
+ }
+
+ ret = OK;
+ }
+
+ sched_unlock();
+ }
+
+ return ret;
+}
+
diff --git a/nuttx/sched/mq_waitirq.c b/nuttx/sched/mq_waitirq.c
new file mode 100644
index 000000000..94a15df3c
--- /dev/null
+++ b/nuttx/sched/mq_waitirq.c
@@ -0,0 +1,172 @@
+/****************************************************************************
+ * sched/mq_waitirq.c
+ *
+ * Copyright (C) 2007-2009, 2011 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 <sched.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mqueue.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_waitirq
+ *
+ * Description:
+ * This function is called when a signal or a timeout is received by a
+ * task that is waiting on a message queue -- either for a queue to
+ * becoming not full (on mq_send) or not empty (on mq_receive).
+ *
+ * Parameters:
+ * wtcb - A pointer to the TCB of the task that is waiting on a message
+ * queue, but has received a signal instead.
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void mq_waitirq(FAR _TCB *wtcb, int errcode)
+{
+ FAR msgq_t *msgq;
+ irqstate_t saved_state;
+
+ /* Disable interrupts. This is necessary because an interrupt handler may
+ * attempt to send a message while we are doing this.
+ */
+
+ saved_state = irqsave();
+
+ /* It is possible that an interrupt/context switch beat us to the punch and
+ * already changed the task's state. NOTE: The operations within the if
+ * are safe because interrupts are always disabled with the msgwaitq,
+ * nwaitnotempty, and nwaitnotfull fields are modified.
+ */
+
+ if (wtcb->task_state == TSTATE_WAIT_MQNOTEMPTY ||
+ wtcb->task_state == TSTATE_WAIT_MQNOTFULL)
+ {
+ /* Get the message queue associated with the waiter from the TCB */
+
+ msgq = wtcb->msgwaitq;
+#ifdef CONFIG_DEBUG
+ if (!msgq)
+ {
+ /* In these states there must always be an associated message queue */
+
+ PANIC((uint32_t)OSERR_MQNOWAITER);
+ }
+#endif
+ wtcb->msgwaitq = NULL;
+
+ /* Decrement the count of waiters and cancel the wait */
+
+ if (wtcb->task_state == TSTATE_WAIT_MQNOTEMPTY)
+ {
+#ifdef CONFIG_DEBUG
+ if (msgq->nwaitnotempty <= 0)
+ {
+ /* This state, there should be a positive, non-zero waiter
+ * count.
+ */
+
+ PANIC((uint32_t)OSERR_MQNONEMPTYCOUNT);
+
+ }
+#endif
+ msgq->nwaitnotempty--;
+ }
+ else
+ {
+#ifdef CONFIG_DEBUG
+ if (msgq->nwaitnotfull <= 0)
+ {
+ /* This state, there should be a positive, non-zero waiter
+ * count.
+ */
+
+ PANIC((uint32_t)OSERR_MQNOTFULLCOUNT);
+
+ }
+#endif
+ msgq->nwaitnotfull--;
+ }
+
+ /* Mark the errno value for the thread. */
+
+ wtcb->pterrno = errcode;
+
+ /* Restart the task. */
+
+ up_unblock_task(wtcb);
+ }
+
+ /* Interrupts may now be enabled. */
+
+ irqrestore(saved_state);
+}
+
diff --git a/nuttx/sched/on_exit.c b/nuttx/sched/on_exit.c
new file mode 100644
index 000000000..5b8be5cd1
--- /dev/null
+++ b/nuttx/sched/on_exit.c
@@ -0,0 +1,171 @@
+/****************************************************************************
+ * sched/on_exit.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/fs/fs.h>
+
+#include "os_internal.h"
+
+#ifdef CONFIG_SCHED_ONEXIT
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: on_exit
+ *
+ * Description:
+ * Registers a function to be called at program exit.
+ * The on_exit() function registers the given function to be called
+ * at normal process termination, whether via exit or via return from
+ * the program's main(). The function is passed the status argument
+ * given to the last call to exit and the arg argument from on_exit().
+ *
+ * NOTE 1: This function comes from SunOS 4, but is also present in
+ * libc4, libc5 and glibc. It no longer occurs in Solaris (SunOS 5).
+ * Avoid this function, and use the standard atexit() instead.
+ *
+ * NOTE 2: CONFIG_SCHED_ONEXIT must be defined to enable this function
+ *
+ * Limitiations in the current implementation:
+ *
+ * 1. Only a single on_exit function can be registered unless
+ * CONFIG_SCHED_ONEXIT_MAX defines a larger number.
+ * 2. on_exit functions are not inherited when a new task is
+ * created.
+ *
+ * Parameters:
+ * func - A pointer to the function to be called when the task exits.
+ * arg - An argument that will be provided to the on_exit() function when
+ * the task exits.
+ *
+ * Return Value:
+ * Zero on success. Non-zero on failure.
+ *
+ ****************************************************************************/
+
+int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
+{
+#if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1
+ _TCB *tcb = (_TCB*)g_readytorun.head;
+ int index;
+ int ret = ERROR;
+
+ /* The following must be atomic */
+
+ if (func)
+ {
+ sched_lock();
+
+ /* Search for the first available slot. on_exit() functions are registered
+ * from lower to higher arry indices; they must be called in the reverse
+ * order of registration when task exists, i.e., from higher to lower
+ * indices.
+ */
+
+ available = -1;
+ for (index = 0; index < CONFIG_SCHED_ONEXIT_MAX; index++)
+ {
+ if (!tcb->onexitfunc[index])
+ {
+ tcb->onexitfunc[index] = func;
+ tcb->onexitarg[index] = arg;
+ ret = OK;
+ break;
+ }
+ }
+
+ sched_unlock();
+ }
+
+ return ret;
+#else
+ _TCB *tcb = (_TCB*)g_readytorun.head;
+ int ret = ERROR;
+
+ /* The following must be atomic */
+
+ sched_lock();
+ if (func && !tcb->onexitfunc)
+ {
+ tcb->onexitfunc = func;
+ tcb->onexitarg = arg;
+ ret = OK;
+ }
+
+ sched_unlock();
+ return ret;
+#endif
+}
+
+#endif /* CONFIG_SCHED_ONEXIT */
+
+
diff --git a/nuttx/sched/os_bringup.c b/nuttx/sched/os_bringup.c
new file mode 100644
index 000000000..ec6152891
--- /dev/null
+++ b/nuttx/sched/os_bringup.c
@@ -0,0 +1,194 @@
+/****************************************************************************
+ * sched/os_bringup.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * With extensions by:
+ *
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * 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 <sched.h>
+#include <debug.h>
+
+#include <nuttx/init.h>
+#include <nuttx/wqueue.h>
+
+#include "os_internal.h"
+#ifdef CONFIG_PAGING
+# include "pg_internal.h"
+#endif
+#ifdef CONFIG_SCHED_WORKQUEUE
+# include "work_internal.h"
+#endif
+#ifdef CONFIG_BUILTIN_APP_START
+# include "apps/apps.h"
+#endif
+#ifdef CONFIG_NUTTX_KERNEL
+# include "arch/board/user_map.h"
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If NuttX is built as a separately compiled module, then the the header
+ * file should contain the address of the user module entry point. If not
+ * then the default entry point is user_start.
+ */
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: os_bringup
+ *
+ * Description:
+ * Start all initial system tasks. This does the "system bring-up" after
+ * the conclusion of basic OS initialization. These initial system tasks
+ * may include:
+ *
+ * - pg_worker: The page-fault worker thread (only if CONFIG_PAGING is
+ * defined.
+ * - work_thread: The work thread. This general thread can be used to
+ * perform most any kind of queued work. Its primary
+ * function is to serve as the "bottom half" of device
+ * drivers.
+ *
+ * And the main application entry point. This may be one of two different
+ * symbols:
+ *
+ * - USER_ENTRYPOINT: This is the default entry point used for all of the
+ * example code in apps/examples.
+ * - CONFIG_BUILTIN_APP_START: The system can also be configured to start
+ * custom applications at however CONFIG_BUILTIN_APP_START
+ * is defined in the NuttX start-up file.
+ *
+ ****************************************************************************/
+
+int os_bringup(void)
+{
+#ifdef CONFIG_BUILTIN_APP_START
+ static const char *argv[3] = {NULL, "init", NULL};
+#endif
+ int init_taskid;
+
+ /* Start the page fill worker kernel thread that will resolve page faults.
+ * This should always be the first thread started because it may have to
+ * resolve page faults in other threads
+ */
+
+#ifdef CONFIG_PAGING
+ svdbg("Starting paging thread\n");
+
+ g_pgworker = KERNEL_THREAD("pgfill", CONFIG_PAGING_DEFPRIO,
+ CONFIG_PAGING_STACKSIZE,
+ (main_t)pg_worker, (const char **)NULL);
+ ASSERT(g_pgworker != ERROR);
+#endif
+
+ /* Start the worker thread that will serve as the device driver "bottom-
+ * half" and will perform misc garbage clean-up.
+ */
+
+#ifdef CONFIG_SCHED_WORKQUEUE
+ svdbg("Starting worker thread\n");
+
+ g_work[HPWORK].pid = KERNEL_THREAD("work0", CONFIG_SCHED_WORKPRIORITY,
+ CONFIG_SCHED_WORKSTACKSIZE,
+ (main_t)work_hpthread, (const char **)NULL);
+ ASSERT(g_work[HPWORK].pid != ERROR);
+
+ /* Start a lower priority worker thread for other, non-critical continuation
+ * tasks
+ */
+
+#ifdef CONFIG_SCHED_LPWORK
+ svdbg("Starting worker thread\n");
+
+ g_work[LPWORK].pid = KERNEL_THREAD("work1", CONFIG_SCHED_LPWORKPRIORITY,
+ CONFIG_SCHED_LPWORKSTACKSIZE,
+ (main_t)work_lpthread, (const char **)NULL);
+ ASSERT(g_work[LPWORK].pid != ERROR);
+#endif
+#endif
+
+ /* Once the operating system has been initialized, the system must be
+ * started by spawning the user init thread of execution. This is the
+ * first user-mode thead.
+ */
+
+ svdbg("Starting init thread\n");
+
+#ifdef CONFIG_BUILTIN_APP_START
+ /* Start the built-in named application, passing an "init" argument, so that
+ * application can distinguish different run-levels
+ */
+
+ init_taskid = exec_namedapp(CONFIG_BUILTIN_APP_START, argv);
+#else
+ /* Start the default application at CONFIG_USER_ENTRYPOINT() */
+
+ init_taskid = TASK_CREATE("init", SCHED_PRIORITY_DEFAULT,
+ CONFIG_USERMAIN_STACKSIZE,
+ (main_t)CONFIG_USER_ENTRYPOINT, (const char **)NULL);
+#endif
+ ASSERT(init_taskid != ERROR);
+ return OK;
+}
diff --git a/nuttx/sched/os_internal.h b/nuttx/sched/os_internal.h
new file mode 100644
index 000000000..13b8083cf
--- /dev/null
+++ b/nuttx/sched/os_internal.h
@@ -0,0 +1,306 @@
+/****************************************************************************
+ * sched/os_internal.h
+ *
+ * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_OS_INTERNAL_H
+#define __SCHED_OS_INTERNAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <queue.h>
+#include <sched.h>
+
+#include <nuttx/kmalloc.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* OS CRASH CODES: All must lie in the range 0-99 */
+
+enum os_crash_codes_e
+{
+ OSERR_NOERROR = 0, /* No error */
+ OSERR_NOTIMPLEMENTED, /* Feature is not implemented */
+ OSERR_INTERNAL, /* Internal logic error */
+ OSERR_UNEXPECTEDISR, /* Received unexpected interrupt */
+ OSERR_UNDEFINEDINSN, /* Undefined instruction */
+ OSERR_ERREXCEPTION, /* Other CPU-detected errors */
+ OSERR_OUTOFMEMORY, /* Insufficient memory */
+ OSERR_OUTOFMESSAGES, /* Out of messages */
+ OSERR_NOIDLETASK, /* There is no idle task */
+ OSERR_MQNONEMPTYCOUNT, /* Expected waiter for non-empty queue */
+ OSERR_MQNOTFULLCOUNT, /* Expected waiter for non-full queue */
+ OSERR_MQNOWAITER, /* Expected a queue for the waiter */
+ OSERR_BADWAITSEM, /* Already waiting for a semaphore */
+ OSERR_BADMSGTYPE, /* Tried to free a bad message type */
+ OSERR_FAILEDTOADDSIGNAL, /* Failed to add pending signal */
+ OSERR_FAILEDTOREMOVESIGNAL, /* Failed to remove pending signal */
+ OSERR_TIMEOUTNOTCB, /* Timed out, but not TCB registered */
+ OSERR_NOPENDINGSIGNAL, /* Expected a signal to be pending */
+ OSERR_BADDELETESTATE, /* Bad state in task deletion */
+ OSERR_WDOGNOTFOUND, /* Active watchdog not found */
+ OSERR_EXITFROMINTERRUPT, /* Interrupt code attempted to exit */
+ OSERR_BADUNBLOCKSTATE, /* Attempt to unblock from bad state */
+ OSERR_BADBLOCKSTATE, /* Attempt to block from bad state */
+ OSERR_BADREPRIORITIZESTATE /* Attempt to reprioritize in bad state or priority */
+};
+
+/* Special task IDS */
+
+#define NULL_TASK_PROCESS_ID 0
+#define INVALID_PROCESS_ID 0
+
+/* Although task IDs can take the (positive, non-zero)
+ * range of pid_t, the number of tasks that will be supported
+ * at any one time is (artificially) limited by the CONFIG_MAX_TASKS
+ * configuration setting. Limiting the number of tasks speeds certain
+ * OS functions (this is the only limitation in the number of
+ * tasks built into the design).
+ */
+
+#define MAX_TASKS_MASK (CONFIG_MAX_TASKS-1)
+#define PIDHASH(pid) ((pid) & MAX_TASKS_MASK)
+
+/* Stubs used when there are no file descriptors */
+
+#if CONFIG_NFILE_DESCRIPTORS <= 0 && CONFIG_NSOCKET_DESCRIPTORS <= 0
+# define sched_setupidlefiles(t) (OK)
+# define sched_setuptaskfiles(t) (OK)
+# define sched_setuppthreadfiles(t) (OK)
+# define sched_releasefiles(t) (OK)
+#endif
+
+/* One processor family supported by NuttX has a single, fixed hardware stack.
+ * That is the 8051 family. So for that family only, there is a variant form
+ * of kernel_thread() that does not take a stack size parameter. The following
+ * helper macro is provided to work around the ugliness of that exception.
+ */
+
+#ifndef CONFIG_CUSTOM_STACK
+# define KERNEL_THREAD(n,p,s,e,a) kernel_thread(n,p,s,e,a)
+#else
+# define KERNEL_THREAD(n,p,s,e,a) kernel_thread(n,p,e,a)
+#endif
+
+/* A more efficient ways to access the errno */
+
+#define SET_ERRNO(e) \
+ { _TCB *rtcb = _TCB*)g_readytorun.head; rtcb->pterrno = (e); }
+
+#define _SET_TCB_ERRNO(t,e) \
+ { (t)->pterrno = (e); }
+
+/****************************************************************************
+ * Public Type Definitions
+ ****************************************************************************/
+
+/* This structure defines the format of the hash table that
+ * is used to (1) determine if a task ID is unique, and (2)
+ * to map a process ID to its corresponding TCB.
+ */
+
+struct pidhash_s
+{
+ FAR _TCB *tcb;
+ pid_t pid;
+};
+
+typedef struct pidhash_s pidhash_t;
+
+/* This structure defines an element of the g_tasklisttable[].
+ * This table is used to map a task_state enumeration to the
+ * corresponding task list.
+ */
+
+struct tasklist_s
+{
+ DSEG volatile dq_queue_t *list; /* Pointer to the task list */
+ bool prioritized; /* true if the list is prioritized */
+};
+
+typedef struct tasklist_s tasklist_t;
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/* Declared in os_start.c ***************************************************/
+
+/* The state of a task is indicated both by the task_state field of the TCB
+ * and by a series of task lists. All of these tasks lists are declared
+ * below. Although it is not always necessary, most of these lists are
+ * prioritized so that common list handling logic can be used (only the
+ * g_readytorun, the g_pendingtasks, and the g_waitingforsemaphore lists need
+ * to be prioritized).
+ */
+
+/* This is the list of all tasks that are ready to run. The head of this
+ * list is the currently active task; the tail of this list is always the
+ * IDLE task.
+ */
+
+extern volatile dq_queue_t g_readytorun;
+
+/* This is the list of all tasks that are ready-to-run, but cannot be placed
+ * in the g_readytorun list because: (1) They are higher priority than the
+ * currently active task at the head of the g_readytorun list, and (2) the
+ * currently active task has disabled pre-emption.
+ */
+
+extern volatile dq_queue_t g_pendingtasks;
+
+/* This is the list of all tasks that are blocked waiting for a semaphore */
+
+extern volatile dq_queue_t g_waitingforsemaphore;
+
+/* This is the list of all tasks that are blocked waiting for a signal */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+extern volatile dq_queue_t g_waitingforsignal;
+#endif
+
+/* This is the list of all tasks that are blocked waiting for a message
+ * queue to become non-empty.
+ */
+
+#ifndef CONFIG_DISABLE_MQUEUE
+extern volatile dq_queue_t g_waitingformqnotempty;
+#endif
+
+/* This is the list of all tasks that are blocked waiting for a message
+ * queue to become non-full.
+ */
+
+#ifndef CONFIG_DISABLE_MQUEUE
+extern volatile dq_queue_t g_waitingformqnotfull;
+#endif
+
+/* This is the list of all tasks that are blocking waiting for a page fill */
+
+#ifdef CONFIG_PAGING
+extern volatile dq_queue_t g_waitingforfill;
+#endif
+
+/* This the list of all tasks that have been initialized, but not yet
+ * activated. NOTE: This is the only list that is not prioritized.
+ */
+
+extern volatile dq_queue_t g_inactivetasks;
+
+/* This is the list of dayed memory deallocations that need to be handled
+ * within the IDLE loop. These deallocations get queued by sched_free()
+ * if the OS attempts to deallocate memory while it is within an interrupt
+ * handler.
+ */
+
+extern volatile sq_queue_t g_delayeddeallocations;
+
+/* This is the value of the last process ID assigned to a task */
+
+extern volatile pid_t g_lastpid;
+
+/* The following hash table is used for two things:
+ *
+ * 1. This hash table greatly speeds the determination of a new unique
+ * process ID for a task, and
+ * 2. Is used to quickly map a process ID into a TCB.
+ *
+ * It has the side effects of using more memory and limiting the number
+ * of tasks to CONFIG_MAX_TASKS.
+ */
+
+extern pidhash_t g_pidhash[CONFIG_MAX_TASKS];
+
+/* This is a table of task lists. This table is indexed by the task state
+ * enumeration type (tstate_t) and provides a pointer to the associated
+ * static task list (if there is one) as well as a boolean indication as to
+ * if the list is an ordered list or not.
+ */
+
+extern const tasklist_t g_tasklisttable[NUM_TASK_STATES];
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+int os_bringup(void);
+void task_start(void);
+int task_schedsetup(FAR _TCB *tcb, int priority, start_t start,
+ main_t main);
+int task_argsetup(FAR _TCB *tcb, FAR const char *name, FAR const char *argv[]);
+void task_exithook(FAR _TCB *tcb, int status);
+int task_deletecurrent(void);
+#ifndef CONFIG_CUSTOM_STACK
+int kernel_thread(FAR const char *name, int priority, int stack_size,
+ main_t entry, FAR const char *argv[]);
+#else
+int kernel_thread(FAR const char *name, int priority, main_t entry,
+ FAR const char *argv[]);
+#endif
+bool sched_addreadytorun(FAR _TCB *rtrtcb);
+bool sched_removereadytorun(FAR _TCB *rtrtcb);
+bool sched_addprioritized(FAR _TCB *newTcb, DSEG dq_queue_t *list);
+bool sched_mergepending(void);
+void sched_addblocked(FAR _TCB *btcb, tstate_t task_state);
+void sched_removeblocked(FAR _TCB *btcb);
+int sched_setpriority(FAR _TCB *tcb, int sched_priority);
+#ifdef CONFIG_PRIORITY_INHERITANCE
+int sched_reprioritize(FAR _TCB *tcb, int sched_priority);
+#else
+# define sched_reprioritize(tcb,sched_priority) sched_setpriority(tcb,sched_priority)
+#endif
+FAR _TCB *sched_gettcb(pid_t pid);
+bool sched_verifytcb(FAR _TCB *tcb);
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+int sched_setupidlefiles(FAR _TCB *tcb);
+int sched_setuptaskfiles(FAR _TCB *tcb);
+int sched_setuppthreadfiles(FAR _TCB *tcb);
+#if CONFIG_NFILE_STREAMS > 0
+int sched_setupstreams(FAR _TCB *tcb);
+#endif
+int sched_releasefiles(FAR _TCB *tcb);
+#endif
+
+int sched_releasetcb(FAR _TCB *tcb);
+void sched_garbagecollection(void);
+
+#endif /* __SCHED_OS_INTERNAL_H */
diff --git a/nuttx/sched/os_start.c b/nuttx/sched/os_start.c
new file mode 100644
index 000000000..c0b16236d
--- /dev/null
+++ b/nuttx/sched/os_start.c
@@ -0,0 +1,466 @@
+/****************************************************************************
+ * sched/os_start.c
+ *
+ * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <debug.h>
+#include <string.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/compiler.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/net/net.h>
+#include <nuttx/lib.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/init.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+#include "wd_internal.h"
+#include "sem_internal.h"
+#ifndef CONFIG_DISABLE_MQUEUE
+# include "mq_internal.h"
+#endif
+#ifndef CONFIG_DISABLE_PTHREAD
+# include "pthread_internal.h"
+#endif
+#include "clock_internal.h"
+#include "timer_internal.h"
+#include "irq_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/* Task Lists ***************************************************************/
+/* The state of a task is indicated both by the task_state field of the TCB
+ * and by a series of task lists. All of these tasks lists are declared
+ * below. Although it is not always necessary, most of these lists are
+ * prioritized so that common list handling logic can be used (only the
+ * g_readytorun, the g_pendingtasks, and the g_waitingforsemaphore lists need
+ * to be prioritized).
+ */
+
+/* This is the list of all tasks that are ready to run. The head of this
+ * list is the currently active task; the tail of this list is always the
+ * IDLE task.
+ */
+
+volatile dq_queue_t g_readytorun;
+
+/* This is the list of all tasks that are ready-to-run, but cannot be placed
+ * in the g_readytorun list because: (1) They are higher priority than the
+ * currently active task at the head of the g_readytorun list, and (2) the
+ * currently active task has disabled pre-emption.
+ */
+
+volatile dq_queue_t g_pendingtasks;
+
+/* This is the list of all tasks that are blocked waiting for a semaphore */
+
+volatile dq_queue_t g_waitingforsemaphore;
+
+/* This is the list of all tasks that are blocked waiting for a signal */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+volatile dq_queue_t g_waitingforsignal;
+#endif
+
+/* This is the list of all tasks that are blocked waiting for a message
+ * queue to become non-empty.
+ */
+
+#ifndef CONFIG_DISABLE_MQUEUE
+volatile dq_queue_t g_waitingformqnotempty;
+#endif
+
+/* This is the list of all tasks that are blocked waiting for a message
+ * queue to become non-full.
+ */
+
+#ifndef CONFIG_DISABLE_MQUEUE
+volatile dq_queue_t g_waitingformqnotfull;
+#endif
+
+/* This is the list of all tasks that are blocking waiting for a page fill */
+
+#ifdef CONFIG_PAGING
+volatile dq_queue_t g_waitingforfill;
+#endif
+
+/* This the list of all tasks that have been initialized, but not yet
+ * activated. NOTE: This is the only list that is not prioritized.
+ */
+
+volatile dq_queue_t g_inactivetasks;
+
+/* This is the list of dayed memory deallocations that need to be handled
+ * within the IDLE loop. These deallocations get queued by sched_free()
+ * if the OS attempts to deallocate memory while it is within an interrupt
+ * handler.
+ */
+
+volatile sq_queue_t g_delayeddeallocations;
+
+/* This is the value of the last process ID assigned to a task */
+
+volatile pid_t g_lastpid;
+
+/* The following hash table is used for two things:
+ *
+ * 1. This hash table greatly speeds the determination of
+ * a new unique process ID for a task, and
+ * 2. Is used to quickly map a process ID into a TCB.
+ * It has the side effects of using more memory and limiting
+ *
+ * the number of tasks to CONFIG_MAX_TASKS.
+ */
+
+pidhash_t g_pidhash[CONFIG_MAX_TASKS];
+
+/* This is a table of task lists. This table is indexed by
+ * the task state enumeration type (tstate_t) and provides
+ * a pointer to the associated static task list (if there
+ * is one) as well as a boolean indication as to if the list
+ * is an ordered list or not.
+ */
+
+const tasklist_t g_tasklisttable[NUM_TASK_STATES] =
+{
+ { NULL, false }, /* TSTATE_TASK_INVALID */
+ { &g_pendingtasks, true }, /* TSTATE_TASK_PENDING */
+ { &g_readytorun, true }, /* TSTATE_TASK_READYTORUN */
+ { &g_readytorun, true }, /* TSTATE_TASK_RUNNING */
+ { &g_inactivetasks, false }, /* TSTATE_TASK_INACTIVE */
+ { &g_waitingforsemaphore, true } /* TSTATE_WAIT_SEM */
+#ifndef CONFIG_DISABLE_SIGNALS
+ ,
+ { &g_waitingforsignal, false } /* TSTATE_WAIT_SIG */
+#endif
+#ifndef CONFIG_DISABLE_MQUEUE
+ ,
+ { &g_waitingformqnotempty, true }, /* TSTATE_WAIT_MQNOTEMPTY */
+ { &g_waitingformqnotfull, true } /* TSTATE_WAIT_MQNOTFULL */
+#endif
+#ifdef CONFIG_PAGING
+ ,
+ { &g_waitingforfill, true } /* TSTATE_WAIT_PAGEFILL */
+#endif
+};
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+/* This is the task control block for this thread of execution. This thread
+ * of execution is the IDLE task. NOTE: the system boots into the IDLE
+ * task. The IDLE task spawns the user initialization task (user_start) and
+ * that user init task is responsible for bringing up the rest of the system
+ */
+
+static FAR _TCB g_idletcb;
+
+/* This is the name of the idle task */
+
+static FAR const char g_idlename[] = "Idle Task";
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: os_start
+ *
+ * Description:
+ * This function is called to initialize the operating system and to spawn
+ * the user initization thread of execution
+ *
+ ****************************************************************************/
+
+void os_start(void)
+{
+ int i;
+
+ slldbg("Entry\n");
+
+ /* Initialize all task lists */
+
+ dq_init(&g_readytorun);
+ dq_init(&g_pendingtasks);
+ dq_init(&g_waitingforsemaphore);
+#ifndef CONFIG_DISABLE_SIGNALS
+ dq_init(&g_waitingforsignal);
+#endif
+#ifndef CONFIG_DISABLE_MQUEUE
+ dq_init(&g_waitingformqnotfull);
+ dq_init(&g_waitingformqnotempty);
+#endif
+#ifdef CONFIG_PAGING
+ dq_init(&g_waitingforfill);
+#endif
+ dq_init(&g_inactivetasks);
+ sq_init(&g_delayeddeallocations);
+
+ /* Initialize the logic that determine unique process IDs. */
+
+ g_lastpid = 0;
+ for (i = 0; i < CONFIG_MAX_TASKS; i++)
+ {
+ g_pidhash[i].tcb = NULL;
+ g_pidhash[i].pid = INVALID_PROCESS_ID;
+ }
+
+ /* Assign the process ID of ZERO to the idle task */
+
+ g_pidhash[ PIDHASH(0)].tcb = &g_idletcb;
+ g_pidhash[ PIDHASH(0)].pid = 0;
+
+ /* Initialize a TCB for this thread of execution. NOTE: The default
+ * value for most components of the g_idletcb are zero. The entire
+ * structure is set to zero. Then only the (potentially) non-zero
+ * elements are initialized. NOTE: The idle task is the only task in
+ * that has pid == 0 and sched_priority == 0.
+ */
+
+ bzero((void*)&g_idletcb, sizeof(_TCB));
+ g_idletcb.task_state = TSTATE_TASK_RUNNING;
+ g_idletcb.entry.main = (main_t)os_start;
+
+#if CONFIG_TASK_NAME_SIZE > 0
+ strncpy(g_idletcb.name, g_idlename, CONFIG_TASK_NAME_SIZE-1);
+ g_idletcb.argv[0] = g_idletcb.name;
+#else
+ g_idletcb.argv[0] = (char*)g_idlename;
+#endif /* CONFIG_TASK_NAME_SIZE */
+
+ /* Then add the idle task's TCB to the head of the ready to run list */
+
+ dq_addfirst((FAR dq_entry_t*)&g_idletcb, (FAR dq_queue_t*)&g_readytorun);
+
+ /* Initialize the processor-specific portion of the TCB */
+
+ g_idletcb.flags = TCB_FLAG_TTYPE_KERNEL;
+ up_initial_state(&g_idletcb);
+
+ /* Initialize the semaphore facility(if in link). This has to be done
+ * very early because many subsystems depend upon fully functional
+ * semaphores.
+ */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (sem_initialize != NULL)
+#endif
+ {
+ sem_initialize();
+ }
+
+ /* Initialize the memory manager */
+
+#ifndef CONFIG_HEAP_BASE
+ {
+ FAR void *heap_start;
+ size_t heap_size;
+ up_allocate_heap(&heap_start, &heap_size);
+ kmm_initialize(heap_start, heap_size);
+ }
+#else
+ kmm_initialize((void*)CONFIG_HEAP_BASE, CONFIG_HEAP_SIZE);
+#endif
+
+ /* Initialize the interrupt handling subsystem (if included) */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (irq_initialize != NULL)
+#endif
+ {
+ irq_initialize();
+ }
+
+ /* Initialize the watchdog facility (if included in the link) */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (wd_initialize != NULL)
+#endif
+ {
+ wd_initialize();
+ }
+
+ /* Initialize the POSIX timer facility (if included in the link) */
+
+#ifndef CONFIG_DISABLE_CLOCK
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (clock_initialize != NULL)
+#endif
+ {
+ clock_initialize();
+ }
+#endif
+
+#ifndef CONFIG_DISABLE_POSIX_TIMERS
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (timer_initialize != NULL)
+#endif
+ {
+ timer_initialize();
+ }
+#endif
+
+ /* Initialize the signal facility (if in link) */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (sig_initialize != NULL)
+#endif
+ {
+ sig_initialize();
+ }
+#endif
+
+ /* Initialize the named message queue facility (if in link) */
+
+#ifndef CONFIG_DISABLE_MQUEUE
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (mq_initialize != NULL)
+#endif
+ {
+ mq_initialize();
+ }
+#endif
+
+ /* Initialize the thread-specific data facility (if in link) */
+
+#ifndef CONFIG_DISABLE_PTHREAD
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (pthread_initialize != NULL)
+#endif
+ {
+ pthread_initialize();
+ }
+#endif
+
+ /* Initialize the file system (needed to support device drivers) */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (fs_initialize != NULL)
+#endif
+ {
+ fs_initialize();
+ }
+#endif
+
+ /* Initialize the network system */
+
+#ifdef CONFIG_NET
+#if 0
+ if (net_initialize != NULL)
+#endif
+ {
+ net_initialize();
+ }
+#endif
+
+ /* The processor specific details of running the operating system
+ * will be handled here. Such things as setting up interrupt
+ * service routines and starting the clock are some of the things
+ * that are different for each processor and hardware platform.
+ */
+
+ up_initialize();
+
+ /* Initialize the C libraries (if included in the link). This
+ * is done last because the libraries may depend on the above.
+ */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (lib_initialize != NULL)
+#endif
+ {
+ lib_initialize();
+ }
+
+ /* Create stdout, stderr, stdin */
+
+ (void)sched_setupidlefiles(&g_idletcb);
+
+ /* Create initial tasks and bring-up the system */
+
+ (void)os_bringup();
+
+ /* When control is return to this point, the system is idle. */
+
+ sdbg("Beginning Idle Loop\n");
+ for (;;)
+ {
+ /* Perform garbage collection (if it is not being done by the worker
+ * thread). This cleans-up memory de-allocations that were queued
+ * because they could not be freed in that execution context (for
+ * example, if the memory was freed from an interrupt handler).
+ */
+
+#ifndef CONFIG_SCHED_WORKQUEUE
+ /* We must have exclusive access to the memory manager to do this
+ * BUT the idle task cannot wait on a semaphore. So we only do
+ * the cleanup now if we can get the semaphore -- this should be
+ * possible because if the IDLE thread is running, no other task is!
+ */
+
+ if (kmm_trysemaphore() == 0)
+ {
+ sched_garbagecollection();
+ kmm_givesemaphore();
+ }
+#endif
+
+ /* Perform any processor-specific idle state operations */
+
+ up_idle();
+ }
+}
diff --git a/nuttx/sched/pg_internal.h b/nuttx/sched/pg_internal.h
new file mode 100644
index 000000000..e7bafcd91
--- /dev/null
+++ b/nuttx/sched/pg_internal.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+ * sched/pg_internal.h
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_PG_INTERNAL_H
+#define __SCHED_PG_INTERNAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <queue.h>
+
+#ifdef CONFIG_PAGING
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/* Supply reasonable (but probably non-optimal) default settings if
+ * configuration items are omitted.
+ */
+
+#ifndef CONFIG_PAGING_DEFPRIO
+# define CONFIG_PAGING_DEFPRIO 50
+#endif
+
+#ifndef CONFIG_PAGING_WORKPERIOD
+# define CONFIG_PAGING_WORKPERIOD (500*1000) /* 1/2 second */
+#endif
+
+#ifndef CONFIG_PAGING_STACKSIZE
+# define CONFIG_PAGING_STACKSIZE CONFIG_IDLETHREAD_STACKSIZE
+#endif
+
+#ifdef CONFIG_DISABLE_SIGNALS
+# warning "Page fill support requires signals"
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY
+
+/* This is the task IDof the page fill worker thread. This value was set in
+ * os_start when the page fill worker thread was started.
+ */
+
+extern pid_t g_pgworker;
+
+/* The page fill worker thread maintains a static variable called g_pftcb.
+ * If no page fill is in progress, g_pftcb will be NULL. Otherwise, g_pftcb
+ * will point to the TCB of the task which is receiving the fill that is
+ * in progess.
+ *
+ * NOTE: I think that this is the only state in which a TCB does not reside
+ * in some list. Here is it in limbo, outside of the normally queuing while
+ * the page file is in progress. Where here, it will be marked with
+ * TSTATE_TASK_INVALID.
+ */
+
+extern FAR _TCB *g_pftcb;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pg_worker
+ *
+ * Description:
+ * This is the entry point of the worker thread that performs the actual
+ * page file.
+ *
+ * Input parameters:
+ * argc, argv (not used)
+ *
+ * Returned Value:
+ * Does not return
+ *
+ ****************************************************************************/
+
+int pg_worker(int argc, char *argv[]);
+
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_PAGING */
+#endif /* __SCHED_PG_INTERNAL_H */
diff --git a/nuttx/sched/pg_miss.c b/nuttx/sched/pg_miss.c
new file mode 100644
index 000000000..8a649a6d5
--- /dev/null
+++ b/nuttx/sched/pg_miss.c
@@ -0,0 +1,179 @@
+/****************************************************************************
+ * sched/pg_miss.c
+ *
+ * Copyright (C) 2010 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 <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/sched.h>
+#include <nuttx/page.h>
+
+#ifdef CONFIG_PAGING
+
+#include "os_internal.h"
+#include "pg_internal.h"
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pg_miss
+ *
+ * Description:
+ * This function is called from architecture-specific memory segmentation
+ * fault handling logic. This function will perform the following
+ * operations:
+ *
+ * 1) Sanity checking.
+ * - ASSERT if the currently executing task is the page fill worker
+ * thread. The page fill worker thread is how the the page fault
+ * is resolved and all logic associated with the page fill worker
+ * must be "locked" and always present in memory.
+ * - ASSERT if an interrupt was executing at the time of the exception.
+ * 2) Block the currently executing task.
+ * - Call up_block_task() to block the task at the head of the ready-
+ * to-run list. This should cause an interrupt level context switch
+ * to the next highest priority task.
+ * - The blocked task will be marked with state TSTATE_WAIT_PAGEFILL
+ * and will be retained in the g_waitingforfill prioritized task
+ * list.
+ * 3) Boost the page fill worker thread priority.
+ * - Check the priority of the task at the head of the g_waitingforfill
+ * list. If the priority of that task is higher than the current
+ * priority of the page fill worker thread, then boost the priority
+ * of the page fill worker thread to that priority.
+ * 4) Signal the page fill worker thread.
+ * - Is there a page fill pending? If not then signal the worker
+ * thread to start working on the queued page fill requests.
+ *
+ * Input Parameters:
+ * None - The head of the ready-to-run list is assumed to be task that
+ * caused the exception.
+ *
+ * Returned Value:
+ * None - Either this function function succeeds or an assertion occurs.
+ *
+ * Assumptions:
+ * - It is assumed that this function is called from the level of an
+ * exception handler and that all interrupts are disabled.
+ * - It is assumed that currently executing task (the one at the head of
+ * the ready-to-run list) is the one that cause the fault. This will
+ * always be true unless the page fault occurred in an interrupt handler.
+ * Interrupt handling logic must always be present and "locked" into
+ * memory.
+ * - As mentioned above, the task causing the page fault must not be the
+ * page fill worker thread because that is the only way to complete the
+ * page fill.
+ *
+ * NOTES:
+ * 1. One way to accomplish this would be a two pass link phase:
+ * - In the first phase, create a partially linked objected containing
+ * all interrupt/exception handling logic, the page fill worker thread
+ * plus all parts of the IDLE thread (which must always be available
+ * for execution).
+ * - All of the .text and .rodata sections of this partial link should
+ * be collected into a single section.
+ * - The second link would link the partially linked object along with
+ * the remaining object to produce the final binary. The linker
+ * script should position the "special" section so that it lies
+ * in a reserved, "non-swappable" region.
+ *
+ ****************************************************************************/
+
+void pg_miss(void)
+{
+ FAR _TCB *ftcb = (FAR _TCB*)g_readytorun.head;
+ FAR _TCB *wtcb;
+
+ /* Sanity checking
+ *
+ * ASSERT if the currently executing task is the page fill worker thread.
+ * The page fill worker thread is how the the page fault is resolved and
+ * all logic associated with the page fill worker must be "locked" and
+ * always present in memory.
+ */
+
+ pglldbg("Blocking TCB: %p PID: %d\n", ftcb, ftcb->pid);
+ DEBUGASSERT(g_pgworker != ftcb->pid);
+
+ /* Block the currently executing task
+ * - Call up_block_task() to block the task at the head of the ready-
+ * to-run list. This should cause an interrupt level context switch
+ * to the next highest priority task.
+ * - The blocked task will be marked with state TSTATE_WAIT_PAGEFILL
+ * and will be retained in the g_waitingforfill prioritized task list.
+ */
+
+ up_block_task(ftcb, TSTATE_WAIT_PAGEFILL);
+
+ /* Boost the page fill worker thread priority.
+ * - Check the priority of the task at the head of the g_waitingforfill
+ * list. If the priority of that task is higher than the current
+ * priority of the page fill worker thread, then boost the priority
+ * of the page fill worker thread to that priority.
+ */
+
+ wtcb = sched_gettcb(g_pgworker);
+ DEBUGASSERT(wtcb != NULL);
+
+ if (wtcb->sched_priority < ftcb->sched_priority)
+ {
+ /* Reprioritize the page fill worker thread */
+
+ pgllvdbg("New worker priority. %d->%d\n",
+ wtcb->sched_priority, ftcb->sched_priority);
+ sched_setpriority(wtcb, ftcb->sched_priority);
+ }
+
+ /* Signal the page fill worker thread.
+ * - Is there a page fill pending? If not then signal the worker
+ * thread to start working on the queued page fill requests.
+ */
+
+ if (!g_pftcb)
+ {
+ pglldbg("Signaling worker. PID: %d\n", g_pgworker);
+ kill(g_pgworker, SIGWORK);
+ }
+}
+
+#endif /* CONFIG_PAGING */
diff --git a/nuttx/sched/pg_worker.c b/nuttx/sched/pg_worker.c
new file mode 100644
index 000000000..4a18ec9a3
--- /dev/null
+++ b/nuttx/sched/pg_worker.c
@@ -0,0 +1,678 @@
+/****************************************************************************
+ * sched/pg_worker.c
+ * Page fill worker thread implementation.
+ *
+ * Copyright (C) 2010-2011 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 <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <queue.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/page.h>
+#include <nuttx/clock.h>
+
+#include "os_internal.h"
+#include "pg_internal.h"
+
+#ifdef CONFIG_PAGING
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifdef CONFIG_DISABLE_SIGNALS
+# warning "Signals needed by this function (CONFIG_DISABLE_SIGNALS=n)"
+#endif
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/* This is the task ID of the page fill worker thread. This value was set in
+ * os_start when the page fill worker thread was started.
+ */
+
+pid_t g_pgworker;
+
+/* The page fill worker thread maintains a static variable called g_pftcb.
+ * If no fill is in progress, g_pftcb will be NULL. Otherwise, g_pftcb will
+ * point to the TCB of the task which is receiving the fill that is in progess.
+ *
+ * NOTE: I think that this is the only state in which a TCB does not reside
+ * in some list. Here is it in limbo, outside of the normally queuing while
+ * the page file is in progress. Where here, it will be marked with
+ * TSTATE_TASK_INVALID.
+ */
+
+FAR _TCB *g_pftcb;
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+#ifndef CONFIG_PAGING_BLOCKINGFILL
+
+/* When a page fill completes, the result of the fill is stored here. The
+ * value -EBUSY means that the page fill callback has not yet been received.
+ */
+
+static int g_fillresult;
+
+/* A configurable timeout period (in clock ticks) may be select to detect
+ * page fill failures.
+ */
+
+#ifdef CONFIG_PAGING_TIMEOUT_TICKS
+status uint32_t g_starttime;
+#endif
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pg_callback
+ *
+ * Description:
+ * This function is called from the architecture-specific, page fill logic
+ * when the page fill completes (with or without an error). A reference to
+ * this function was provided to up_fillpage(). The driver will provide
+ * the result of the fill as an argument.
+ *
+ * NOTE: pg_callback() must also be locked in memory.
+ *
+ * When pg_callback() is called, it will perform the following operations:
+ *
+ * - Verify that g_pftcb is non-NULL.
+ * - Find the higher priority between the task waiting for the fill to
+ * complete in g_pftcb and the task waiting at the head of the
+ * g_waitingforfill list. That will be the priority of he highest priority
+ * task waiting for a fill.
+ * - If this higher priority is higher than current page fill worker thread,
+ * then boost worker thread's priority to that level. Thus, the page fill
+ * worker thread will always run at the priority of the highest priority
+ * task that is waiting for a fill.
+ * - Signal the page fill worker thread.
+ *
+ * Input parameters:
+ * tcb - The TCB of the task that just received the fill.
+ * result - The result of the page fill operation.
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Possibly executing in the context of a driver interrupt handler???
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_PAGING_BLOCKINGFILL
+static void pg_callback(FAR _TCB *tcb, int result)
+{
+ /* Verify that g_pftcb is non-NULL */
+
+ pgllvdbg("g_pftcb: %p\n", g_pftcb);
+ if (g_pftcb)
+ {
+ FAR _TCB *htcb = (FAR _TCB *)g_waitingforfill.head;
+ FAR _TCB *wtcb = sched_gettcb(g_pgworker);
+
+ /* Find the higher priority between the task waiting for the fill to
+ * complete in g_pftcb and the task waiting at the head of the
+ * g_waitingforfill list. That will be the priority of he highest
+ * priority task waiting for a fill.
+ */
+
+ int priority = g_pftcb->sched_priority;
+ if (htcb && priority < htcb->sched_priority)
+ {
+ priority = htcb->sched_priority;
+ }
+
+ /* If this higher priority is higher than current page fill worker
+ * thread, then boost worker thread's priority to that level. Thus,
+ * the page fill worker thread will always run at the priority of
+ * the highest priority task that is waiting for a fill.
+ */
+
+ if (priority > wtcb->sched_priority)
+ {
+ pgllvdbg("New worker priority. %d->%d\n",
+ wtcb->sched_priority, priority);
+ sched_setpriority(wtcb, priority);
+ }
+
+ /* Save the page fill result (don't permit the value -EBUSY) */
+
+ if (result == -EBUSY)
+ {
+ result = -ENOSYS;
+ }
+
+ g_fillresult = result;
+ }
+
+ /* Signal the page fill worker thread (in any event) */
+
+ pglldbg("Signaling worker. PID: %d\n", g_pgworker);
+ kill(g_pgworker, SIGWORK);
+}
+#endif
+
+/****************************************************************************
+ * Name: pg_dequeue
+ *
+ * Description:
+ * Dequeue the next, highest priority TCB from the g_waitingforfill task
+ * list. Call up_checkmapping() see if the still needs to be performed
+ * for that task. In certain conditions, the page fault may occur on
+ * several threads for the same page and be queued multiple times. In this
+ * corner case, the blocked task will simply be restarted.
+ *
+ * This function will continue to examine g_waitingforfill until either
+ * (1) a task is found that still needs the page fill, or (2) the
+ * g_waitingforfill task list becomes empty.
+ *
+ * The result (NULL or a TCB pointer) will be returned in the global
+ * variable, g_pftcb.
+ *
+ * Input parameters:
+ * None
+ *
+ * Returned Value:
+ * If there are no further queue page fill operations to be performed,
+ * pg_dequeue() will return false. Otherwise, it will return
+ * true to that the full is in process (any errors will result in
+ * assertions and this function will not return).
+ *
+ * Assumptions:
+ * Executing in the context of the page fill worker thread with all
+ * interrupts disabled.
+ *
+ ****************************************************************************/
+
+static inline bool pg_dequeue(void)
+{
+ /* Loop until either (1) the TCB of a task that requires a fill is found, OR
+ * (2) the g_watingforfill list becomes empty.
+ */
+
+ do
+ {
+ /* Remove the TCB from the head of the list (if any) */
+
+ g_pftcb = (FAR _TCB *)dq_remfirst((dq_queue_t*)&g_waitingforfill);
+ pgllvdbg("g_pftcb: %p\n", g_pftcb);
+ if (g_pftcb != NULL)
+ {
+ /* Call the architecture-specific function up_checkmapping() to see if
+ * the page fill still needs to be performed. In certain conditions,
+ * the page fault may occur on several threads for the same page and
+ * be queues multiple times. In this corner case, the blocked task will
+ * simply be restarted.
+ */
+
+ if (!up_checkmapping(g_pftcb))
+ {
+ /* This page needs to be filled. pg_miss bumps up
+ * the priority of the page fill worker thread as each
+ * TCB is added to the g_waitingforfill list. So we
+ * may need to also drop the priority of the worker
+ * thread as the next TCB comes off of the list.
+ *
+ * If wtcb->sched_priority > CONFIG_PAGING_DEFPRIO,
+ * then the page fill worker thread is executing at
+ * an elevated priority that may be reduced.
+ *
+ * If wtcb->sched_priority > g_pftcb->sched_priority
+ * then the page fill worker thread is executing at
+ * a higher priority than is appropriate for this
+ * fill (this priority can get re-boosted by pg_miss()
+ * if a new higher priority fill is required).
+ */
+
+ FAR _TCB *wtcb = (FAR _TCB *)g_readytorun.head;
+ if (wtcb->sched_priority > CONFIG_PAGING_DEFPRIO &&
+ wtcb->sched_priority > g_pftcb->sched_priority)
+ {
+ /* Don't reduce the priority of the page fill
+ * worker thread lower than the configured
+ * minimum.
+ */
+
+ int priority = g_pftcb->sched_priority;
+ if (priority < CONFIG_PAGING_DEFPRIO)
+ {
+ priority = CONFIG_PAGING_DEFPRIO;
+ }
+
+ /* Reduce the priority of the page fill worker thread */
+
+ pgllvdbg("New worker priority. %d->%d\n",
+ wtcb->sched_priority, priority);
+ sched_setpriority(wtcb, priority);
+ }
+
+ /* Return with g_pftcb holding the pointer to
+ * the TCB associated with task that requires the page fill.
+ */
+
+ return true;
+ }
+
+ /* The page need by this task has already been mapped into the
+ * virtual address space -- just restart it.
+ */
+
+ pglldbg("Restarting TCB: %p\n", g_pftcb);
+ up_unblock_task(g_pftcb);
+ }
+ }
+ while (g_pftcb != NULL);
+
+ return false;
+}
+
+/****************************************************************************
+ * Name: pg_startfill
+ *
+ * Description:
+ * Start a page fill operation on the thread whose TCB is at the head of
+ * of the g_waitingforfill task list. That is a prioritized list so that
+ * will be the highest priority task waiting for a page fill (in the event
+ * that are multiple tasks waiting for a page fill).
+ *
+ * This function may be called either (1) when the page fill worker thread
+ * is notified that there is a new page fill TCB in the g_waitingforfill
+ * prioritized list, or (2) when a page fill completes and there are more
+ * pages to be filled in g_waitingforfill list.
+ *
+ * Input parameters:
+ * None
+ *
+ * Returned Value:
+ * If there are no further queue page fill operations to be performed,
+ * pg_startfill() will return false. Otherwise, it will return
+ * true to that the full is in process (any errors will result in
+ * assertions and this function will not return).
+ *
+ * Assumptions:
+ * Executing in the context of the page fill worker thread with all
+ * interrupts disabled.
+ *
+ ****************************************************************************/
+
+static inline bool pg_startfill(void)
+{
+ FAR void *vpage;
+ int result;
+
+ /* Remove the TCB at the head of the g_waitfor fill list and check if there
+ * is any task waiting for a page fill. pg_dequeue will handle this (plus
+ * some cornercases) and will true if the next page TCB was successfully
+ * dequeued.
+ */
+
+ if (pg_dequeue())
+ {
+ /* Call up_allocpage(tcb, &vpage). This architecture-specific function will
+ * set aside page in memory and map to virtual address (vpage). If all
+ * available pages are in-use (the typical case), this function will select
+ * a page in-use, un-map it, and make it available.
+ */
+
+ pgllvdbg("Call up_allocpage(%p)\n", g_pftcb);
+ result = up_allocpage(g_pftcb, &vpage);
+ DEBUGASSERT(result == OK);
+
+ /* Start the fill. The exact way that the fill is started depends upon
+ * the nature of the architecture-specific up_fillpage() function -- Is it
+ * a blocking or a non-blocking call?
+ */
+#ifdef CONFIG_PAGING_BLOCKINGFILL
+ /* If CONFIG_PAGING_BLOCKINGFILL is defined, then up_fillpage is blocking
+ * call. In this case, up_fillpage() will accept only (1) a reference to
+ * the TCB that requires the fill. Architecture-specific context information
+ * within the TCB will be sufficient to perform the fill. And (2) the
+ * (virtual) address of the allocated page to be filled. The resulting
+ * status of the fill will be provided by return value from up_fillpage().
+ */
+
+ pgllvdbg("Call up_fillpage(%p)\n", g_pftcb);
+ result = up_fillpage(g_pftcb, vpage);
+ DEBUGASSERT(result == OK);
+#else
+ /* If CONFIG_PAGING_BLOCKINGFILL is defined, then up_fillpage is non-blocking
+ * call. In this case up_fillpage() will accept an additional argument: The page
+ * fill worker thread will provide a callback function, pg_callback.
+ *
+ * Calling up_fillpage will start an asynchronous page fill. pg_callback
+ * ill be called when the page fill is finished (or an error occurs). This
+ * This callback will probably from interrupt level.
+ */
+
+ pgllvdbg("Call up_fillpage(%p)\n", g_pftcb);
+ result = up_fillpage(g_pftcb, vpage, pg_callback);
+ DEBUGASSERT(result == OK);
+
+ /* Save the time that the fill was started. These will be used to check for
+ * timeouts.
+ */
+
+#ifdef CONFIG_PAGING_TIMEOUT_TICKS
+ g_starttime = clock_systimer();
+#endif
+
+ /* Return and wait to be signaled for the next event -- the fill completion
+ * event. While the fill is in progress, other tasks may execute. If
+ * another page fault occurs during this time, the faulting task will be
+ * blocked, its TCB will be added (in priority order) to g_waitingforfill
+ * and the priority of the page worker task may be boosted. But no action
+ * will be taken until the current page fill completes. NOTE: The IDLE task
+ * must also be fully locked in memory. The IDLE task cannot be blocked. It
+ * the case where all tasks are blocked waiting for a page fill, the IDLE
+ * task must still be available to run.
+ */
+#endif /* CONFIG_PAGING_BLOCKINGFILL */
+
+ return true;
+ }
+
+ pglldbg("Queue empty\n");
+ return false;
+}
+
+/****************************************************************************
+ * Name: pg_alldone
+ *
+ * Description:
+ * Called by the page fill worker thread when all pending page fill
+ * operations have been completed and the g_waitingforfill list is empty.
+ *
+ * This functin will perform the following operations:
+ *
+ * - Set g_pftcb to NULL.
+ * - Restore the default priority of the page fill worker thread.
+ *
+ * Input parameters:
+ * None.
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Executing in the context of the page fill worker thread with interrupts
+ * disabled.
+ *
+ ****************************************************************************/
+
+static inline void pg_alldone(void)
+{
+ FAR _TCB *wtcb = (FAR _TCB *)g_readytorun.head;
+ g_pftcb = NULL;
+ pgllvdbg("New worker priority. %d->%d\n",
+ wtcb->sched_priority, CONFIG_PAGING_DEFPRIO);
+ sched_setpriority(wtcb, CONFIG_PAGING_DEFPRIO);
+}
+
+/****************************************************************************
+ * Name: pg_fillcomplete
+ *
+ * Description:
+ * Called by the page fill worker thread when a page fill completes.
+ * Either (1) in the non-blocking up_fillpage(), after the architecture-
+ * specific driver call the pg_callback() to wake up the page fill worker
+ * thread, or (2) after the blocking up_fillpage() returens (when
+ * CONFIG_PAGING_BLOCKINGFILL is defined).
+ *
+ * This function is just a dumb wrapper around up_unblocktask(). This
+ * function simply makes the task that just received the fill ready-to-run.
+ *
+ * Input parameters:
+ * None.
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Executing in the context of the page fill worker thread with interrupts
+ * disabled.
+ *
+ ****************************************************************************/
+
+static inline void pg_fillcomplete(void)
+{
+ /* Call up_unblocktask(g_pftcb) to make the task that just
+ * received the fill ready-to-run.
+ */
+
+ pglldbg("Restarting TCB: %p\n", g_pftcb);
+ up_unblock_task(g_pftcb);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+/****************************************************************************
+ * Name: pg_worker
+ *
+ * Description:
+ * This is the page fill worker thread that performs pages fills for tasks
+ * that have received a pag fault and are blocked in the g_waitingforfill
+ * task queue.
+ *
+ * The page fill worker thread will be awakened on one of three conditions:
+ * - When signaled by pg_miss(), the page fill worker thread will be
+ * awakenend, or
+ * - if CONFIG_PAGING_BLOCKINGFILL is not defined, from pg_callback()
+ * after completing a page fill.
+ * - A configurable timeout with no activity.
+ *
+ * Input parameters:
+ * argc, argv (not used)
+ *
+ * Returned Value:
+ * Does not return
+ *
+ ****************************************************************************/
+
+int pg_worker(int argc, char *argv[])
+{
+ irqstate_t flags;
+
+ /* Loop forever -- Notice that interrupts will be disable at all times that
+ * this thread runs. That is so that we con't lose signals or have
+ * asynchronous page faults.
+ *
+ * All interrupt logic as well as all page fill worker thread logic must
+ * be locked in memory. Therefore, keeping interrupts disabled here
+ * should prevent any concurrent page faults. Any page faults or page
+ * fill completions should occur while this thread sleeps.
+ */
+
+ pglldbg("Started\n");
+ flags = irqsave();
+ for (;;)
+ {
+ /* Wait awhile. We will wait here until either the configurable timeout
+ * elapses or until we are awakened by a signal (which terminates the
+ * usleep with an EINTR error). Note that interrupts will be re-enabled
+ * while this task sleeps.
+ *
+ * The timeout is a failsafe that will handle any cases where a single
+ * is lost (that would really be a bug and shouldn't happen!) and also
+ * supports timeouts for case of non-blocking, asynchronous fills.
+ */
+
+ usleep(CONFIG_PAGING_WORKPERIOD);
+
+ /* The page fill worker thread will be awakened on one of three conditions:
+ *
+ * - When signaled by pg_miss(), the page fill worker thread will be awakenend,
+ * - if CONFIG_PAGING_BLOCKINGFILL is not defined, from pg_callback()
+ * after completing a page fill, or
+ * - On a configurable timeout expires with no activity.
+ *
+ * Interrupts are still disabled.
+ */
+
+#ifndef CONFIG_PAGING_BLOCKINGFILL
+ /* For the non-blocking up_fillpage(), the page fill worker thread will detect
+ * that the page fill is complete when it is awakened with g_pftcb non-NULL
+ * and fill completion status from pg_callback.
+ */
+
+ if (g_pftcb != NULL)
+ {
+ /* If it is a real page fill completion event, then the result of the page
+ * fill will be in g_fillresult and will not be equal to -EBUSY.
+ */
+
+ if (g_fillresult != -EBUSY)
+ {
+ /* Any value other than OK, brings the system down */
+
+ ASSERT(g_fillresult == OK);
+
+ /* Handle the successful page fill complete event by restarting the
+ * task that was blocked waiting for this page fill.
+ */
+
+ pglldbg("Restarting TCB: %p\n", g_pftcb);
+ up_unblock_task(g_pftcb);;
+
+ /* Yes .. Start the next asynchronous fill. Check the return
+ * value to see a fill was actually started (false means that
+ * no fill was started).
+ */
+
+ pgllvdbg("Calling pg_startfill\n");
+ if (!pg_startfill())
+ {
+ /* No fill was started. This can mean only that all queued
+ * page fill actions have and been completed and there is
+ * nothing more to do.
+ */
+
+ pgllvdbg("Call pg_alldone()\n");
+ pg_alldone();
+ }
+ }
+
+ /* If a configurable timeout period expires with no page fill completion
+ * event, then declare a failure.
+ */
+
+#ifdef CONFIG_PAGING_TIMEOUT_TICKS
+ else
+ {
+ lldbg("Timeout!\n");
+ ASSERT(clock_systimer() - g_starttime < CONFIG_PAGING_TIMEOUT_TICKS);
+ }
+#endif
+ }
+
+ /* Otherwise, this might be a page fill initiation event. When
+ * awakened from pg_miss(), no fill will be in progress and
+ * g_pftcb will be NULL.
+ */
+
+ else
+ {
+ /* Are there tasks blocked and waiting for a fill? If so,
+ * pg_startfill() will start the asynchronous fill (and set
+ * g_pftcb).
+ */
+
+ pgllvdbg("Calling pg_startfill\n");
+ (void)pg_startfill();
+ }
+#else
+ /* Are there tasks blocked and waiting for a fill? Loop until all
+ * pending fills have been processed.
+ */
+
+ for (;;)
+ {
+ /* Yes .. Start the fill and block until the fill completes.
+ * Check the return value to see a fill was actually performed.
+ * (false means that no fill was perforemd).
+ */
+
+ pgllvdbg("Calling pg_startfill\n");
+ if (!pg_startfill())
+ {
+ /* Break out of the loop -- there is nothing more to do */
+
+ break;
+ }
+
+ /* Handle the page fill complete event by restarting the
+ * task that was blocked waiting for this page fill. In the
+ * non-blocking fill case, the page fill worker thread will
+ * know that the page fill is complete when pg_startfill()
+ * returns true.
+ */
+
+ pgllvdbg("Restarting TCB: %p\n", g_pftcb);
+ up_unblock_task(g_pftcb);;
+ }
+
+ /* All queued fills have been processed */
+
+ pgllvdbg("Call pg_alldone()\n");
+ pg_alldone();
+#endif
+ }
+
+ return OK; /* To keep some compilers happy */
+}
+#endif /* CONFIG_PAGING */
diff --git a/nuttx/sched/prctl.c b/nuttx/sched/prctl.c
new file mode 100644
index 000000000..d71a0e174
--- /dev/null
+++ b/nuttx/sched/prctl.c
@@ -0,0 +1,167 @@
+/************************************************************************
+ * sched/prctl.c
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/prctl.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/sched.h>
+
+#include "os_internal.h"
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/****************************************************************************
+ * Name: prctl
+ *
+ * Description:
+ * prctl() is called with a first argument describing what to do (with
+ * values PR_* defined above) and with additional arguments depending on
+ * the specific command.
+ *
+ * Returned Value:
+ * The returned value may depend on the specific commnand. For PR_SET_NAME
+ * and PR_GET_NAME, the returned value of 0 indicates successful operation.
+ * On any failure, -1 is retruend and the errno value is set appropriately.
+ *
+ * EINVAL The value of 'option' is not recognized.
+ * EFAULT optional arg1 is not a valid address.
+ * ESRCH No task/thread can be found corresponding to that specified
+ * by optional arg1.
+ *
+ ****************************************************************************/
+
+int prctl(int option, ...)
+{
+ va_list ap;
+ int err;
+
+ va_start(ap, option);
+ switch (option)
+ {
+ case PR_SET_NAME:
+ case PR_GET_NAME:
+#if CONFIG_TASK_NAME_SIZE > 0
+ {
+ /* Get the prctl arguments */
+
+ FAR char *name = va_arg(ap, FAR char *);
+ int pid = va_arg(ap, int);
+ FAR _TCB *tcb;
+
+ /* Get the TCB associated with the PID (handling the special case of
+ * pid==0 meaning "this thread")
+ */
+
+ if (!pid)
+ {
+ tcb = (FAR _TCB *)g_readytorun.head;
+ }
+ else
+ {
+ tcb = sched_gettcb(pid);
+ }
+
+ /* An invalid pid will be indicated by a NULL TCB returned from
+ * sched_gettcb()
+ */
+
+ if (!tcb)
+ {
+ sdbg("Pid does not correspond to a task: %d\n", pid);
+ err = ESRCH;
+ goto errout;
+ }
+
+ /* A pointer to the task name storage must also be provided */
+
+ if (!name)
+ {
+ sdbg("No name provide\n");
+ err = EFAULT;
+ goto errout;
+ }
+
+ /* Now get or set the task name */
+
+ if (option == PR_SET_NAME)
+ {
+ /* tcb->name may not be null-terminated */
+
+ strncpy(tcb->name, name, CONFIG_TASK_NAME_SIZE);
+ }
+ else
+ {
+ /* The returned value will be null-terminated, truncating if necessary */
+
+ strncpy(name, tcb->name, CONFIG_TASK_NAME_SIZE-1);
+ name[CONFIG_TASK_NAME_SIZE-1] = '\0';
+ }
+ }
+ break;
+#else
+ sdbg("Option not enabled: %d\n", option);
+ err = ENOSYS;
+ goto errout;
+#endif
+
+ default:
+ sdbg("Unrecognized option: %d\n", option);
+ err = EINVAL;
+ goto errout;
+ }
+
+ va_end(ap);
+ return OK;
+
+errout:
+ va_end(ap);
+ set_errno(err);
+ return ERROR;
+}
diff --git a/nuttx/sched/pthread_barrierdestroy.c b/nuttx/sched/pthread_barrierdestroy.c
new file mode 100644
index 000000000..40e8e875c
--- /dev/null
+++ b/nuttx/sched/pthread_barrierdestroy.c
@@ -0,0 +1,110 @@
+/********************************************************************************
+ * sched/pthread_barriedestroy.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ********************************************************************************/
+
+/********************************************************************************
+ * Included Files
+ ********************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Type Declarations
+ ********************************************************************************/
+
+/********************************************************************************
+ * Global Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Function Prototypes
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: pthread_barrier_destroy
+ *
+ * Description:
+ * The pthread_barrier_destroy() function destroys the barrier referenced by
+ * 'barrier' and releases any resources used by the barrier. The effect of
+ * subsequent use of the barrier is undefined until the barrier is
+ * reinitialized by another call to pthread_barrier_init(). The results are
+ * undefined if pthread_barrier_destroy() is called when any thread is blocked
+ * on the barrier, or if this function is called with an uninitialized barrier.
+ *
+ * Parameters:
+ * barrier - barrier to be destroyed.
+ *
+ * Return Value:
+ * 0 (OK) on success or on of the following error numbers:
+ *
+ * EBUSY The implementation has detected an attempt to destroy a barrier while
+ * it is in use.
+ * EINVAL The value specified by barrier is invalid.
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int pthread_barrier_destroy(FAR pthread_barrier_t *barrier)
+{
+ int ret = OK;
+
+ if (!barrier)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ sem_destroy(&barrier->sem);
+ barrier->count = 0;
+ }
+ return ret;
+}
diff --git a/nuttx/sched/pthread_barrierinit.c b/nuttx/sched/pthread_barrierinit.c
new file mode 100644
index 000000000..73b974b18
--- /dev/null
+++ b/nuttx/sched/pthread_barrierinit.c
@@ -0,0 +1,122 @@
+/********************************************************************************
+ * sched/pthread_barrieinit.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ********************************************************************************/
+
+/********************************************************************************
+ * Included Files
+ ********************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Type Declarations
+ ********************************************************************************/
+
+/********************************************************************************
+ * Global Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Function Prototypes
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: pthread_barrier_init
+ *
+ * Description:
+ * The pthread_barrier_init() function allocates any resources required to use
+ * the barrier referenced by 'barrier' and initialized the barrier with the
+ * attributes referenced by attr. If attr is NULL, the default barrier
+ * attributes will be used. The results are undefined if pthread_barrier_init()
+ * is called when any thread is blocked on the barrier. The results are
+ * undefined if a barrier is used without first being initialized. The results
+ * are undefined if pthread_barrier_init() is called specifying an already
+ * initialized barrier.
+ *
+ * Parameters:
+ * barrier - the barrier to be initialized
+ * attr - barrier attributes to be used in the initialization.
+ * count - the count to be associated with the barrier. The count argument
+ * specifies the number of threads that must call pthread_barrier_wait() before
+ * any of them successfully return from the call. The value specified by
+ * count must be greater than zero.
+ *
+ * Return Value:
+ * 0 (OK) on success or on of the following error numbers:
+ *
+ * EAGAIN The system lacks the necessary resources to initialize another barrier.
+ * EINVAL The barrier reference is invalid, or the values specified by attr are
+ * invalid, or the value specified by count is equal to zero.
+ * ENOMEM Insufficient memory exists to initialize the barrier.
+ * EBUSY The implementation has detected an attempt to reinitialize a barrier
+ * while it is in use.
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int pthread_barrier_init(FAR pthread_barrier_t *barrier,
+ FAR const pthread_barrierattr_t *attr, unsigned int count)
+{
+ int ret = OK;
+
+ if (!barrier || count == 0)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ sem_init(&barrier->sem, 0, 0);
+ barrier->count = count;
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/pthread_barrierwait.c b/nuttx/sched/pthread_barrierwait.c
new file mode 100644
index 000000000..8ca8d1754
--- /dev/null
+++ b/nuttx/sched/pthread_barrierwait.c
@@ -0,0 +1,182 @@
+/********************************************************************************
+ * sched/pthread_barrierwait.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ********************************************************************************/
+
+/********************************************************************************
+ * Included Files
+ ********************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Type Declarations
+ ********************************************************************************/
+
+/********************************************************************************
+ * Global Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Function Prototypes
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: pthread_barrier_wait
+ *
+ * Description:
+ * The pthread_barrier_wait() function synchronizse participating threads at
+ * the barrier referenced by 'barrier'. The calling thread is blocked until
+ * the required number of threads have called pthread_barrier_wait() specifying
+ * the same 'barrier'. When the required number of threads have called
+ * pthread_barrier_wait() specifying the 'barrier', the constant
+ * PTHREAD_BARRIER_SERIAL_THREAD will be returned to one unspecified thread
+ * and zero will be returned to each of the remaining threads. At this point,
+ * the barrier will be reset to the state it had as a result of the most recent
+ * pthread_barrier_init() function that referenced it.
+ *
+ * The constant PTHREAD_BARRIER_SERIAL_THREAD is defined in pthread.h and its
+ * value must be distinct from any other value returned by pthread_barrier_wait().
+ *
+ * The results are undefined if this function is called with an uninitialized
+ * barrier.
+ *
+ * If a signal is delivered to a thread blocked on a barrier, upon return from
+ * the signal handler the thread will resume waiting at the barrier if the barrier
+ * wait has not completed; otherwise, the thread will continue as normal from
+ * the completed barrier wait. Until the thread in the signal handler returns
+ * from it, it is unspecified whether other threads may proceed past the barrier
+ * once they have all reached it.
+ *
+ * A thread that has blocked on a barrier will not prevent any unblocked thread
+ * that is eligible to use the same processing resources from eventually making
+ * forward progress in its execution. Eligibility for processing resources will
+ * be determined by the scheduling policy.
+ *
+ * Parameters:
+ * barrier - the barrier to wait on
+ *
+ * Return Value:
+ * 0 (OK) on success or EINVAL if the barrier is not valid.
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int pthread_barrier_wait(FAR pthread_barrier_t *barrier)
+{
+ int semcount;
+ int ret = OK;
+
+ if (!barrier)
+ {
+ return EINVAL;
+ }
+
+ /* Disable pre-emption throughout the following */
+
+ sched_lock();
+
+ /* Find out how many threads are already waiting at the barrier */
+
+ ret = sem_getvalue(&barrier->sem, &semcount);
+ if (ret != OK)
+ {
+ sched_unlock();
+ return EINVAL;
+ }
+
+ /* If the number of waiters would be equal to the count, then we are done */
+
+ if (1 - semcount >= barrier->count)
+ {
+ /* Free all of the waiting threads */
+
+ while (semcount < 0)
+ {
+ (void)sem_post(&barrier->sem);
+ (void)sem_getvalue(&barrier->sem, &semcount);
+ }
+
+ /* Then return PTHREAD_BARRIER_SERIAL_THREAD to the final thread */
+
+ sched_unlock();
+ return PTHREAD_BARRIER_SERIAL_THREAD;
+ }
+ else
+ {
+ /* Otherwise, this thread must wait as well */
+
+ while (sem_wait(&barrier->sem) != OK)
+ {
+ /* If the thread is awakened by a signal, just continue to wait */
+
+ int errornumber = get_errno();
+ if (errornumber != EINTR)
+ {
+ /* If it is awakened by some other error, then there is a
+ * problem
+ */
+
+ sched_unlock();
+ return errornumber;
+ }
+ }
+
+ /* We will only get here when we are one of the N-1 threads that were
+ * waiting for the final thread at the barrier. We just need to return
+ * zero.
+ */
+
+ sched_unlock();
+ return 0;
+ }
+}
diff --git a/nuttx/sched/pthread_cancel.c b/nuttx/sched/pthread_cancel.c
new file mode 100644
index 000000000..5e34eeaba
--- /dev/null
+++ b/nuttx/sched/pthread_cancel.c
@@ -0,0 +1,148 @@
+/**************************************************************************
+ * sched/pthread_cancel.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ **************************************************************************/
+
+/**************************************************************************
+ * Included Files
+ **************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include "os_internal.h"
+#include "pthread_internal.h"
+
+/**************************************************************************
+ * Private Definitions
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Types
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Function Prototypes
+ **************************************************************************/
+
+/**************************************************************************
+ * Global Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Variables
+ **************************************************************************/
+
+/**************************************************************************
+ * Private Functions
+ **************************************************************************/
+
+/**************************************************************************
+ * Public Functions
+ **************************************************************************/
+
+int pthread_cancel(pthread_t thread)
+{
+ _TCB *tcb;
+
+ /* First, make sure that the handle references a valid thread */
+
+ if (!thread)
+ {
+ /* pid == 0 is the IDLE task. Callers cannot cancel the
+ * IDLE task.
+ */
+
+ return ESRCH;
+ }
+
+ tcb = sched_gettcb((pid_t)thread);
+ if (!tcb)
+ {
+ /* The pid does not correspond to any known thread */
+
+ return ESRCH;
+ }
+
+ /* Check to see if this thread has the non-cancelable bit set in its
+ * flags. Suppress context changes for a bit so that the flags are stable.
+ * (the flags should not change in interrupt handling.
+ */
+
+ sched_lock();
+ if ((tcb->flags & TCB_FLAG_NONCANCELABLE) != 0)
+ {
+ /* Then we cannot cancel the thread now. Here is how this is
+ * supposed to work:
+ *
+ * "When cancelability is disabled, all cancels are held pending
+ * in the target thread until the thread changes the cancelability.
+ * When cancelability is deferred, all cancels are held pending in
+ * the target thread until the thread changes the cancelability, calls
+ * a function which is a cancellation point or calls pthread_testcancel(),
+ * thus creating a cancellation point. When cancelability is asynchronous,
+ * all cancels are acted upon immediately, interrupting the thread with its
+ * processing."
+ */
+
+ tcb->flags |= TCB_FLAG_CANCEL_PENDING;
+ sched_unlock();
+ return OK;
+ }
+
+ sched_unlock();
+
+ /* Check to see if the ID refers to ourselves.. this would be the
+ * same as pthread_exit(PTHREAD_CANCELED).
+ */
+
+ if (tcb == (_TCB*)g_readytorun.head)
+ {
+ pthread_exit(PTHREAD_CANCELED);
+ }
+
+ /* Complete pending join operations */
+
+ (void)pthread_completejoin((pid_t)thread, PTHREAD_CANCELED);
+
+ /* Then let pthread_delete do the real work */
+
+ task_delete((pid_t)thread);
+ return OK;
+}
+
+
diff --git a/nuttx/sched/pthread_completejoin.c b/nuttx/sched/pthread_completejoin.c
new file mode 100644
index 000000000..7c5191034
--- /dev/null
+++ b/nuttx/sched/pthread_completejoin.c
@@ -0,0 +1,231 @@
+/************************************************************************
+ * sched/pthread_completejoin.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "os_internal.h"
+#include "pthread_internal.h"
+
+/************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: pthread_notifywaiters
+ *
+ * Description:
+ * Notify all other threads waiting in phread join for this thread's
+ * exit data. This must be done by the child at child thread
+ * destruction time.
+ *
+ ************************************************************************/
+
+static bool pthread_notifywaiters(FAR join_t *pjoin)
+{
+ int ntasks_waiting;
+ int status;
+
+ svdbg("pjoin=0x%p\n", pjoin);
+
+ /* Are any tasks waiting for our exit value? */
+
+ status = sem_getvalue(&pjoin->exit_sem, &ntasks_waiting);
+ if (status == OK && ntasks_waiting < 0)
+ {
+ /* Set the data semaphore so that this thread will be
+ * awakened when all waiting tasks receive the data
+ */
+
+ (void)sem_init(&pjoin->data_sem, 0, (ntasks_waiting+1));
+
+ /* Post the semaphore to restart each thread that is waiting
+ * on the semaphore
+ */
+
+ do
+ {
+ status = pthread_givesemaphore(&pjoin->exit_sem);
+ if (status == OK)
+ {
+ status = sem_getvalue(&pjoin->exit_sem, &ntasks_waiting);
+ }
+ }
+ while (ntasks_waiting < 0 && status == OK);
+
+ /* Now wait for all these restarted tasks to obtain the return
+ * value.
+ */
+
+ (void)pthread_takesemaphore(&pjoin->data_sem);
+ return true;
+ }
+
+ return false;
+}
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: pthread_completejoin
+ *
+ * Description:
+ * A thread has been terminated -- either by returning, calling
+ * pthread_exit(), or through pthread_cancel(). In any event, we must
+ * complete any pending join events.
+ *
+ * Parameters:
+ * exit_value
+ *
+ * Returned Value:
+ * OK unless there is no join information associated with the pid.
+ * This could happen, for example, if a task started with task_create()
+ * calls pthread_exit().
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+int pthread_completejoin(pid_t pid, FAR void *exit_value)
+{
+ FAR join_t *pjoin;
+
+ svdbg("pid=%d exit_value=%p\n", pid, exit_value);
+
+ /* First, find thread's structure in the private data set. */
+
+ (void)pthread_takesemaphore(&g_join_semaphore);
+ pjoin = pthread_findjoininfo(pid);
+ if (!pjoin)
+ {
+ sdbg("Could not find join info, pid=%d\n", pid);
+ (void)pthread_givesemaphore(&g_join_semaphore);
+ return ERROR;
+ }
+ else
+ {
+ bool waiters;
+
+ /* Save the return exit value in the thread structure. */
+
+ pjoin->terminated = true;
+ pjoin->exit_value = exit_value;
+
+ /* Notify waiters of the availability of the exit value */
+
+ waiters = pthread_notifywaiters(pjoin);
+
+ /* If there are no waiters and if the thread is marked as detached.
+ * then discard the join information now. Otherwise, the pthread
+ * join logic will call pthread_destroyjoin() when all of the threads
+ * have sampled the exit value.
+ */
+
+ if (!waiters && pjoin->detached)
+ {
+ pthread_destroyjoin(pjoin);
+ }
+
+ /* Giving the following semaphore will allow the waiters
+ * to call pthread_destroyjoin.
+ */
+
+ (void)pthread_givesemaphore(&g_join_semaphore);
+ }
+
+ return OK;
+}
+
+/************************************************************************
+ * Name: pthread_destroyjoin
+ *
+ * Description:
+ * This is called from pthread_completejoin if the join info was
+ * detached or from pthread_join when the last waiting thread has
+ * received the thread exit info.
+ *
+ * Or it may never be called if the join info was never detached or if
+ * no thread ever calls pthread_join. In case, there is a memory leak!
+ *
+ * Assumptions:
+ * The caller holds g_join_semaphore
+ *
+ ************************************************************************/
+
+void pthread_destroyjoin(FAR join_t *pjoin)
+{
+ sdbg("pjoin=0x%p\n", pjoin);
+
+ /* Remove the join info from the set of joins */
+
+ (void)pthread_removejoininfo((pid_t)pjoin->thread);
+
+ /* Destroy its semaphores */
+
+ (void)sem_destroy(&pjoin->data_sem);
+ (void)sem_destroy(&pjoin->exit_sem);
+
+ /* And deallocate the pjoin structure */
+
+ sched_free(pjoin);
+}
+
diff --git a/nuttx/sched/pthread_condbroadcast.c b/nuttx/sched/pthread_condbroadcast.c
new file mode 100644
index 000000000..05f4bb483
--- /dev/null
+++ b/nuttx/sched/pthread_condbroadcast.c
@@ -0,0 +1,145 @@
+/****************************************************************************
+ * sched/pthread_condbroadcast.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <pthread.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_cond_broadcast
+ *
+ * Description:
+ * A thread broadcast on a condition variable.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_cond_broadcast(FAR pthread_cond_t *cond)
+{
+ int ret = OK;
+ int sval;
+
+ sdbg("cond=0x%p\n", cond);
+
+ if (!cond)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ /* Disable pre-emption until all of the waiting threads have been
+ * restarted. This is necessary to assure that the sval behaves as
+ * expected in the following while loop
+ */
+
+ sched_lock();
+
+ /* Get the current value of the semaphore */
+
+ if (sem_getvalue((sem_t*)&cond->sem, &sval) != OK)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ /* Loop until all of the waiting threads have been restarted. */
+
+ while (sval < 0)
+ {
+ /* If the value is less than zero (meaning that one or more
+ * thread is waiting), then post the condition semaphore.
+ * Only the highest priority waiting thread will get to execute
+ */
+
+ ret = pthread_givesemaphore((sem_t*)&cond->sem);
+
+ /* Increment the semaphore count (as was done by the
+ * above post).
+ */
+
+ sval++;
+ }
+ }
+
+ /* Now we can let the restarted threads run */
+
+ sched_unlock();
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
+
diff --git a/nuttx/sched/pthread_conddestroy.c b/nuttx/sched/pthread_conddestroy.c
new file mode 100644
index 000000000..11292e639
--- /dev/null
+++ b/nuttx/sched/pthread_conddestroy.c
@@ -0,0 +1,88 @@
+/****************************************************************************
+ * sched/pthread_conddestroy.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <pthread.h>
+#include <debug.h>
+#include <errno.h>
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_cond_destroy
+ *
+ * Description:
+ * A thread can delete condition variables.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_cond_destroy(FAR pthread_cond_t *cond)
+{
+ int ret = OK;
+
+ sdbg("cond=0x%p\n", cond);
+
+ if (!cond)
+ {
+ ret = EINVAL;
+ }
+
+ /* Destroy the semaphore contained in the structure */
+
+ else if (sem_destroy((sem_t*)&cond->sem) != OK)
+ {
+ ret = EINVAL;
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
diff --git a/nuttx/sched/pthread_condinit.c b/nuttx/sched/pthread_condinit.c
new file mode 100644
index 000000000..e49bb8658
--- /dev/null
+++ b/nuttx/sched/pthread_condinit.c
@@ -0,0 +1,93 @@
+/****************************************************************************
+ * sched/pthread_condinit.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <pthread.h>
+#include <debug.h>
+#include <errno.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_cond_init
+ *
+ * Description:
+ * A thread can create condition variables.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_cond_init(FAR pthread_cond_t *cond, FAR pthread_condattr_t *attr)
+{
+ int ret = OK;
+
+ sdbg("cond=0x%p attr=0x%p\n", cond, attr);
+
+ if (!cond)
+ {
+ ret = EINVAL;
+ }
+
+ /* Initialize the semaphore contained in the condition structure
+ * with initial count = 0
+ */
+
+ else if (sem_init((sem_t*)&cond->sem, 0, 0) != OK)
+ {
+ ret = EINVAL;
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
+
+
diff --git a/nuttx/sched/pthread_condsignal.c b/nuttx/sched/pthread_condsignal.c
new file mode 100644
index 000000000..48ff4cf20
--- /dev/null
+++ b/nuttx/sched/pthread_condsignal.c
@@ -0,0 +1,137 @@
+/****************************************************************************
+ * sched/pthread_condsignal.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <pthread.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_cond_signal
+ *
+ * Description:
+ * A thread can signal on a condition variable.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_cond_signal(FAR pthread_cond_t *cond)
+{
+ int ret = OK;
+ int sval;
+
+ sdbg("cond=0x%p\n", cond);
+
+ if (!cond)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ /* Get the current value of the semaphore */
+
+ if (sem_getvalue((sem_t*)&cond->sem, &sval) != OK)
+ {
+ ret = EINVAL;
+ }
+
+ /* If the value is less than zero (meaning that one or more
+ * thread is waiting), then post the condition semaphore.
+ * Only the highest priority waiting thread will get to execute
+ */
+
+ else
+ {
+ /* One of my objectives in this design was to make pthread_cond_signal
+ * usable from interrupt handlers. However, from interrupt handlers,
+ * you cannot take the associated mutex before signaling the condition.
+ * As a result, I think that there could be a race condition with
+ * the following logic which assumes that the if sval < 0 then the
+ * thread is waiting. Without the mutex, there is no atomic, protected
+ * operation that will guarantee this to be so.
+ */
+
+ sdbg("sval=%d\n", sval);
+ if (sval < 0)
+ {
+ sdbg("Signalling...\n");
+ ret = pthread_givesemaphore((sem_t*)&cond->sem);
+ }
+ }
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
+
diff --git a/nuttx/sched/pthread_condtimedwait.c b/nuttx/sched/pthread_condtimedwait.c
new file mode 100644
index 000000000..25f86d813
--- /dev/null
+++ b/nuttx/sched/pthread_condtimedwait.c
@@ -0,0 +1,308 @@
+/****************************************************************************
+ * sched/pthread_condtimedwait.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <stdint.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+#include <wdog.h>
+#include <debug.h>
+
+#include "os_internal.h"
+#include "pthread_internal.h"
+#include "clock_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_condtimedout
+ *
+ * Description:
+ * This function is called if the timeout elapses before
+ * the condition is signaled.
+ *
+ * Parameters:
+ * argc - the number of arguments (should be 2)
+ * pid - the task ID of the task to wakeup
+ * signo - The signal to use to wake up the task
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void pthread_condtimedout(int argc, uint32_t pid, uint32_t signo)
+{
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ union sigval value;
+
+ /* Send the specified signal to the specified task. */
+
+ value.sival_ptr = NULL;
+ (void)sigqueue((int)pid, (int)signo, value);
+#else
+ (void)sigqueue((int)pid, (int)signo, NULL);
+#endif
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_cond_timedwait
+ *
+ * Description:
+ * A thread can perform a timed wait on a condition variable.
+ *
+ * Parameters:
+ * cond - the condition variable to wait on
+ * mutex - the mutex that protects the condition variable
+ * abstime - wait until this absolute time
+ *
+ * Return Value:
+ * OK (0) on success; ERROR (-1) on failure with errno
+ * set appropriately.
+ *
+ * Assumptions:
+ * Timing is of resolution 1 msec, with +/-1 millisecond
+ * accuracy.
+ *
+ ****************************************************************************/
+
+int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex,
+ FAR const struct timespec *abstime)
+{
+ WDOG_ID wdog;
+ int ticks;
+ int mypid = (int)getpid();
+ irqstate_t int_state;
+ int ret = OK;
+ int status;
+
+ sdbg("cond=0x%p mutex=0x%p abstime=0x%p\n", cond, mutex, abstime);
+
+ /* Make sure that non-NULL references were provided. */
+
+ if (!cond || !mutex)
+ {
+ ret = EINVAL;
+ }
+
+ /* Make sure that the caller holds the mutex */
+
+ else if (mutex->pid != mypid)
+ {
+ ret = EPERM;
+ }
+
+ /* If no wait time is provided, this function degenerates to
+ * the same behavior as pthread_cond_wait().
+ */
+
+ else if (!abstime)
+ {
+ ret = pthread_cond_wait(cond, mutex);
+ }
+
+ else
+ {
+ /* Create a watchdog */
+
+ wdog = wd_create();
+ if (!wdog)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ sdbg("Give up mutex...\n");
+
+ /* We must disable pre-emption and interrupts here so that
+ * the time stays valid until the wait begins. This adds
+ * complexity because we assure that interrupts and
+ * pre-emption are re-enabled correctly.
+ */
+
+ sched_lock();
+ int_state = irqsave();
+
+ /* Convert the timespec to clock ticks. We must disable pre-emption
+ * here so that this time stays valid until the wait begins.
+ */
+
+ ret = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
+ if (ret)
+ {
+ /* Restore interrupts (pre-emption will be enabled when
+ * we fall through the if/then/else
+ */
+
+ irqrestore(int_state);
+ }
+ else
+ {
+ /* Check the absolute time to wait. If it is now or in the past, then
+ * just return with the timedout condition.
+ */
+
+ if (ticks <= 0)
+ {
+ /* Restore interrupts and indicate that we have already timed out.
+ * (pre-emption will be enabled when we fall through the
+ * if/then/else
+ */
+
+ irqrestore(int_state);
+ ret = ETIMEDOUT;
+ }
+ else
+ {
+ /* Give up the mutex */
+
+ mutex->pid = 0;
+ ret = pthread_givesemaphore((sem_t*)&mutex->sem);
+ if (ret)
+ {
+ /* Restore interrupts (pre-emption will be enabled when
+ * we fall through the if/then/else)
+ */
+
+ irqrestore(int_state);
+ }
+ else
+ {
+ /* Start the watchdog */
+
+ wd_start(wdog, ticks, (wdentry_t)pthread_condtimedout,
+ 2, (uint32_t)mypid, (uint32_t)SIGCONDTIMEDOUT);
+
+ /* Take the condition semaphore. Do not restore interrupts
+ * until we return from the wait. This is necessary to
+ * make sure that the watchdog timer and the condition wait
+ * are started atomically.
+ */
+
+ status = sem_wait((sem_t*)&cond->sem);
+
+ /* Did we get the condition semaphore. */
+
+ if (status != OK)
+ {
+ /* NO.. Handle the special case where the semaphore wait was
+ * awakened by the receipt of a signal -- presumably the
+ * signal posted by pthread_condtimedout().
+ */
+
+ if (get_errno() == EINTR)
+ {
+ sdbg("Timedout!\n");
+ ret = ETIMEDOUT;
+ }
+ else
+ {
+ ret = EINVAL;
+ }
+ }
+
+ /* The interrupts stay disabled until after we sample the errno.
+ * This is because when debug is enabled and the console is used
+ * for debug output, then the errno can be altered by interrupt
+ * handling! (bad)
+ */
+
+ irqrestore(int_state);
+ }
+
+ /* Reacquire the mutex (retaining the ret). */
+
+ sdbg("Re-locking...\n");
+ status = pthread_takesemaphore((sem_t*)&mutex->sem);
+ if (!status)
+ {
+ mutex->pid = mypid;
+ }
+ else if (!ret)
+ {
+ ret = status;
+ }
+ }
+
+ /* Re-enable pre-emption (It is expected that interrupts
+ * have already been re-enabled in the above logic)
+ */
+
+ sched_unlock();
+ }
+
+ /* We no longer need the watchdog */
+
+ wd_delete(wdog);
+ }
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
diff --git a/nuttx/sched/pthread_condwait.c b/nuttx/sched/pthread_condwait.c
new file mode 100644
index 000000000..bf0164d2d
--- /dev/null
+++ b/nuttx/sched/pthread_condwait.c
@@ -0,0 +1,137 @@
+/****************************************************************************
+ * sched/pthread_condwait.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <pthread.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: int pthread_cond_wait
+ *
+ * Description:
+ * A thread can wait for a condition variable to be signalled or broadcast.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex)
+{
+ int ret;
+
+ sdbg("cond=0x%p mutex=0x%p\n", cond, mutex);
+
+ /* Make sure that non-NULL references were provided. */
+
+ if (!cond || !mutex)
+ {
+ ret = EINVAL;
+ }
+
+ /* Make sure that the caller holds the mutex */
+
+ else if (mutex->pid != (int)getpid())
+ {
+ ret = EPERM;
+ }
+ else
+ {
+ /* Give up the mutex */
+
+ sdbg("Give up mutex / take cond\n");
+
+ sched_lock();
+ mutex->pid = 0;
+ ret = pthread_givesemaphore((sem_t*)&mutex->sem);
+
+ /* Take the semaphore */
+
+ ret |= pthread_takesemaphore((sem_t*)&cond->sem);
+ sched_unlock();
+
+ /* Reacquire the mutex */
+
+ sdbg("Reacquire mutex...\n");
+ ret |= pthread_takesemaphore((sem_t*)&mutex->sem);
+ if (!ret)
+ {
+ mutex->pid = getpid();;
+ }
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
diff --git a/nuttx/sched/pthread_create.c b/nuttx/sched/pthread_create.c
new file mode 100644
index 000000000..5fdf3b88d
--- /dev/null
+++ b/nuttx/sched/pthread_create.c
@@ -0,0 +1,435 @@
+/****************************************************************************
+ * sched/pthread_create.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <string.h>
+#include <pthread.h>
+#include <sched.h>
+#include <debug.h>
+#include <errno.h>
+#include <queue.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/pthread.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "clock_internal.h"
+#include "env_internal.h"
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/* Default pthread attributes */
+
+pthread_attr_t g_default_pthread_attr = PTHREAD_ATTR_INITIALIZER;
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/* This is the name for name-less pthreads */
+
+static const char g_pthreadname[] = "<pthread>";
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_argsetup
+ *
+ * Description:
+ * This functions sets up parameters in the Task Control Block (TCB) in
+ * preparation for starting a new thread.
+ *
+ * pthread_argsetup() is called from task_init() and task_start() to create
+ * a new task (with arguments cloned via strdup) or pthread_create() which
+ * has one argument passed by value (distinguished by the pthread boolean
+ * argument).
+ *
+ * Input Parameters:
+ * tcb - Address of the new task's TCB
+ * name - Name of the new task (not used)
+ * argv - A pointer to an array of input parameters. Up to
+ * CONFIG_MAX_TASK_ARG parameters may be provided. If fewer
+ * than CONFIG_MAX_TASK_ARG parameters are passed, the list
+ * should be terminated with a NULL argv[] value. If no
+ * parameters are required, argv may be NULL.
+ *
+ * Return Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void pthread_argsetup(FAR _TCB *tcb, pthread_addr_t arg)
+{
+ int i;
+
+#if CONFIG_TASK_NAME_SIZE > 0
+ /* Copy the pthread name into the TCB */
+
+ strncpy(tcb->name, g_pthreadname, CONFIG_TASK_NAME_SIZE);
+
+ /* Save the name as the first argument in the TCB */
+
+ tcb->argv[0] = tcb->name;
+#else
+ /* Save the name as the first argument in the TCB */
+
+ tcb->argv[0] = (char *)g_pthreadname;
+#endif /* CONFIG_TASK_NAME_SIZE */
+
+ /* For pthreads, args are strictly pass-by-value; that actual
+ * type wrapped by pthread_addr_t is unknown.
+ */
+
+ tcb->argv[1] = (char*)arg;
+
+ /* Nullify the remaining, unused argument storage */
+
+ for (i = 2; i < CONFIG_MAX_TASK_ARGS+1; i++)
+ {
+ tcb->argv[i] = NULL;
+ }
+}
+
+/****************************************************************************
+ * Name: pthread_addjoininfo
+ *
+ * Description:
+ * Add a join_t to the local data set.
+ *
+ * Parameters:
+ * pjoin
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * The caller has provided protection from re-entrancy.
+ *
+ ****************************************************************************/
+
+static void pthread_addjoininfo(FAR join_t *pjoin)
+{
+ pjoin->next = NULL;
+ if (!g_pthread_tail)
+ {
+ g_pthread_head = pjoin;
+ }
+ else
+ {
+ g_pthread_tail->next = pjoin;
+ }
+
+ g_pthread_tail = pjoin;
+}
+
+/****************************************************************************
+ * Name: pthread_start
+ *
+ * Description:
+ * This function is the low level entry point into the
+ * pthread
+ *
+ * Parameters:
+ * None
+ *
+ ****************************************************************************/
+
+static void pthread_start(void)
+{
+ FAR _TCB *ptcb = (FAR _TCB*)g_readytorun.head;
+ FAR join_t *pjoin = (FAR join_t*)ptcb->joininfo;
+ pthread_addr_t exit_status;
+
+ /* Sucessfully spawned, add the pjoin to our data set.
+ * Don't re-enable pre-emption until this is done.
+ */
+
+ (void)pthread_takesemaphore(&g_join_semaphore);
+ pthread_addjoininfo(pjoin);
+ (void)pthread_givesemaphore(&g_join_semaphore);
+
+ /* Report to the spawner that we successfully started. */
+
+ pjoin->started = true;
+ (void)pthread_givesemaphore(&pjoin->data_sem);
+
+ /* Pass control to the thread entry point. The argument is
+ * argv[1]. argv[0] (the thread name) and argv[2-4] are not made
+ * available to the pthread.
+ */
+
+ exit_status = (*ptcb->entry.pthread)((pthread_addr_t)ptcb->argv[1]);
+
+ /* The thread has returned */
+
+ pthread_exit(exit_status);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_create
+ *
+ * Description:
+ * This function creates and activates a new thread with a specified
+ * attributes.
+ *
+ * Input Parameters:
+ * thread
+ * attr
+ * start_routine
+ * arg
+ *
+ * Returned value:
+ * OK (0) on success; a (non-negated) errno value on failure. The errno
+ * variable is not set.
+ *
+ ****************************************************************************/
+
+int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
+ pthread_startroutine_t start_routine, pthread_addr_t arg)
+{
+ FAR _TCB *ptcb;
+ FAR join_t *pjoin;
+ int status;
+ int priority;
+#if CONFIG_RR_INTERVAL > 0
+ int policy;
+#endif
+ pid_t pid;
+
+ /* If attributes were not supplied, use the default attributes */
+
+ if (!attr)
+ {
+ attr = &g_default_pthread_attr;
+ }
+
+ /* Allocate a TCB for the new task. */
+
+ ptcb = (FAR _TCB*)kzalloc(sizeof(_TCB));
+ if (!ptcb)
+ {
+ return ENOMEM;
+ }
+
+ /* Associate file descriptors with the new task */
+
+ status = sched_setuppthreadfiles(ptcb);
+ if (status != OK)
+ {
+ sched_releasetcb(ptcb);
+ return status;
+ }
+
+ /* Share the parent's envionment */
+
+ (void)env_share(ptcb);
+
+ /* Allocate a detachable structure to support pthread_join logic */
+
+ pjoin = (FAR join_t*)kzalloc(sizeof(join_t));
+ if (!pjoin)
+ {
+ sched_releasetcb(ptcb);
+ return ENOMEM;
+ }
+
+ /* Allocate the stack for the TCB */
+
+ status = up_create_stack(ptcb, attr->stacksize);
+ if (status != OK)
+ {
+ sched_releasetcb(ptcb);
+ sched_free(pjoin);
+ return ENOMEM;
+ }
+
+ /* Should we use the priority and scheduler specified in the
+ * pthread attributes? Or should we use the current thread's
+ * priority and scheduler?
+ */
+
+ if (attr->inheritsched == PTHREAD_INHERIT_SCHED)
+ {
+ /* Get the priority for this thread. */
+
+ struct sched_param param;
+ status = sched_getparam(0, &param);
+ if (status == OK)
+ {
+ priority = param.sched_priority;
+ }
+ else
+ {
+ priority = SCHED_FIFO;
+ }
+
+ /* Get the scheduler policy for this thread */
+
+#if CONFIG_RR_INTERVAL > 0
+ policy = sched_getscheduler(0);
+ if (policy == ERROR)
+ {
+ policy = SCHED_FIFO;
+ }
+#endif
+ }
+ else
+ {
+ /* Use the priority and scheduler from the attributes */
+
+ priority = attr->priority;
+#if CONFIG_RR_INTERVAL > 0
+ policy = attr->policy;
+#endif
+ }
+
+ /* Mark this task as a pthread (this setting will be needed in
+ * task_schedsetup() when up_initial_state() is called.
+ */
+
+ ptcb->flags |= TCB_FLAG_TTYPE_PTHREAD;
+
+ /* Initialize the task control block */
+
+ status = task_schedsetup(ptcb, priority, pthread_start,
+ (main_t)start_routine);
+ if (status != OK)
+ {
+
+ sched_releasetcb(ptcb);
+ sched_free(pjoin);
+ return EBUSY;
+ }
+
+ /* Configure the TCB for a pthread receiving on parameter
+ * passed by value
+ */
+
+ pthread_argsetup(ptcb, arg);
+
+ /* Attach the join info to the TCB. */
+
+ ptcb->joininfo = (void*)pjoin;
+
+ /* If round robin scheduling is selected, set the appropriate flag
+ * in the TCB.
+ */
+
+#if CONFIG_RR_INTERVAL > 0
+ if (policy == SCHED_RR)
+ {
+ ptcb->flags |= TCB_FLAG_ROUND_ROBIN;
+ ptcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK;
+ }
+#endif
+
+ /* 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
+ * as well.
+ */
+
+ pid = (int)ptcb->pid;
+ pjoin->thread = (pthread_t)pid;
+
+ /* Initialize the semaphores in the join structure to zero. */
+
+ status = sem_init(&pjoin->data_sem, 0, 0);
+ if (status == OK)
+ {
+ status = sem_init(&pjoin->exit_sem, 0, 0);
+ }
+
+ /* Activate the task */
+
+ sched_lock();
+ if (status == OK)
+ {
+ status = task_activate(ptcb);
+ }
+
+ if (status == OK)
+ {
+ /* Wait for the task to actually get running and to register
+ * its join_t
+ */
+
+ (void)pthread_takesemaphore(&pjoin->data_sem);
+
+ /* Return the thread information to the caller */
+
+ if (thread) *thread = (pthread_t)pid;
+ if (!pjoin->started) status = ERROR;
+
+ sched_unlock();
+ (void)sem_destroy(&pjoin->data_sem);
+ }
+ else
+ {
+ sched_unlock();
+ dq_rem((FAR dq_entry_t*)ptcb, (dq_queue_t*)&g_inactivetasks);
+ (void)sem_destroy(&pjoin->data_sem);
+ (void)sem_destroy(&pjoin->exit_sem);
+ sched_releasetcb(ptcb);
+ sched_free(pjoin);
+ return EIO;
+ }
+
+ return OK;
+}
diff --git a/nuttx/sched/pthread_detach.c b/nuttx/sched/pthread_detach.c
new file mode 100644
index 000000000..a959d94b3
--- /dev/null
+++ b/nuttx/sched/pthread_detach.c
@@ -0,0 +1,137 @@
+/************************************************************************
+ * sched/pthread_detach.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "os_internal.h"
+#include "pthread_internal.h"
+
+/************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: pthread_detach
+ *
+ * Description:
+ * A thread object may be "detached" to specify that the return value
+ * and completion status will not be requested.
+ *
+ * Parameters:
+ * thread
+ *
+ * Return Value:
+ * 0 if successful. Otherwise, an error code.
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+int pthread_detach(pthread_t thread)
+{
+ FAR join_t *pjoin;
+ int ret;
+
+ sdbg("Thread=%d\n", thread);
+
+ /* Find the entry associated with this pthread. */
+
+ (void)pthread_takesemaphore(&g_join_semaphore);
+ pjoin = pthread_findjoininfo((pid_t)thread);
+ if (!pjoin)
+ {
+ sdbg("Could not find thread entry\n");
+ ret = EINVAL;
+ }
+ else
+ {
+ /* Has the thread already terminated? */
+
+ if (pjoin->terminated)
+ {
+ /* YES.. just remove the thread entry. */
+
+ pthread_destroyjoin(pjoin);
+ }
+ else
+ {
+ /* NO.. Just mark the thread as detached. It
+ * will be removed and deallocated when the
+ * thread exits
+ */
+
+ pjoin->detached = true;
+ }
+
+ /* Either case is successful */
+
+ ret = OK;
+ }
+
+ (void)pthread_givesemaphore(&g_join_semaphore);
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
diff --git a/nuttx/sched/pthread_exit.c b/nuttx/sched/pthread_exit.c
new file mode 100644
index 000000000..db51be78f
--- /dev/null
+++ b/nuttx/sched/pthread_exit.c
@@ -0,0 +1,137 @@
+/************************************************************************
+ * sched/pthread_exit.c
+ *
+ * Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "pthread_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: pthread_exit
+ *
+ * Description:
+ * Terminate execution of a thread started with pthread_create.
+ *
+ * Parameters:
+ * exit_valie
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+void pthread_exit(FAR void *exit_value)
+{
+ int error_code = (int)((intptr_t)exit_value);
+ int status;
+
+ sdbg("exit_value=%p\n", exit_value);
+
+ /* Block any signal actions that would awaken us while were
+ * are performing the JOIN handshake.
+ */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ {
+ sigset_t set = ALL_SIGNAL_SET;
+ (void)sigprocmask(SIG_SETMASK, &set, NULL);
+ }
+#endif
+
+ /* Complete pending join operations */
+
+ status = pthread_completejoin(getpid(), exit_value);
+ if (status != OK)
+ {
+ /* Assume that the join completion failured because this
+ * not really a pthread. Exit by calling exit() to flush
+ * and close all file descriptors and calling atexit()
+ * functions.
+ */
+
+ if (error_code == EXIT_SUCCESS)
+ {
+ error_code = EXIT_FAILURE;
+ }
+
+ exit(error_code);
+ }
+
+ /* Then just exit, retaining all file descriptors and without
+ * calling atexit() functions.
+ */
+
+ _exit(error_code);
+}
+
diff --git a/nuttx/sched/pthread_findjoininfo.c b/nuttx/sched/pthread_findjoininfo.c
new file mode 100644
index 000000000..584ed8f96
--- /dev/null
+++ b/nuttx/sched/pthread_findjoininfo.c
@@ -0,0 +1,101 @@
+/************************************************************************
+ * pthread_findjoininfo.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+
+#include "pthread_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: thread_findjoininfo
+ *
+ * Description:
+ * Find a join_t to the local data set.
+ *
+ * Parameters:
+ * pid
+ *
+ * Return Value:
+ * None or pointer to the found entry.
+ *
+ * Assumptions:
+ * The caller has provided protection from re-entrancy.
+ *
+ ************************************************************************/
+
+FAR join_t *pthread_findjoininfo(pid_t pid)
+{
+ FAR join_t *pjoin;
+
+ /* Find the entry with the matching pid */
+
+ for (pjoin = g_pthread_head;
+ (pjoin && (pid_t)pjoin->thread != pid);
+ pjoin = pjoin->next);
+
+ /* and return it */
+
+ return pjoin;
+}
+
diff --git a/nuttx/sched/pthread_getschedparam.c b/nuttx/sched/pthread_getschedparam.c
new file mode 100644
index 000000000..c376fd400
--- /dev/null
+++ b/nuttx/sched/pthread_getschedparam.c
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * pthread_getschedparam.c
+ *
+ * Copyright (C) 2007, 2008 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 <sys/types.h>
+#include <pthread.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ *****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_getschedparam
+ *
+ * Description:
+ * The pthread_getschedparam() functions will get the scheduling policy and
+ * parameters of threads. For SCHED_FIFO and SCHED_RR, the only required
+ * member of the sched_param structure is the priority sched_priority.
+ *
+ * The pthread_getschedparam() function will retrieve the scheduling
+ * policy and scheduling parameters for the thread whose thread ID is
+ * given by 'thread' and will store those values in 'policy' and 'param',
+ * respectively. The priority value returned from pthread_getschedparam()
+ * will be the value specified by the most recent pthread_setschedparam(),
+ * pthread_setschedprio(), or pthread_create() call affecting the target
+ * thread. It will not reflect any temporary adjustments to its priority
+ * (such as might result of any priority inheritance, for example).
+ *
+ * The policy parameter may have the value SCHED_FIFO, or SCHED_RR
+ * (SCHED_OTHER and SCHED_SPORADIC, in particular, are not supported).
+ * The SCHED_FIFO and SCHED_RR policies will have a single scheduling
+ * parameter, sched_priority.
+*
+ * Parameters:
+ * thread - The ID of thread whose scheduling parameters will be queried.
+ * policy - The location to store the thread's scheduling policy.
+ * param - The location to store the thread's priority.
+ *
+ * Return Value:
+ * 0 if successful. Otherwise, the error code ESRCH if the value specified
+ * by thread does not refer to an existing thread.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_getschedparam(pthread_t thread, FAR int *policy,
+ FAR struct sched_param *param)
+{
+ int ret;
+
+ sdbg("Thread ID=%d policy=0x%p param=0x%p\n", thread, policy, param);
+
+ if (!policy || !param)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ /* Get the schedparams of the thread. */
+
+ ret = sched_getparam((pid_t)thread, param);
+ if (ret != OK)
+ {
+ ret = EINVAL;
+ }
+
+ /* Return the policy. */
+
+ *policy = sched_getscheduler((pid_t)thread);
+ if (*policy == ERROR)
+ {
+ ret = get_errno();
+ }
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
diff --git a/nuttx/sched/pthread_getspecific.c b/nuttx/sched/pthread_getspecific.c
new file mode 100644
index 000000000..eeead14fa
--- /dev/null
+++ b/nuttx/sched/pthread_getspecific.c
@@ -0,0 +1,123 @@
+/************************************************************************
+ * sched/pthread_getspecific.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "os_internal.h"
+#include "pthread_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: pthread_getspecific
+ *
+ * Description:
+ * The pthread_getspecific() function returns the value currently
+ * bound to the specified key on behalf of the calling thread.
+ *
+ * The effect of calling pthread_getspecific() with with a key value
+ * not obtained from pthread_create() or after a key has been deleted
+ * with pthread_key_delete() is undefined.
+ *
+ * Parameters:
+ * key = The data key to get or set
+ *
+ * Return Value:
+ * The function pthread_getspecific() returns the thread-specific data
+ * associated with the given key. If no thread specific data is
+ * associated with the key, then the value NULL is returned.
+ *
+ * EINVAL - The key value is invalid.
+ *
+ * Assumptions:
+ *
+ * POSIX Compatibility:
+ * - Both calling pthread_setspecific() and pthread_getspecific()
+ * may be called from a thread-specific data destructor
+ * function.
+ *
+ ************************************************************************/
+
+FAR void *pthread_getspecific(pthread_key_t key)
+{
+#if CONFIG_NPTHREAD_KEYS > 0
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ FAR void *ret = NULL;
+
+ /* Check if the key is valid. */
+
+ if (key < g_pthread_num_keys)
+ {
+ /* Return the stored value. */
+
+ ret = rtcb->pthread_data[key];
+ }
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
diff --git a/nuttx/sched/pthread_initialize.c b/nuttx/sched/pthread_initialize.c
new file mode 100644
index 000000000..09db1d50e
--- /dev/null
+++ b/nuttx/sched/pthread_initialize.c
@@ -0,0 +1,198 @@
+/****************************************************************************
+ * sched/pthread_initialize.c
+ *
+ * Copyright (C) 2007-2010 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 <stdint.h>
+#include <semaphore.h>
+#include <errno.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/* This is the head of a private singly linked list. It
+ * is used to retain information about the spawned threads.
+ */
+
+FAR join_t *g_pthread_head = NULL;
+FAR join_t *g_pthread_tail = NULL;
+
+/* Mutually exclusive access to this data set is enforced with
+ * the following (un-named) semaphore.
+ */
+
+sem_t g_join_semaphore;
+
+/* This keys track of the number of global keys that have been
+ * allocated.
+ */
+
+uint8_t g_pthread_num_keys;
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_initialize
+ *
+ * Description:
+ * This is an internal OS function called only at power-up boot time.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void pthread_initialize(void)
+{
+ /* Initialize some global variables */
+
+ g_pthread_head = NULL;
+ g_pthread_tail = NULL;
+ g_pthread_num_keys = 0;
+
+ /* Initialize the join semaphore to one (to support one-at-
+ * a-time access to private data sets).
+ */
+
+ (void)sem_init(&g_join_semaphore, 0, 1);
+}
+
+/****************************************************************************
+ * Name: pthread_takesemaphore and pthread_givesemaphore
+ *
+ * Description:
+ * Support managed access to the private data sets.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * 0 on success or an ERROR on failure with errno value set to EINVAL.
+ * Note that the errno EINTR is never returned by this function.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_takesemaphore(sem_t *sem)
+{
+ /* Verify input parameters */
+
+ if (sem)
+ {
+ /* Take the semaphore */
+
+ while (sem_wait(sem) != OK)
+ {
+ /* Handle the special case where the semaphore wait was
+ * awakened by the receipt of a signal.
+ */
+
+ if (get_errno() != EINTR)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+ }
+ return OK;
+ }
+ else
+ {
+ /* NULL semaphore pointer! */
+
+ set_errno(EINVAL);
+ return ERROR;
+ }
+}
+
+int pthread_givesemaphore(sem_t *sem)
+{
+ /* Verify input parameters */
+
+ if (sem)
+ {
+ /* Give the semaphore */
+
+ if (sem_post(sem) == OK)
+ {
+ return OK;
+ }
+ else
+ {
+ /* sem_post() reported an error */
+
+ set_errno(EINVAL);
+ return ERROR;
+ }
+ }
+ else
+ {
+ /* NULL semaphore pointer! */
+
+ set_errno(EINVAL);
+ return ERROR;
+ }
+}
+
diff --git a/nuttx/sched/pthread_internal.h b/nuttx/sched/pthread_internal.h
new file mode 100644
index 000000000..ca70ab291
--- /dev/null
+++ b/nuttx/sched/pthread_internal.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+ * sched/pthread_internal.h
+ *
+ * Copyright (C) 2007-2009, 2011 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.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_PTHREAD_INTERNAL_H
+#define __SCHED_PTHREAD_INTERNAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <pthread.h>
+
+#include <nuttx/compiler.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Type Declarations
+ ****************************************************************************/
+
+/* The following defines an entry in the pthread logic's local data set.
+ * Note that this structure is used to implemented a singly linked list.
+ * This structure is used (instead of, say, a binary search tree) because
+ * the data set will be searched using the pid as a key -- a process IDs will
+ * always be created in a montonically increasing fashion.
+ */
+
+struct join_s
+{
+ FAR struct join_s *next; /* Implements link list */
+ uint8_t crefs; /* Reference count */
+ bool started; /* true: pthread started. */
+ bool detached; /* true: pthread_detached'ed */
+ bool terminated; /* true: detach'ed+exit'ed */
+ pthread_t thread; /* Includes pid */
+ sem_t exit_sem; /* Implements join */
+ sem_t data_sem; /* Implements join */
+ pthread_addr_t exit_value; /* Returned data */
+
+};
+
+typedef struct join_s join_t;
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/* This is the head of a private singly linked list. It is used to retain
+ * information about the spawned threads.
+ */
+
+extern FAR join_t *g_pthread_head;
+extern FAR join_t *g_pthread_tail;
+
+/* Mutually exclusive access to this data set is enforced with the following
+ * (un-named) semaphore.
+ */
+
+extern sem_t g_join_semaphore;
+
+/* This keys track of the number of global keys that have been allocated. */
+
+extern uint8_t g_pthread_num_keys;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+EXTERN void weak_function pthread_initialize(void);
+EXTERN int pthread_completejoin(pid_t pid, FAR void *exit_value);
+EXTERN void pthread_destroyjoin(FAR join_t *pjoin);
+EXTERN FAR join_t *pthread_findjoininfo(pid_t pid);
+EXTERN int pthread_givesemaphore(sem_t *sem);
+EXTERN FAR join_t *pthread_removejoininfo(pid_t pid);
+EXTERN int pthread_takesemaphore(sem_t *sem);
+
+#ifdef CONFIG_MUTEX_TYPES
+EXTERN int pthread_mutexattr_verifytype(int type);
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SCHED_PTHREAD_INTERNAL_H */
+
diff --git a/nuttx/sched/pthread_join.c b/nuttx/sched/pthread_join.c
new file mode 100644
index 000000000..6a02af352
--- /dev/null
+++ b/nuttx/sched/pthread_join.c
@@ -0,0 +1,248 @@
+/****************************************************************************
+ * pthread_join.c
+ *
+ * Copyright (C) 2007, 2008, 2011 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 <sys/types.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "os_internal.h"
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_join
+ *
+ * Description:
+ * A thread can await termination of another thread and retrieve the
+ * return value of the thread.
+ *
+ * Parameters:
+ * thread
+ * pexit_value
+ *
+ * Return Value:
+ * 0 if successful. Otherwise, one of the following error codes:
+ *
+ * EINVAL The value specified by thread does not refer to ajoinable
+ * thread.
+ * ESRCH No thread could be found corresponding to thatspecified by the
+ * given thread ID.
+ * EDEADLK A deadlock was detected or the value of thread specifies the
+ * calling thread.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
+{
+ FAR join_t *pjoin;
+ int ret;
+
+ sdbg("thread=%d\n", thread);
+
+ /* First make sure that this is not an attempt to join to
+ * ourself.
+ */
+
+ if ((pid_t)thread == getpid())
+ {
+ return EDEADLK;
+ }
+
+ /* Make sure no other task is mucking with the data structures
+ * while we are performing the following operations. NOTE:
+ * we can be also sure that pthread_exit() will not execute
+ * because it will also attempt to get this semaphore.
+ */
+
+ (void)pthread_takesemaphore(&g_join_semaphore);
+
+ /* Find the join information associated with this thread.
+ * This can fail for one of three reasons: (1) There is no
+ * thread associated with 'thread,' (2) the thread is a task
+ * and does not have join information, or (3) the thread
+ * was detached and has exitted.
+ */
+
+ pjoin = pthread_findjoininfo((pid_t)thread);
+ if (!pjoin)
+ {
+ /* Determine what kind of error to return */
+
+ FAR _TCB *tcb = sched_gettcb((pthread_t)thread);
+
+ sdbg("Could not find thread data\n");
+
+ /* Case (1) or (3) -- we can't tell which. Assume (3) */
+
+ if (!tcb)
+ {
+ ret = ESRCH;
+ }
+
+ /* The thread is still active but has no join info. In that
+ * case, it must be a task and not a pthread.
+ */
+
+ else
+ {
+ ret = EINVAL;
+ }
+
+ (void)pthread_givesemaphore(&g_join_semaphore);
+ }
+ else
+ {
+ /* We found the join info structure. Increment for the reference
+ * to the join structure that we have. This will keep things
+ * stable for we have to do
+ */
+
+ sched_lock();
+ pjoin->crefs++;
+
+ /* Check if the thread is still running. If not, then things are
+ * simpler. There are still race conditions to be concerned with.
+ * For example, there could be multiple threads executing in the
+ * 'else' block below when we enter!
+ */
+
+ if (pjoin->terminated)
+ {
+ sdbg("Thread has terminated\n");
+
+ /* Get the thread exit value from the terminated thread. */
+
+ if (pexit_value)
+ {
+ sdbg("exit_value=0x%p\n", pjoin->exit_value);
+ *pexit_value = pjoin->exit_value;
+ }
+ }
+ else
+ {
+ sdbg("Thread is still running\n");
+
+ /* Relinquish the data set semaphore. Since pre-emption is
+ * disabled, we can be certain that no task has the
+ * opportunity to run between the time we relinquish the
+ * join semaphore and the time that we wait on the thread exit
+ * semaphore.
+ */
+
+ (void)pthread_givesemaphore(&g_join_semaphore);
+
+ /* Take the thread's thread exit semaphore. We will sleep here
+ * until the thread exits. We need to exercise caution because
+ * there could be multiple threads waiting here for the same
+ * pthread to exit.
+ */
+
+ (void)pthread_takesemaphore(&pjoin->exit_sem);
+
+ /* The thread has exited! Get the thread exit value */
+
+ if (pexit_value)
+ {
+ *pexit_value = pjoin->exit_value;
+ sdbg("exit_value=0x%p\n", pjoin->exit_value);
+ }
+
+ /* Post the thread's data semaphore so that the exitting thread
+ * will know that we have received the data.
+ */
+
+ (void)pthread_givesemaphore(&pjoin->data_sem);
+
+ /* Retake the join semaphore, we need to hold this when
+ * pthread_destroyjoin is called.
+ */
+
+ (void)pthread_takesemaphore(&g_join_semaphore);
+ }
+
+ /* Pre-emption is okay now. The logic still cannot be re-entered
+ * because we hold the join semaphore
+ */
+
+ sched_unlock();
+
+ /* Release our reference to the join structure and, if the reference
+ * count decrements to zero, deallocate the join structure.
+ */
+
+ if (--pjoin->crefs <= 0)
+ {
+ (void)pthread_destroyjoin(pjoin);
+ }
+
+ (void)pthread_givesemaphore(&g_join_semaphore);
+ ret = OK;
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
diff --git a/nuttx/sched/pthread_keycreate.c b/nuttx/sched/pthread_keycreate.c
new file mode 100644
index 000000000..7579e4c11
--- /dev/null
+++ b/nuttx/sched/pthread_keycreate.c
@@ -0,0 +1,135 @@
+/****************************************************************************
+ * sched/pthread_keycreate.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_key_create
+ *
+ * Description:
+ * This function creates a thread-specific data key visible to all threads
+ * in the system. Although the same key value may be used by different
+ * threads, the values bound to the key by pthread_setspecific() are
+ * maintained on a per-thread basis and persist for the life of the calling
+ * thread.
+ *
+ * Upon key creation, the value NULL will be associated with the new key
+ * in all active threads. Upon thread creation, the value NULL will be
+ * associated with all defined keys in the new thread.
+ *
+ * Parameters:
+ * key = A pointer to the key to create.
+ * destructor = An optional destructor() function that may be associated
+ * with each key that is invoked when a thread exits. However, this
+ * argument is ignored in the current implementation.
+ *
+ * Return Value:
+ * If successful, the pthread_key_create() function will store the newly
+ * created key value at *key and return zero (OK). Otherwise, an error
+ * number will bereturned to indicate the error:
+ *
+ * EAGAIN - The system lacked sufficient resources to create another
+ * thread-specific data key, or the system-imposed limit on the total
+ * number of keys pers process {PTHREAD_KEYS_MAX} has been exceeded
+ * ENONMEM - Insufficient memory exists to create the key.
+ *
+ * Assumptions:
+ *
+ * POSIX Compatibility:
+ * - The present implementation ignores the destructor argument.
+ *
+ ****************************************************************************/
+
+int pthread_key_create(FAR pthread_key_t *key, CODE void (*destructor)(void*))
+{
+#if CONFIG_NPTHREAD_KEYS > 0
+ int ret = EAGAIN;
+
+ /* Check if we have exceeded the system-defined number of keys. */
+
+ if (g_pthread_num_keys < PTHREAD_KEYS_MAX)
+ {
+ /* Return the key value */
+
+ *key = g_pthread_num_keys;
+
+ /* Increment the count of global keys. */
+
+ g_pthread_num_keys++;
+
+ /* Return success. */
+
+ ret = OK;
+ }
+
+ return ret;
+#else
+ return ENOSYS;
+#endif
+}
diff --git a/nuttx/sched/pthread_keydelete.c b/nuttx/sched/pthread_keydelete.c
new file mode 100644
index 000000000..d55a448ed
--- /dev/null
+++ b/nuttx/sched/pthread_keydelete.c
@@ -0,0 +1,96 @@
+/************************************************************************
+ * sched/pthread_keydelete.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: pthread_key_delete
+ *
+ * Description:
+ * This POSIX function should delete a thread-specific data key
+ * previously returned by pthread_key_create(). However, this function
+ * does nothing in the present implementation.
+ *
+ * Parameters:
+ * key = the key to delete
+ *
+ * Return Value:
+ * Always returns ENOSYSL.
+ *
+ * Assumptions:
+ *
+ * POSIX Compatibility:
+ *
+ ************************************************************************/
+
+int pthread_key_delete(pthread_key_t key)
+{
+ return ENOSYS;
+}
+
diff --git a/nuttx/sched/pthread_kill.c b/nuttx/sched/pthread_kill.c
new file mode 100644
index 000000000..5a1506c0c
--- /dev/null
+++ b/nuttx/sched/pthread_kill.c
@@ -0,0 +1,95 @@
+/************************************************************************
+ * sched/pthread_kill.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <signal.h>
+#include <pthread.h>
+#include <errno.h>
+#include <debug.h>
+
+/************************************************************************
+ * Global Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: pthread_kill
+ *
+ * Description:
+ * The pthread_kill() system call can be used to send any signal to a
+ * thread. See kill() for further information as this is just a simple
+ * wrapper around the kill() function.
+ *
+ * Parameters:
+ * thread - The id of the thread to receive the signal. Only positive,
+ * non-zero values of 'thread' are supported.
+ * signo - The signal number to send. If 'signo' is zero, no signal is
+ * sent, but all error checking is performed.
+ *
+ * Return Value:
+ * On success the signal was send and zero is returned. On error one
+ * of the following error numbers is returned.
+ *
+ * EINVAL An invalid signal was specified.
+ * EPERM The thread does not have permission to send the
+ * signal to the target thread.
+ * ESRCH No thread could be found corresponding to that
+ * specified by the given thread ID
+ * ENOSYS Do not support sending signals to process groups.
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+int pthread_kill(pthread_t thread, int signo)
+{
+ int ret;
+
+ set_errno(EINVAL);
+ ret = kill((pid_t)thread, signo);
+ if (ret != OK)
+ {
+ ret = get_errno();
+ }
+
+ return ret;
+}
+
+
diff --git a/nuttx/sched/pthread_mutexdestroy.c b/nuttx/sched/pthread_mutexdestroy.c
new file mode 100644
index 000000000..f66358534
--- /dev/null
+++ b/nuttx/sched/pthread_mutexdestroy.c
@@ -0,0 +1,131 @@
+/****************************************************************************
+ * sched/pthread_mutexdestroy.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_mutex_destroy
+ *
+ * Description:
+ * Destroy a mutex.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_mutex_destroy(FAR pthread_mutex_t *mutex)
+{
+ int ret = OK;
+ int status;
+
+ sdbg("mutex=0x%p\n", mutex);
+
+ if (!mutex)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ /* Make sure the semaphore is stable while we make the following
+ * checks
+ */
+
+ sched_lock();
+
+ /* Is the semaphore available? */
+
+ if (mutex->pid != 0)
+ {
+ ret = EBUSY;
+ }
+ else
+ {
+ /* Destroy the semaphore */
+
+ status = sem_destroy((sem_t*)&mutex->sem);
+ if (status != OK)
+ {
+ ret = EINVAL;
+ }
+ }
+
+ sched_unlock();
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
diff --git a/nuttx/sched/pthread_mutexinit.c b/nuttx/sched/pthread_mutexinit.c
new file mode 100644
index 000000000..265f014e3
--- /dev/null
+++ b/nuttx/sched/pthread_mutexinit.c
@@ -0,0 +1,138 @@
+/****************************************************************************
+ * sched/pthread_mutexinit.c
+ *
+ * Copyright (C) 2007-2009, 2011 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 <stdint.h>
+#include <pthread.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_mutex_init
+ *
+ * Description:
+ * Create a mutex
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_mutex_init(FAR pthread_mutex_t *mutex, FAR pthread_mutexattr_t *attr)
+{
+ int pshared = 0;
+#ifdef CONFIG_MUTEX_TYPES
+ uint8_t type = PTHREAD_MUTEX_DEFAULT;
+#endif
+ int ret = OK;
+ int status;
+
+ sdbg("mutex=0x%p attr=0x%p\n", mutex, attr);
+
+ if (!mutex)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ /* Were attributes specified? If so, use them */
+
+ if (attr)
+ {
+ pshared = attr->pshared;
+#ifdef CONFIG_MUTEX_TYPES
+ type = attr->type;
+#endif
+ }
+
+ /* Indicate that the semaphore is not held by any thread. */
+
+ mutex->pid = 0;
+
+ /* Initialize the mutex like a semaphore with initial count = 1 */
+
+ status = sem_init((sem_t*)&mutex->sem, pshared, 1);
+ if (status != OK)
+ {
+ ret = EINVAL;
+ }
+
+ /* Set up attributes unique to the mutex type */
+
+#ifdef CONFIG_MUTEX_TYPES
+ mutex->type = type;
+ mutex->nlocks = 0;
+#endif
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
diff --git a/nuttx/sched/pthread_mutexlock.c b/nuttx/sched/pthread_mutexlock.c
new file mode 100644
index 000000000..7681d771a
--- /dev/null
+++ b/nuttx/sched/pthread_mutexlock.c
@@ -0,0 +1,187 @@
+/****************************************************************************
+ * sched/pthread_mutexlock.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <pthread.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_mutex_lock
+ *
+ * Description:
+ * The mutex object referenced by mutex is locked by calling
+ * pthread_mutex_lock(). If the mutex is already locked, the calling thread
+ * blocks until the mutex becomes available. This operation returns with the
+ * mutex object referenced by mutex in the locked state with the calling
+ * thread as its owner.
+ *
+ * If the mutex type is PTHREAD_MUTEX_NORMAL, deadlock detection is not
+ * provided. Attempting to relock the mutex causes deadlock. If a thread
+ * attempts to unlock a mutex that it has not locked or a mutex which is
+ * unlocked, undefined behavior results.
+ *
+ * If the mutex type is PTHREAD_MUTEX_ERRORCHECK, then error checking is
+ * provided. If a thread attempts to relock a mutex that it has already
+ * locked, an error will be returned. If a thread attempts to unlock a
+ * mutex that it has not locked or a mutex which is unlocked, an error will
+ * be returned.
+ *
+ * If the mutex type is PTHREAD_MUTEX_RECURSIVE, then the mutex maintains
+ * the concept of a lock count. When a thread successfully acquires a mutex
+ * for the first time, the lock count is set to one. Every time a thread
+ * relocks this mutex, the lock count is incremented by one. Each time the
+ * thread unlocks the mutex, the lock count is decremented by one. When the
+ * lock count reaches zero, the mutex becomes available for other threads to
+ * acquire. If a thread attempts to unlock a mutex that it has not locked or
+ * a mutex which is unlocked, an error will be returned.
+ *
+ * If a signal is delivered to a thread waiting for a mutex, upon return
+ * from the signal handler the thread resumes waiting for the mutex as if
+ * it was not interrupted.
+ *
+ * Parameters:
+ * mutex - A reference to the mutex to be locked.
+ *
+ * Return Value:
+ * 0 on success or an errno value on failure. Note that the errno EINTR
+ * is never returned by pthread_mutex_lock().
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_mutex_lock(FAR pthread_mutex_t *mutex)
+{
+ int mypid = (int)getpid();
+ int ret = OK;
+
+ sdbg("mutex=0x%p\n", mutex);
+
+ if (!mutex)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ /* Make sure the semaphore is stable while we make the following
+ * checks. This all needs to be one atomic action.
+ */
+
+ sched_lock();
+
+ /* Does this task already hold the semaphore? */
+
+ if (mutex->pid == mypid)
+ {
+ /* Yes.. Is this a recursive mutex? */
+
+#ifdef CONFIG_MUTEX_TYPES
+ if (mutex->type == PTHREAD_MUTEX_RECURSIVE)
+ {
+ /* Yes... just increment the number of locks held and return success */
+
+ mutex->nlocks++;
+ }
+ else
+#endif
+ {
+ /* No, then we would deadlock... return an error (default behavior
+ * is like PTHREAD_MUTEX_ERRORCHECK)
+ */
+
+ sdbg("Returning EDEADLK\n");
+ ret = EDEADLK;
+ }
+ }
+ else
+ {
+ /* Take the semaphore */
+
+ ret = pthread_takesemaphore((sem_t*)&mutex->sem);
+
+ /* If we succussfully obtained the semaphore, then indicate
+ * that we own it.
+ */
+
+ if (!ret)
+ {
+ mutex->pid = mypid;
+#ifdef CONFIG_MUTEX_TYPES
+ mutex->nlocks = 1;
+#endif
+ }
+ }
+
+ sched_unlock();
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
diff --git a/nuttx/sched/pthread_mutextrylock.c b/nuttx/sched/pthread_mutextrylock.c
new file mode 100644
index 000000000..d88012b51
--- /dev/null
+++ b/nuttx/sched/pthread_mutextrylock.c
@@ -0,0 +1,147 @@
+/****************************************************************************
+ * sched/pthread_mutextrylock.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_mutex_trylock
+ *
+ * Description:
+ * The function pthread_mutex_trylock() is identical to pthread_mutex_lock()
+ * except that if the mutex object referenced by mutex is currently locked
+ * (by any thread, including the current thread), the call returns immediately
+ * with the errno EBUSY.
+ *
+ * If a signal is delivered to a thread waiting for a mutex, upon return from
+ * the signal handler the thread resumes waiting for the mutex as if it was
+ * not interrupted.
+ *
+ * Parameters:
+ * mutex - A reference to the mutex to be locked.
+ *
+ * Return Value:
+ * 0 on success or an errno value on failure. Note that the errno EINTR
+ * is never returned by pthread_mutex_lock().
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_mutex_trylock(FAR pthread_mutex_t *mutex)
+{
+ int ret = OK;
+
+ sdbg("mutex=0x%p\n", mutex);
+
+ if (!mutex)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ /* Make sure the semaphore is stable while we make the following
+ * checks. This all needs to be one atomic action.
+ */
+
+ sched_lock();
+
+ /* Try to get the semaphore. */
+
+ if (sem_trywait((sem_t*)&mutex->sem) == OK)
+ {
+ /* If we succussfully obtained the semaphore, then indicate
+ * that we own it.
+ */
+
+ mutex->pid = (int)getpid();
+ }
+
+ /* Was it not available? */
+
+ else if (get_errno() == EAGAIN)
+ {
+ ret = EBUSY;
+ }
+ else
+ {
+ ret = EINVAL;
+ }
+
+ sched_unlock();
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
+
+
diff --git a/nuttx/sched/pthread_mutexunlock.c b/nuttx/sched/pthread_mutexunlock.c
new file mode 100644
index 000000000..34846f952
--- /dev/null
+++ b/nuttx/sched/pthread_mutexunlock.c
@@ -0,0 +1,164 @@
+/****************************************************************************
+ * sched/pthread_mutexunlock.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <pthread.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_mutex_unlock
+ *
+ * Description:
+ * The pthread_mutex_unlock() function releases the mutex object referenced
+ * by mutex. The manner in which a mutex is released is dependent upon the
+ * mutex's type attribute. If there are threads blocked on the mutex object
+ * referenced by mutex when pthread_mutex_unlock() is called, resulting in
+ * the mutex becoming available, the scheduling policy is used to determine
+ * which thread shall acquire the mutex. (In the case of PTHREAD_MUTEX_RECURSIVE
+ * mutexes, the mutex becomes available when the count reaches zero and the
+ * calling thread no longer has any locks on this mutex).
+ *
+ * If a signal is delivered to a thread waiting for a mutex, upon return from
+ * the signal handler the thread resumes waiting for the mutex as if it was
+ * not interrupted.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_mutex_unlock(FAR pthread_mutex_t *mutex)
+{
+ int ret = OK;
+
+ sdbg("mutex=0x%p\n", mutex);
+
+ if (!mutex)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+ /* Make sure the semaphore is stable while we make the following
+ * checks. This all needs to be one atomic action.
+ */
+
+ sched_lock();
+
+ /* Does the calling thread own the semaphore? */
+
+ if (mutex->pid != (int)getpid())
+ {
+ /* No... return an error (default behavior is like PTHREAD_MUTEX_ERRORCHECK) */
+
+ sdbg("Holder=%d returning EPERM\n", mutex->pid);
+ ret = EPERM;
+ }
+
+
+ /* Yes, the caller owns the semaphore.. Is this a recursive mutex? */
+
+#ifdef CONFIG_MUTEX_TYPES
+ else if (mutex->type == PTHREAD_MUTEX_RECURSIVE && mutex->nlocks > 1)
+ {
+ /* This is a recursive mutex and we there are multiple locks held. Retain
+ * the mutex lock, just decrement the count of locks held, and return
+ * success.
+ */
+ mutex->nlocks--;
+ }
+#endif
+
+ /* This is either a non-recursive mutex or is the outermost unlock of
+ * a recursive mutex.
+ */
+
+ else
+ {
+ /* Nullify the pid and lock count then post the semaphore */
+
+ mutex->pid = 0;
+#ifdef CONFIG_MUTEX_TYPES
+ mutex->nlocks = 0;
+#endif
+ ret = pthread_givesemaphore((sem_t*)&mutex->sem);
+ }
+ sched_unlock();
+ }
+
+ sdbg("Returning %d\n", ret);
+ return ret;
+}
+
+
diff --git a/nuttx/sched/pthread_once.c b/nuttx/sched/pthread_once.c
new file mode 100644
index 000000000..413300472
--- /dev/null
+++ b/nuttx/sched/pthread_once.c
@@ -0,0 +1,128 @@
+/********************************************************************************
+ * sched/pthread_once.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ********************************************************************************/
+
+/********************************************************************************
+ * Included Files
+ ********************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <pthread.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+/********************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Type Declarations
+ ********************************************************************************/
+
+/********************************************************************************
+ * Global Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Function Prototypes
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: pthread_once
+ *
+ * Description:
+ * The first call to pthread_once() by any thread with a given once_control,
+ * will call the init_routine with no arguments. Subsequent calls to
+ * pthread_once() with the same once_control will have no effect. On return
+ * from pthread_once(), init_routine will have completed.
+ *
+ * Parameters:
+ * once_control - Determines if init_routine should be called. once_control
+ * should be declared and intialized as follows:
+ *
+ * pthread_once_t once_control = PTHREAD_ONCE_INIT;
+ *
+ * PTHREAD_ONCE_INIT is defined in pthread.h
+ * init_routine - The initialization routine that will be called once.
+ *
+ * Return Value:
+ * 0 (OK) on success or EINVAL if either once_control or init_routine are
+ * invalid
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int pthread_once(FAR pthread_once_t *once_control,
+ CODE void (*init_routine)(void))
+{
+ /* Sanity checks */
+
+ if (once_control && init_routine)
+ {
+ /* Prohibit pre-emption while we test and set the once_control */
+
+ sched_lock();
+ if (!*once_control)
+ {
+ *once_control = true;
+
+ /* Call the init_routine with pre-emption enabled. */
+
+ sched_unlock();
+ init_routine();
+ return OK;
+ }
+
+ /* The init_routine has already been called. Restore pre-emption and return */
+
+ sched_unlock();
+ return OK;
+ }
+
+ /* One of the two arguments is NULL */
+
+ return EINVAL;
+}
diff --git a/nuttx/sched/pthread_removejoininfo.c b/nuttx/sched/pthread_removejoininfo.c
new file mode 100644
index 000000000..defc02991
--- /dev/null
+++ b/nuttx/sched/pthread_removejoininfo.c
@@ -0,0 +1,137 @@
+/************************************************************************
+ * sched/pthread_removejoininfo.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <sys/types.h>
+#include "pthread_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: pthread_removejoininfo
+ *
+ * Description:
+ * Remove a join_t from the local data set.
+ *
+ * Parameters:
+ * pid
+ *
+ * Return Value:
+ * None or pointer to the found entry.
+ *
+ * Assumptions:
+ * The caller has provided protection from re-entrancy.
+ *
+ ************************************************************************/
+
+FAR join_t *pthread_removejoininfo(pid_t pid)
+{
+ FAR join_t *prev;
+ FAR join_t *join;
+
+ /* Find the entry with the matching pid */
+
+ for (prev = NULL, join = g_pthread_head;
+ (join && (pid_t)join->thread != pid);
+ prev = join, join = join->next);
+
+ /* Remove it from the data set. */
+
+ /* First check if this is the entry at the head of the list. */
+
+ if (join)
+ {
+ if (!prev)
+ {
+ /* Check if this is the only entry in the list */
+
+ if (!join->next)
+ {
+ g_pthread_head = NULL;
+ g_pthread_tail = NULL;
+ }
+
+ /* Otherwise, remove it from the head of the list */
+
+ else
+ {
+ g_pthread_head = join->next;
+ }
+ }
+
+ /* It is not at the head of the list, check if it is at the tail. */
+
+ else if (!join->next)
+ {
+ g_pthread_tail = prev;
+ prev->next = NULL;
+ }
+
+ /* No, remove it from the middle of the list. */
+
+ else
+ {
+ prev->next = join->next;
+ }
+ }
+
+ return join;
+}
+
diff --git a/nuttx/sched/pthread_setcancelstate.c b/nuttx/sched/pthread_setcancelstate.c
new file mode 100644
index 000000000..2c6bf3083
--- /dev/null
+++ b/nuttx/sched/pthread_setcancelstate.c
@@ -0,0 +1,131 @@
+/******************************************************************************************
+ * pthread_setcancelstate.c
+ *
+ * Copyright (C) 2007, 2008 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 <pthread.h>
+#include <errno.h>
+#include "os_internal.h"
+
+/******************************************************************************************
+ * Private Definitions
+ ******************************************************************************************/
+
+/******************************************************************************************
+ * Private Types
+ ******************************************************************************************/
+
+/******************************************************************************************
+ * Private Function Prototypes
+ ******************************************************************************************/
+
+/******************************************************************************************
+ * Global Variables
+ ******************************************************************************************/
+
+/******************************************************************************************
+ * Private Variables
+ ******************************************************************************************/
+
+/******************************************************************************************
+ * Private Functions
+ ******************************************************************************************/
+
+/******************************************************************************************
+ * Public Functions
+ ******************************************************************************************/
+
+/******************************************************************************************
+ * Name: pthread_setcancelstate
+ ******************************************************************************************/
+
+int pthread_setcancelstate(int state, FAR int *oldstate)
+{
+ _TCB *tcb = (_TCB*)g_readytorun.head;
+ 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 state if so requrested */
+
+ if (oldstate)
+ {
+ if ((tcb->flags & TCB_FLAG_NONCANCELABLE) != 0)
+ {
+ *oldstate = PTHREAD_CANCEL_DISABLE;
+ }
+ else
+ {
+ *oldstate = PTHREAD_CANCEL_ENABLE;
+ }
+ }
+
+ /* Set the new cancellation state */
+
+ if (state == PTHREAD_CANCEL_ENABLE)
+ {
+ unsigned flags = tcb->flags;
+
+ /* Clear the non-cancelable and cancel pending flags */
+
+ tcb->flags &= ~(TCB_FLAG_NONCANCELABLE|TCB_FLAG_CANCEL_PENDING);
+
+ /* If the cancel was pending, then just exit as requested */
+
+ if (flags & TCB_FLAG_CANCEL_PENDING)
+ {
+ pthread_exit(PTHREAD_CANCELED);
+ }
+ }
+ else if (state == PTHREAD_CANCEL_DISABLE)
+ {
+ /* Set the non-cancelable state */
+
+ tcb->flags |= TCB_FLAG_NONCANCELABLE;
+ }
+ else
+ {
+ ret = EINVAL;
+ }
+
+ sched_unlock();
+ return ret;
+}
diff --git a/nuttx/sched/pthread_setschedparam.c b/nuttx/sched/pthread_setschedparam.c
new file mode 100644
index 000000000..019a7c7a5
--- /dev/null
+++ b/nuttx/sched/pthread_setschedparam.c
@@ -0,0 +1,142 @@
+/****************************************************************************
+ * pthread_setschedparam.c
+ *
+ * Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_setschedparam
+ *
+ * Description:
+ * The pthread_setschedparam() functions will set the scheduling policy
+ * and parameters of threads. For SCHED_FIFO and SCHED_RR, the only
+ * required member of the sched_param structure is the priority
+ * sched_priority.
+ *
+ * The pthread_setschedparam() function will set the scheduling policy
+ * and associated scheduling parameters for the thread whose thread ID
+ * is given by 'thread' to the policy and associated parameters provided
+ * in 'policy' and 'param', respectively.
+ *
+ * The policy parameter may have the value SCHED_FIFO, or SCHED_RR
+ * (SCHED_OTHER and SCHED_SPORADIC, in particular, are not supported).
+ * The SCHED_FIFO and SCHED_RR policies will have a single scheduling
+ * parameter, sched_priority.
+ *
+ * If the pthread_setschedparam() function fails, the scheduling parameters
+ * will not be changed for the target thread.
+ *
+ * Parameters:
+ * thread - The ID of thread whose scheduling parameters will be modified.
+ * policy - The new scheduling policy of the thread. Either SCHED_FIFO or
+ * SCHED_RR. SCHED_OTHER and SCHED_SPORADIC are not supported.
+ * param - Provides the new priority of the thread.
+ *
+ * Return Value:
+ * 0 if successful. Otherwise, an error code identifying the cause of the
+ * failure:
+ *
+ * EINVAL The value specified by 'policy' or one of the scheduling
+ * parameters associated with the scheduling policy 'policy' is
+ * invalid.
+ * ENOTSUP An attempt was made to set the policy or scheduling parameters
+ * to an unsupported value (SCHED_OTHER and SCHED_SPORADIC in
+ * particular are not supported)
+ * EPERM The caller does not have the appropriate permission to set either
+ * the scheduling parameters or the scheduling policy of the
+ * specified thread. Or, the implementation does not allow the
+ * application to modify one of the parameters to the value
+ * specified.
+ * ESRCH The value specified by thread does not refer to a existing thread.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_setschedparam(pthread_t thread, int policy, FAR const struct sched_param *param)
+{
+ int ret;
+
+ sdbg("thread ID=%d policy=%d param=0x%p\n", thread, policy, param);
+
+ /* Set the errno to some non-zero value (failsafe) */
+
+ set_errno(EINVAL);
+
+ /* Let sched_setscheduler do all of the work */
+
+ ret = sched_setscheduler((pid_t)thread, policy, param);
+ if (ret != OK)
+ {
+ /* If sched_setscheduler() fails, return the errno */
+
+ ret = get_errno();
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/pthread_setschedprio.c b/nuttx/sched/pthread_setschedprio.c
new file mode 100644
index 000000000..a523b20ea
--- /dev/null
+++ b/nuttx/sched/pthread_setschedprio.c
@@ -0,0 +1,120 @@
+/****************************************************************************
+ * pthread_schedsetprio.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+#include <sched.h>
+#include <errno.h>
+#include <nuttx/arch.h>
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_setsetprio
+ *
+ * Description:
+ * The pthread_setschedprio() function sets the scheduling priority for the
+ * thread whose thread ID is given by 'thread' to the value given by 'prio'.
+ * If the thread_setschedprio() function fails, the scheduling priority
+ * of the target thread will not be changed.
+ *
+ * Inputs:
+ * thread - the thread ID of the task to reprioritize.
+ * prio - The new thread priority. The range of valid priority numbers is
+ * from SCHED_PRIORITY_MIN through SCHED_PRIORITY_MAX.
+ *
+ * Return Value:
+ * OK if successful, otherwise an error number. This function can
+ * fail for the following reasons:
+ *
+ * EINVAL - prio is out of range.
+ * ESRCH - thread ID does not correspond to any thread.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int pthread_setschedprio(pthread_t thread, int prio)
+{
+ struct sched_param param;
+ int ret;
+
+ /* Set the errno to some non-zero value (failsafe) */
+
+ errno = EINVAL;
+
+ /* Call sched_setparam() to change the priority */
+
+ param.sched_priority = prio;
+ ret = sched_setparam((pid_t)thread, &param);
+ if (ret != OK)
+ {
+ /* If sched_setparam() fails, return the errno */
+
+ ret = errno;
+ }
+ return ret;
+}
diff --git a/nuttx/sched/pthread_setspecific.c b/nuttx/sched/pthread_setspecific.c
new file mode 100644
index 000000000..33fb4aeeb
--- /dev/null
+++ b/nuttx/sched/pthread_setspecific.c
@@ -0,0 +1,137 @@
+/****************************************************************************
+ * sched/pthread_setspecific.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+#include "os_internal.h"
+#include "pthread_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pthread_setspecific
+ *
+ * Description:
+ * The pthread_setspecific() function associates a thread-
+ * specific value with a key obtained via a previous call
+ * to pthread_key_create(). Different threads may bind
+ * different values to the same key. These values are
+ * typically pointers to blocks of dynamically allocated
+ * memory that have been reserved for use by the calling
+ * thread.
+ *
+ * The effect of calling pthread_setspecific() with
+ * with a key value not obtained from pthread_create() or
+ * after a key has been deleted with pthread_key_delete()
+ * is undefined.
+ *
+ * Parameters:
+ * key = The data key to get or set
+ * value = The value to bind to the key.
+ *
+ * Return Value:
+ * If successful, pthread_setspecific() will return zero (OK).
+ * Otherwise, an error number will be returned:
+ *
+ * ENOMEM - Insufficient memory exists to associate
+ * the value with the key.
+ * EINVAL - The key value is invalid.
+ *
+ * Assumptions:
+ *
+ * POSIX Compatibility:
+ * int pthread_setspecific(pthread_key_t key, void *value)
+ * void *pthread_getspecific(pthread_key_t key)
+ *
+ * - Both calling pthread_setspecific() and pthread_getspecific()
+ * may be called from a thread-specific data destructor
+ * function.
+ *
+ ****************************************************************************/
+
+int pthread_setspecific(pthread_key_t key, FAR void *value)
+{
+#if CONFIG_NPTHREAD_KEYS > 0
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ int ret = EINVAL;
+
+ /* Check if the key is valid. */
+
+ if (key < g_pthread_num_keys)
+ {
+ /* Store the data in the TCB. */
+
+ rtcb->pthread_data[key] = value;
+
+ /* Return success. */
+
+ ret = OK;
+ }
+
+ return ret;
+#else
+ return ENOSYS;
+#endif
+}
+
diff --git a/nuttx/sched/pthread_sigmask.c b/nuttx/sched/pthread_sigmask.c
new file mode 100644
index 000000000..c66b8591c
--- /dev/null
+++ b/nuttx/sched/pthread_sigmask.c
@@ -0,0 +1,107 @@
+/************************************************************************
+ * sched/pthread_sigmask.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <signal.h>
+#include <pthread.h>
+#include <errno.h>
+#include <debug.h>
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: pthread_sigmask
+ *
+ * Description:
+ * This function is a simple wrapper around sigprocmask().
+ * See the sigprocmask() function description for further
+ * information.
+ *
+ * Parameters:
+ * how - How the signal mast will be changed:
+ * SIG_BLOCK - The resulting set is the union of
+ * the current set and the signal set
+ * pointed to by 'set'.
+ * SIG_UNBLOCK - The resulting set is the intersection
+ * of the current set and the complement
+ * of the signal set pointed to by 'set'.
+ * SIG_SETMASK - The resulting set is the signal set
+ * pointed to by 'set'.
+ * set - Location of the new signal mask
+ * oset - Location to store the old signal mask
+ *
+ * Return Value:
+ * 0 (OK) or EINVAL if how is invalid.
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+int pthread_sigmask(int how, FAR const sigset_t *set, FAR sigset_t *oset)
+{
+ int ret = sigprocmask(how, set, oset);
+ if (ret != OK)
+ {
+ ret = EINVAL;
+ }
+ return ret;
+}
diff --git a/nuttx/sched/pthread_yield.c b/nuttx/sched/pthread_yield.c
new file mode 100644
index 000000000..c4535b9db
--- /dev/null
+++ b/nuttx/sched/pthread_yield.c
@@ -0,0 +1,87 @@
+/************************************************************************
+ * sched/pthread_yield.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <pthread.h>
+#include <sched.h>
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: pthread_yield
+ *
+ * Description:
+ * A thread may tell the scheduler that its processor can be
+ * made available.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+void pthread_yield(void)
+{
+ (void)sched_yield();
+}
diff --git a/nuttx/sched/sched_addblocked.c b/nuttx/sched/sched_addblocked.c
new file mode 100644
index 000000000..c0b80c8ac
--- /dev/null
+++ b/nuttx/sched/sched_addblocked.c
@@ -0,0 +1,122 @@
+/************************************************************************
+ * sched/sched_addblocked.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <queue.h>
+#include <assert.h>
+
+#include "os_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_addblocked
+ *
+ * Description:
+ * This function adds a TCB to one of the blocked state task lists as
+ * inferred from task_state.
+ *
+ * Inputs:
+ * btcb - Points to the TCB that is blocked
+ * task_state - identifies the state of the blocked task
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * - The caller has established a critical section before
+ * calling this function.
+ *
+ ************************************************************************/
+
+void sched_addblocked(FAR _TCB *btcb, tstate_t task_state)
+{
+ /* Make sure that we received a valid blocked state */
+
+ ASSERT(task_state >= FIRST_BLOCKED_STATE &&
+ task_state <= LAST_BLOCKED_STATE);
+
+ /* Add the TCB to the blocked task list associated with this state.
+ * First, determine if the task is to be added to a prioritized task
+ * list
+ */
+
+ if (g_tasklisttable[task_state].prioritized)
+ {
+ /* Add the task to a prioritized list */
+
+ sched_addprioritized(btcb,
+ (FAR dq_queue_t*)g_tasklisttable[task_state].list);
+ }
+ else
+ {
+ /* Add the task to a non-prioritized list */
+
+ dq_addlast((FAR dq_entry_t*)btcb,
+ (FAR dq_queue_t*)g_tasklisttable[task_state].list);
+ }
+
+ /* Make sure the TCB's state corresponds to the list */
+
+ btcb->task_state = task_state;
+}
+
diff --git a/nuttx/sched/sched_addprioritized.c b/nuttx/sched/sched_addprioritized.c
new file mode 100644
index 000000000..8f19a4731
--- /dev/null
+++ b/nuttx/sched/sched_addprioritized.c
@@ -0,0 +1,175 @@
+/************************************************************************
+ * sched/sched_addprioritized.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <queue.h>
+#include <assert.h>
+
+#include "os_internal.h"
+
+/************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_addprioritized
+ *
+ * Description:
+ * This function adds a TCB to a prioritized TCB list.
+ *
+ * Inputs:
+ * tcb - Points to the TCB to add to the prioritized list
+ * list - Points to the prioritized list to add tcb to
+ *
+ * Return Value:
+ * true if the head of the list has changed.
+ *
+ * Assumptions:
+ * - The caller has established a critical section before
+ * calling this function (calling sched_lock() first is NOT
+ * a good idea -- use irqsave()).
+ * - The caller has already removed the input tcb from
+ * whatever list it was in.
+ * - The caller handles the condition that occurs if the
+ * the head of the task list is changed.
+ * - The caller must set the task_state field of the TCB to
+ * match the state associated with the list.
+ ************************************************************************/
+
+bool sched_addprioritized(FAR _TCB *tcb, DSEG dq_queue_t *list)
+{
+ FAR _TCB *next;
+ FAR _TCB *prev;
+ uint8_t sched_priority = tcb->sched_priority;
+ bool ret = false;
+
+ /* Lets do a sanity check before we get started. */
+
+ ASSERT(sched_priority >= SCHED_PRIORITY_MIN);
+
+ /* Search the list to find the location to insert the new Tcb.
+ * Each is list is maintained in ascending sched_priority order.
+ */
+
+ for (next = (FAR _TCB*)list->head;
+ (next && sched_priority <= next->sched_priority);
+ next = next->flink);
+
+ /* Add the tcb to the spot found in the list. Check if the tcb
+ * goes at the end of the list. NOTE: This could only happen if list
+ * is the g_pendingtasks list!
+ */
+
+ if (!next)
+ {
+ /* The tcb goes at the end of the list. */
+
+ prev = (FAR _TCB*)list->tail;
+ if (!prev)
+ {
+ /* Special case: The list is empty */
+
+ tcb->flink = NULL;
+ tcb->blink = NULL;
+ list->head = (FAR dq_entry_t*)tcb;
+ list->tail = (FAR dq_entry_t*)tcb;
+ ret = true;
+ }
+ else
+ {
+ /* The tcb goes at the end of a non-empty list */
+
+ tcb->flink = NULL;
+ tcb->blink = prev;
+ prev->flink = tcb;
+ list->tail = (FAR dq_entry_t*)tcb;
+ }
+ }
+ else
+ {
+ /* The tcb goes just before next */
+
+ prev = (FAR _TCB*)next->blink;
+ if (!prev)
+ {
+ /* Special case: Insert at the head of the list */
+
+ tcb->flink = next;
+ tcb->blink = NULL;
+ next->blink = tcb;
+ list->head = (FAR dq_entry_t*)tcb;
+ ret = true;
+ }
+ else
+ {
+ /* Insert in the middle of the list */
+
+ tcb->flink = next;
+ tcb->blink = prev;
+ prev->flink = tcb;
+ next->blink = tcb;
+ }
+ }
+
+ return ret;
+}
+
diff --git a/nuttx/sched/sched_addreadytorun.c b/nuttx/sched/sched_addreadytorun.c
new file mode 100644
index 000000000..f6117b6ff
--- /dev/null
+++ b/nuttx/sched/sched_addreadytorun.c
@@ -0,0 +1,149 @@
+/****************************************************************************
+ * sched/sched_addreadytorun.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <queue.h>
+#include <assert.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_addreadytorun
+ *
+ * Description:
+ * This function adds a TCB to the ready to run
+ * list. If the currently active task has preemption disabled
+ * and the new TCB would cause this task to be preempted, the
+ * new task is added to the g_pendingtasks list instead. The
+ * pending tasks will be made ready-to-run when preemption
+ * is unlocked.
+ *
+ * Inputs:
+ * btcb - Points to the blocked TCB that is ready-to-run
+ *
+ * Return Value:
+ * true if the currently active task (the head of the
+ * g_readytorun list) has changed.
+ *
+ * Assumptions:
+ * - The caller has established a critical section before
+ * calling this function (calling sched_lock() first is NOT
+ * a good idea -- use irqsave()).
+ * - The caller has already removed the input rtcb from
+ * whatever list it was in.
+ * - The caller handles the condition that occurs if the
+ * the head of the g_readytorun list is changed.
+ *
+ ****************************************************************************/
+
+bool sched_addreadytorun(FAR _TCB *btcb)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ bool ret;
+
+ /* Check if pre-emption is disabled for the current running task and if
+ * the new ready-to-run task would cause the current running task to be
+ * preempted.
+ */
+
+ if (rtcb->lockcount && rtcb->sched_priority < btcb->sched_priority)
+ {
+ /* Yes. Preemption would occur! Add the new ready-to-run task to the
+ * g_pendingtasks task list for now.
+ */
+
+ sched_addprioritized(btcb, (FAR dq_queue_t*)&g_pendingtasks);
+ btcb->task_state = TSTATE_TASK_PENDING;
+ ret = false;
+ }
+
+ /* Otherwise, add the new task to the g_readytorun task list */
+
+ else if (sched_addprioritized(btcb, (FAR dq_queue_t*)&g_readytorun))
+ {
+ /* Information the instrumentation logic that we are switching tasks */
+
+ sched_note_switch(rtcb, btcb);
+
+ /* The new btcb was added at the head of the g_readytorun list. It
+ * is now to new active task!
+ */
+
+ ASSERT(!rtcb->lockcount && btcb->flink != NULL);
+
+ btcb->task_state = TSTATE_TASK_RUNNING;
+ btcb->flink->task_state = TSTATE_TASK_READYTORUN;
+ ret = true;
+ }
+ else
+ {
+ /* The new btcb was added in the middle of the g_readytorun list */
+
+ btcb->task_state = TSTATE_TASK_READYTORUN;
+ ret = false;
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/sched_foreach.c b/nuttx/sched/sched_foreach.c
new file mode 100644
index 000000000..192094533
--- /dev/null
+++ b/nuttx/sched/sched_foreach.c
@@ -0,0 +1,84 @@
+/************************************************************************
+ * sched/sched_foreach.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <sched.h>
+#include "os_internal.h"
+
+/************************************************************************
+ * Global Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_foreach
+ *
+ * Description:
+ * Enumerate over each task and provide the TCB of each
+ * task to a user callback functions. Interrupts will be
+ * disabled throughout this enumeration!
+ *
+ * Parameters:
+ * handler - The function to be called with the TCB of
+ * each task
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+void sched_foreach(sched_foreach_t handler, FAR void *arg)
+{
+ irqstate_t flags = irqsave();
+ int ndx;
+
+ /* Verify that the PID is within range */
+
+ for (ndx = 0; ndx < CONFIG_MAX_TASKS; ndx++)
+ {
+ if (g_pidhash[ndx].tcb)
+ {
+ handler(g_pidhash[ndx].tcb, arg);
+ }
+ }
+
+ irqrestore(flags);
+}
+
+
diff --git a/nuttx/sched/sched_free.c b/nuttx/sched/sched_free.c
new file mode 100644
index 000000000..e5e0bdacf
--- /dev/null
+++ b/nuttx/sched/sched_free.c
@@ -0,0 +1,114 @@
+/************************************************************************
+ * sched/sched_free.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <queue.h>
+#include <assert.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/arch.h>
+#include <nuttx/wqueue.h>
+#include "os_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_free
+ *
+ * Description:
+ * This function performs deallocations that the operating system may
+ * need to make. This special interface to free is used to handling
+ * corner cases where the operating system may have to perform
+ * deallocations from within an interrupt handler.
+ *
+ ************************************************************************/
+
+void sched_free(FAR void *address)
+{
+ /* Check if this is an attempt to deallocate memory from an exception
+ * handler. If this function is called from the IDLE task, then we
+ * must have exclusive access to the memory manager to do this.
+ */
+
+ if (up_interrupt_context() || kmm_trysemaphore() != 0)
+ {
+ /* Yes.. Delay the deallocation until a more appropriate time. */
+
+ irqstate_t saved_state = irqsave();
+ sq_addlast((FAR sq_entry_t*)address, (sq_queue_t*)&g_delayeddeallocations);
+
+ /* Signal the worker thread that is has some clean up to do */
+
+#ifdef CONFIG_SCHED_WORKQUEUE
+ work_signal(LPWORK);
+#endif
+ irqrestore(saved_state);
+ }
+ else
+ {
+ /* No.. just deallocate the memory now. */
+
+ kfree(address);
+ kmm_givesemaphore();
+ }
+}
+
diff --git a/nuttx/sched/sched_garbage.c b/nuttx/sched/sched_garbage.c
new file mode 100644
index 000000000..b8bec9399
--- /dev/null
+++ b/nuttx/sched/sched_garbage.c
@@ -0,0 +1,117 @@
+/****************************************************************************
+ * sched/sched_garbage.c
+ *
+ * Copyright (C) 2009, 2011 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 <nuttx/kmalloc.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+/****************************************************************************
+ * Name: sched_garbagecollection
+ *
+ * Description:
+ * Clean-up memory de-allocations that we queued because they could not
+ * be freed in that execution context (for example, if the memory was freed
+ * from an interrupt handler).
+ *
+ * This logic may be called from the worker thread (see work_thread.c).
+ * If, however, CONFIG_SCHED_WORKQUEUE is not defined, then this logic will
+ * be called from the IDLE thread. It is less optimal for the garbage
+ * collection to be called from the IDLE thread because it runs at a very
+ * low priority and could cause false memory out conditions.
+ *
+ * Input parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void sched_garbagecollection(void)
+{
+ irqstate_t flags;
+ void *address;
+
+ /* Test if the delayed deallocation queue is empty. No special protection
+ * is needed because this is an atomic test.
+ */
+
+ while (g_delayeddeallocations.head)
+ {
+ /* Remove the first delayed deallocation. This is not atomic and so
+ * we must disable interrupts around the queue operation.
+ */
+
+ flags = irqsave();
+ address = (void*)sq_remfirst((FAR sq_queue_t*)&g_delayeddeallocations);
+ irqrestore(flags);
+
+ /* Then deallocate it. */
+
+ if (address)
+ {
+ kfree(address);
+ }
+ }
+}
+
diff --git a/nuttx/sched/sched_getfiles.c b/nuttx/sched/sched_getfiles.c
new file mode 100644
index 000000000..256b4cb6b
--- /dev/null
+++ b/nuttx/sched/sched_getfiles.c
@@ -0,0 +1,76 @@
+/************************************************************************
+ * sched/sched_getfiles.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+#include <sched.h>
+#include "os_internal.h"
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_getfiles
+ *
+ * Description:
+ * Return a pointer to the file list for this thread
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * A pointer to the errno.
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+
+FAR struct filelist *sched_getfiles(void)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ return rtcb->filelist;
+}
+
+#endif /* CONFIG_NFILE_DESCRIPTORS */
diff --git a/nuttx/sched/sched_getparam.c b/nuttx/sched/sched_getparam.c
new file mode 100644
index 000000000..47eab4988
--- /dev/null
+++ b/nuttx/sched/sched_getparam.c
@@ -0,0 +1,146 @@
+/************************************************************************
+ * sched/sched_getparam.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sched.h>
+
+#include "os_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_getparam
+ *
+ * Description:
+ * This function gets the scheduling priority of the task
+ * specified by pid.
+ *
+ * Inputs:
+ * pid - the task ID of the task. If pid is zero, the priority
+ * of the calling task is returned.
+ * param - A structure whose member sched_priority is the integer
+ * priority. The task's priority is copied to the sched_priority
+ * element of this structure.
+ *
+ * Return Value:
+ * 0 (OK) if successful, otherwise -1 (ERROR).
+ *
+ * This function can fail if param is null or if pid does
+ * not correspond to any task.
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+int sched_getparam (pid_t pid, struct sched_param * param)
+{
+ FAR _TCB *rtcb;
+ FAR _TCB *tcb;
+ int ret = OK;
+
+ if (!param)
+ {
+ return ERROR;
+ }
+
+ /* Check if the task to restart is the calling task */
+
+ rtcb = (FAR _TCB*)g_readytorun.head;
+ if ((pid == 0) || (pid == rtcb->pid))
+ {
+ /* Return the priority if the calling task. */
+
+ param->sched_priority = (int)rtcb->sched_priority;
+ }
+
+ /* Ths pid is not for the calling task, we will have to look it up */
+
+ else
+ {
+ /* Get the TCB associated with this pid */
+
+ sched_lock();
+ tcb = sched_gettcb(pid);
+ if (!tcb)
+ {
+ /* This pid does not correspond to any known task */
+
+ ret = ERROR;
+ }
+ else
+ {
+ /* Return the priority of the task */
+
+ param->sched_priority = (int)tcb->sched_priority;
+ }
+
+ sched_unlock();
+ }
+
+ return ret;
+}
+
diff --git a/nuttx/sched/sched_getscheduler.c b/nuttx/sched/sched_getscheduler.c
new file mode 100644
index 000000000..5771e86ff
--- /dev/null
+++ b/nuttx/sched/sched_getscheduler.c
@@ -0,0 +1,131 @@
+/************************************************************************
+ * sched/sched_getscheduler.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sched.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_getscheduler
+ *
+ * Description:
+ * sched_getscheduler() returns the scheduling policy currently
+ * applied to the task identified by pid. If pid equals zero, the
+ * policy of the calling task will be retrieved.
+ *
+ * Inputs:
+ * pid - the task ID of the task to query. If pid is zero, the
+ * calling task is queried.
+ *
+ * Return Value:
+ * On success, sched_getscheduler() returns the policy for the task
+ * (either SCHED_FIFO or SCHED_RR). On error, ERROR (-1) is
+ * returned, and errno is set appropriately:
+ *
+ * ESRCH The task whose ID is pid could not be found.
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+int sched_getscheduler(pid_t pid)
+{
+ _TCB *tcb;
+
+ /* Verify that the pid corresponds to a real task */
+
+ if (!pid)
+ {
+ tcb = (_TCB*)g_readytorun.head;
+ }
+ else
+ {
+ tcb = sched_gettcb(pid);
+ }
+
+ if (!tcb)
+ {
+ set_errno(ESRCH);
+ return ERROR;
+ }
+#if CONFIG_RR_INTERVAL > 0
+ else if ((tcb->flags & TCB_FLAG_ROUND_ROBIN) != 0)
+ {
+ return SCHED_RR;
+ }
+#endif
+ else
+ {
+ return SCHED_FIFO;
+ }
+}
diff --git a/nuttx/sched/sched_getsockets.c b/nuttx/sched/sched_getsockets.c
new file mode 100644
index 000000000..cd499420f
--- /dev/null
+++ b/nuttx/sched/sched_getsockets.c
@@ -0,0 +1,77 @@
+/************************************************************************
+ * sched/sched_getsockets.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include "os_internal.h"
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_getsockets
+ *
+ * Description:
+ * Return a pointer to the socket list for this thread
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * A pointer to the errno.
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+FAR struct socketlist *sched_getsockets(void)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ return rtcb->sockets;
+}
+
+#endif /* CONFIG_NSOCKET_DESCRIPTORS */
diff --git a/nuttx/sched/sched_getstreams.c b/nuttx/sched/sched_getstreams.c
new file mode 100644
index 000000000..f7c21ab4c
--- /dev/null
+++ b/nuttx/sched/sched_getstreams.c
@@ -0,0 +1,76 @@
+/****************************************************************************
+ * sched/sched_getstreams.c
+ *
+ * Copyright (C) 2007, 2008 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 <sched.h>
+#include "os_internal.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_getstreams
+ *
+ * Description:
+ * Return a pointer to the streams list for this thread
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * A pointer to the errno.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
+
+FAR struct streamlist *sched_getstreams(void)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ return rtcb->streams;
+}
+
+#endif /* CONFIG_NFILE_DESCRIPTORS && CONFIG_NFILE_STREAMS */
diff --git a/nuttx/sched/sched_gettcb.c b/nuttx/sched/sched_gettcb.c
new file mode 100644
index 000000000..1e50ef50f
--- /dev/null
+++ b/nuttx/sched/sched_gettcb.c
@@ -0,0 +1,107 @@
+/****************************************************************************
+ * sched/sched_gettcb.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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 <sys/types.h>
+
+#include <sched.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_gettcb
+ *
+ * Description:
+ * Given a task ID, this function will return
+ * the a pointer to the corresponding TCB (or NULL if there
+ * is no such task ID).
+ *
+ ****************************************************************************/
+
+FAR _TCB *sched_gettcb(pid_t pid)
+{
+ FAR _TCB *ret = NULL;
+ int hash_ndx;
+
+ /* Verify that the PID is within range */
+
+ if (pid >= 0 )
+ {
+ /* Get the hash_ndx associated with the pid */
+
+ hash_ndx = PIDHASH(pid);
+
+ /* Verify that the correct TCB was found. */
+
+ if (pid == g_pidhash[hash_ndx].pid)
+ {
+ /* Return the TCB associated with this pid (if any) */
+
+ ret = g_pidhash[hash_ndx].tcb;
+ }
+ }
+
+ /* Return the TCB. */
+
+ return ret;
+}
+
diff --git a/nuttx/sched/sched_lock.c b/nuttx/sched/sched_lock.c
new file mode 100644
index 000000000..61a8a3bc8
--- /dev/null
+++ b/nuttx/sched/sched_lock.c
@@ -0,0 +1,110 @@
+/************************************************************************
+ * sched/sched_lock.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <assert.h>
+
+#include <nuttx/arch.h>
+#include "os_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functionss
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_lock
+ *
+ * Description:
+ * This function disables context switching by disabling addition of
+ * new tasks to the g_readytorun task list. The task that calls this
+ * function will be the only task that is allowed to run until it
+ * either calls sched_unlock() (the appropriate number of times) or
+ * until it blocks itself.
+ *
+ * Inputs
+ * None
+ *
+ * Return Value:
+ * OK on success; ERROR on failure
+ *
+ ************************************************************************/
+
+int sched_lock(void)
+{
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+
+ /* Check for some special cases: (1) rtcb may be NULL only during
+ * early boot-up phases, and (2) sched_lock() should have no
+ * effect if called from the interrupt level.
+ */
+
+ if (rtcb && !up_interrupt_context())
+ {
+ ASSERT(rtcb->lockcount < MAX_LOCK_COUNT);
+ rtcb->lockcount++;
+ }
+
+ return OK;
+}
diff --git a/nuttx/sched/sched_lockcount.c b/nuttx/sched/sched_lockcount.c
new file mode 100644
index 000000000..4dc7a8201
--- /dev/null
+++ b/nuttx/sched/sched_lockcount.c
@@ -0,0 +1,97 @@
+/************************************************************************
+ * sched/sched_lockcount.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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 <stdint.h>
+
+#include "os_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functionss
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_lockcount
+ *
+ * Description:
+ * This function returns the current value of the lockcount. If zero,
+ * pre-emption is enabled; if non-zero, this value indicates the number
+ * of times that sched_lock() has been called on this thread of
+ * execution. sched_unlock() will have to called that many times from
+ * this thread in order to re-enable pre-emption.
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * lockcount
+ *
+ ************************************************************************/
+
+int sched_lockcount(void)
+{
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+ return (int)rtcb->lockcount;
+}
+
diff --git a/nuttx/sched/sched_mergepending.c b/nuttx/sched/sched_mergepending.c
new file mode 100644
index 000000000..71d575c23
--- /dev/null
+++ b/nuttx/sched/sched_mergepending.c
@@ -0,0 +1,177 @@
+/************************************************************************
+ * sched/sched_mergepending.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <sched.h>
+#include <queue.h>
+#include <assert.h>
+
+#include "os_internal.h"
+
+/************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_mergepending
+ *
+ * Description:
+ * This function merges the prioritized g_pendingtasks list into the
+ * prioritized g_readytorun task list.
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * true if the head of the g_readytorun task list has changed.
+ *
+ * Assumptions:
+ * - The caller has established a critical section before
+ * calling this function (calling sched_lock() first is NOT
+ * a good idea -- use irqsave()).
+ * - The caller handles the condition that occurs if the
+ * the head of the sched_mergTSTATE_TASK_PENDINGs is changed.
+ *
+ ************************************************************************/
+
+bool sched_mergepending(void)
+{
+ FAR _TCB *pndtcb;
+ FAR _TCB *pndnext;
+ FAR _TCB *rtrtcb;
+ FAR _TCB *rtrprev;
+ bool ret = false;
+
+ /* Initialize the inner search loop */
+
+ rtrtcb = (FAR _TCB*)g_readytorun.head;
+
+ /* Process every TCB in the g_pendingtasks list */
+
+ for (pndtcb = (FAR _TCB*)g_pendingtasks.head; pndtcb; pndtcb = pndnext)
+ {
+ pndnext = pndtcb->flink;
+
+ /* Search the g_readytorun list to find the location to insert the
+ * new pndtcb. Each is list is maintained in ascending sched_priority
+ * order.
+ */
+
+ for (;
+ (rtrtcb && pndtcb->sched_priority <= rtrtcb->sched_priority);
+ rtrtcb = rtrtcb->flink);
+
+ /* Add the pndtcb to the spot found in the list. Check if the
+ * pndtcb goes at the ends of the g_readytorun list. This would be
+ * error condition since the idle test must always be at the end of
+ * the g_readytorun list!
+ */
+
+ if (!rtrtcb)
+ {
+ PANIC(OSERR_NOIDLETASK);
+ }
+ else
+ {
+ /* The pndtcb goes just before rtrtcb */
+
+ rtrprev = rtrtcb->blink;
+ if (!rtrprev)
+ {
+ /* Special case: Inserting pndtcb at the head of the list */
+ /* Inform the instrumentation layer that we are switching tasks */
+
+ sched_note_switch(rtrtcb, pndtcb);
+
+ /* Then insert at the head of the list */
+
+ pndtcb->flink = rtrtcb;
+ pndtcb->blink = NULL;
+ rtrtcb->blink = pndtcb;
+ g_readytorun.head = (FAR dq_entry_t*)pndtcb;
+ rtrtcb->task_state = TSTATE_TASK_READYTORUN;
+ pndtcb->task_state = TSTATE_TASK_RUNNING;
+ ret = true;
+ }
+ else
+ {
+ /* Insert in the middle of the list */
+
+ pndtcb->flink = rtrtcb;
+ pndtcb->blink = rtrprev;
+ rtrprev->flink = pndtcb;
+ rtrtcb->blink = pndtcb;
+ pndtcb->task_state = TSTATE_TASK_READYTORUN;
+ }
+ }
+
+ /* Set up for the next time through */
+
+ rtrtcb = pndtcb;
+ }
+
+ /* Mark the input list empty */
+
+ g_pendingtasks.head = NULL;
+ g_pendingtasks.tail = NULL;
+
+ return ret;
+}
diff --git a/nuttx/sched/sched_processtimer.c b/nuttx/sched/sched_processtimer.c
new file mode 100644
index 000000000..2224b7691
--- /dev/null
+++ b/nuttx/sched/sched_processtimer.c
@@ -0,0 +1,190 @@
+/************************************************************************
+ * sched/sched_processtimer.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#if CONFIG_RR_INTERVAL > 0
+# include <sched.h>
+# include <nuttx/arch.h>
+#endif
+
+#include "os_internal.h"
+#include "wd_internal.h"
+#include "clock_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+static void sched_process_timeslice(void)
+{
+#if CONFIG_RR_INTERVAL > 0
+ _TCB *rtcb;
+
+ /* Check if the currently executing task uses round robin
+ * scheduling.
+ */
+
+ rtcb = (_TCB*)g_readytorun.head;
+ if ((rtcb->flags & TCB_FLAG_ROUND_ROBIN) != 0)
+ {
+ /* Yes, check if decrementing the timeslice counter
+ * would cause the timeslice to expire
+ */
+
+ if (rtcb->timeslice <= 1)
+ {
+ /* Yes, Now check if the task has pre-emption disabled.
+ * If so, then we will freeze the timeslice count at
+ * the value until the next tick after pre-emption
+ * has been enabled.
+ */
+
+ if (!rtcb->lockcount)
+ {
+ /* Reset the timeslice in any case. */
+
+ rtcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK;
+
+ /* We know we are at the head of the ready to run
+ * prioritized list. We must be the highest priority
+ * task eligible for execution. Check the next task
+ * in the ready to run list. If it is the same
+ * priority, then we need to relinquish the CPU and
+ * give that task a shot.
+ */
+
+ if (rtcb->flink &&
+ rtcb->flink->sched_priority >= rtcb->sched_priority)
+ {
+ /* Just resetting the task priority to its current
+ * value. This this will cause the task to be
+ * rescheduled behind any other tasks at the same
+ * priority.
+ */
+
+ up_reprioritize_rtr(rtcb, rtcb->sched_priority);
+ }
+ }
+ }
+ else
+ {
+ /* Decrement the timeslice counter */
+
+ rtcb->timeslice--;
+ }
+ }
+#endif
+}
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * System Timer Hooks
+ *
+ * These are standard interfaces that are exported by the OS
+ * for use by the architecture specific logic
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_process_timer
+ *
+ * Description:
+ * This function handles system timer events.
+ * The timer interrupt logic itself is implemented in the
+ * architecture specific code, but must call the following OS
+ * function periodically -- the calling interval must be
+ * MSEC_PER_TICK
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ ************************************************************************/
+
+void sched_process_timer(void)
+{
+ /* Increment the system time (if in the link) */
+
+#ifndef CONFIG_DISABLE_CLOCK
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (clock_timer != NULL)
+#endif
+ {
+ clock_timer();
+ }
+#endif
+
+ /* Process watchdogs (if in the link) */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (wd_timer != NULL)
+#endif
+ {
+ wd_timer();
+ }
+
+ /* Check if the currently executing task has exceeded its
+ * timeslice.
+ */
+
+ sched_process_timeslice();
+}
diff --git a/nuttx/sched/sched_releasefiles.c b/nuttx/sched/sched_releasefiles.c
new file mode 100644
index 000000000..a3ef71af4
--- /dev/null
+++ b/nuttx/sched/sched_releasefiles.c
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * sched/sched_releasefiles.c
+ *
+ * Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/net/net.h>
+#include <nuttx/lib.h>
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_releasefiles
+ *
+ * Description:
+ * Release file resources attached to a TCB. This file may be called
+ * multiple times as a task exists. It will be called as early as possible
+ * to support proper closing of complex drivers that may need to wait
+ * on external events.
+ *
+ * Parameters:
+ * tcb - tcb of the new task.
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sched_releasefiles(_TCB *tcb)
+{
+ if (tcb)
+ {
+#if CONFIG_NFILE_DESCRIPTORS > 0
+ /* Free the file descriptor list */
+
+ if (tcb->filelist)
+ {
+ files_releaselist(tcb->filelist);
+ tcb->filelist = NULL;
+ }
+
+#if CONFIG_NFILE_STREAMS > 0
+ /* Free the stream list */
+
+ if (tcb->streams)
+ {
+ lib_releaselist(tcb->streams);
+ tcb->streams = NULL;
+ }
+#endif /* CONFIG_NFILE_STREAMS */
+#endif /* CONFIG_NFILE_DESCRIPTORS */
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+ /* Free the file descriptor list */
+
+ if (tcb->sockets)
+ {
+ net_releaselist(tcb->sockets);
+ tcb->sockets = NULL;
+ }
+#endif /* CONFIG_NSOCKET_DESCRIPTORS */
+ }
+
+ return OK;
+}
+
+#endif /* CONFIG_NFILE_DESCRIPTORS || CONFIG_NSOCKET_DESCRIPTORS */
diff --git a/nuttx/sched/sched_releasetcb.c b/nuttx/sched/sched_releasetcb.c
new file mode 100644
index 000000000..21837262d
--- /dev/null
+++ b/nuttx/sched/sched_releasetcb.c
@@ -0,0 +1,181 @@
+/************************************************************************
+ * sched/sched_releasetcb.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sched.h>
+#include <errno.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "timer_internal.h"
+#include "env_internal.h"
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_releasepid
+ *
+ * Description: When a task is destroyed, this function must
+ * be called to make its process ID available for re-use.
+ ************************************************************************/
+
+static void sched_releasepid(pid_t pid)
+{
+ int hash_ndx = PIDHASH(pid);
+
+ /* Make any pid associated with this hash available. Note:
+ * no special precautions need be taken here because the
+ * following action is atomic
+ */
+
+ g_pidhash[hash_ndx].tcb = NULL;
+ g_pidhash[hash_ndx].pid = INVALID_PROCESS_ID;
+}
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_releasetcb
+ *
+ * Description:
+ * Free all resources contained in a TCB
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * OK on success; ERROR on failure
+ *
+ * Assumptions:
+ * Interrupts are disabled.
+ *
+ ************************************************************************/
+
+int sched_releasetcb(FAR _TCB *tcb)
+{
+ int ret = OK;
+ int i;
+
+ if (tcb)
+ {
+ /* Relase any timers that the task might hold. We do this
+ * before release the PID because it may still be trying to
+ * deliver signals (although interrupts are should be
+ * disabled here).
+ */
+
+#ifndef CONFIG_DISABLE_POSIX_TIMERS
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (timer_deleteall != NULL)
+#endif
+ {
+ timer_deleteall(tcb->pid);
+ }
+#endif
+
+ /* Release the task's process ID if one was assigned. PID
+ * zero is reserved for the IDLE task. The TCB of the IDLE
+ * task is never release so a value of zero simply means that
+ * the process ID was never allocated to this TCB.
+ */
+
+ if (tcb->pid)
+ {
+ sched_releasepid(tcb->pid);
+ }
+
+ /* Delete the thread's stack if one has been allocated */
+
+#ifndef CONFIG_CUSTOM_STACK
+ if (tcb->stack_alloc_ptr)
+ {
+ up_release_stack(tcb);
+ }
+#endif
+
+ /* Delete the tasks's allocated DSpace region (external modules only) */
+
+#ifdef CONFIG_PIC
+ if (tcb->dspace)
+ {
+ if (tcb->dspace->crefs <= 1)
+ {
+ sched_free(tcb->dspace);
+ }
+ else
+ {
+ tcb->dspace->crefs--;
+ }
+ }
+#endif
+
+ /* Release command line arguments that were allocated for task
+ * start/re-start.
+ */
+
+ if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK)
+ {
+ for (i = 1; i < CONFIG_MAX_TASK_ARGS+1 && tcb->argv[i]; i++)
+ {
+ sched_free((FAR void*)tcb->argv[i]);
+ }
+ }
+
+ /* Release any allocated file structures */
+
+ ret = sched_releasefiles(tcb);
+
+ /* Release environment variables */
+
+ (void)env_release(tcb);
+
+ /* And, finally, release the TCB itself */
+
+ sched_free(tcb);
+ }
+
+ return ret;
+}
+
diff --git a/nuttx/sched/sched_removeblocked.c b/nuttx/sched/sched_removeblocked.c
new file mode 100644
index 000000000..8d5a127d2
--- /dev/null
+++ b/nuttx/sched/sched_removeblocked.c
@@ -0,0 +1,111 @@
+/************************************************************************
+ * sched/sched_removeblocked.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <queue.h>
+#include <assert.h>
+
+#include "os_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_removeblocked
+ *
+ * Description:
+ * This function removes a TCB from one of the blocked state task
+ * lists as inferred from the task_state inside the TCB.
+ *
+ * Inputs:
+ * btcb - Points to the TCB that is blocked
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * - The caller has established a critical section before
+ * calling this function.
+ *
+ ************************************************************************/
+
+void sched_removeblocked(FAR _TCB *btcb)
+{
+ tstate_t task_state = btcb->task_state;
+
+ /* Make sure the TCB is in a valid blocked state */
+
+ ASSERT(task_state >= FIRST_BLOCKED_STATE &&
+ task_state <= LAST_BLOCKED_STATE);
+
+ /* Remove the TCB from the blocked task list associated
+ * with this state
+ */
+
+ dq_rem((FAR dq_entry_t*)btcb, (dq_queue_t*)g_tasklisttable[task_state].list);
+
+ /* Make sure the TCB's state corresponds to not being in
+ * any list
+ */
+
+ btcb->task_state = TSTATE_TASK_INVALID;
+}
+
diff --git a/nuttx/sched/sched_removereadytorun.c b/nuttx/sched/sched_removereadytorun.c
new file mode 100644
index 000000000..4982808e2
--- /dev/null
+++ b/nuttx/sched/sched_removereadytorun.c
@@ -0,0 +1,121 @@
+/****************************************************************************
+ * shced/sched_removereadytorun.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <queue.h>
+#include <assert.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_removereadytorun
+ *
+ * Description:
+ * This function removes a TCB from the ready to run list.
+ *
+ * Inputs:
+ * rtcb - Points to the TCB that is ready-to-run
+ *
+ * Return Value:
+ * true if the currently active task (the head of the
+ * g_readytorun list) has changed.
+ *
+ * Assumptions:
+ * - The caller has established a critical section before calling this
+ * function (calling sched_lock() first is NOT a good idea -- use irqsave()).
+ * - The caller handles the condition that occurs if the
+ * the head of the g_readytorun list is changed.
+ *
+ ****************************************************************************/
+
+bool sched_removereadytorun(FAR _TCB *rtcb)
+{
+ bool ret = false;
+
+ /* Check if the TCB to be removed is at the head of the ready to run list.
+ * In this case, we are removing the currently active task.
+ */
+
+ if (!rtcb->blink)
+ {
+ /* There must always be at least one task in the list (the idle task) */
+
+ ASSERT(rtcb->flink != NULL);
+
+ /* Inform the instrumentation layer that we are switching tasks */
+
+ sched_note_switch(rtcb, rtcb->flink);
+
+ rtcb->flink->task_state = TSTATE_TASK_RUNNING;
+ ret = true;
+ }
+
+ /* Remove the TCB from the ready-to-run list */
+
+ dq_rem((FAR dq_entry_t*)rtcb, (dq_queue_t*)&g_readytorun);
+
+ rtcb->task_state = TSTATE_TASK_INVALID;
+ return ret;
+}
diff --git a/nuttx/sched/sched_reprioritize.c b/nuttx/sched/sched_reprioritize.c
new file mode 100644
index 000000000..bd316ec75
--- /dev/null
+++ b/nuttx/sched/sched_reprioritize.c
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * sched/sched_reprioritize.c
+ *
+ * Copyright (C) 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <sched.h>
+#include <errno.h>
+
+#include "os_internal.h"
+
+#ifdef CONFIG_PRIORITY_INHERITANCE
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_reprioritize
+ *
+ * Description:
+ * This function sets the priority of a specified task.
+ *
+ * NOTE: Setting a task's priority to the same value has a similar effect
+ * to sched_yield() -- The task will be moved to after all other tasks
+ * with the same priority.
+ *
+ * Inputs:
+ * tcb - the TCB of task to reprioritize.
+ * sched_priority - The new task priority
+ *
+ * Return Value:
+ * On success, sched_setparam() returns 0 (OK). On error, -1
+ * (ERROR) is returned, and errno is set appropriately.
+ *
+ * EINVAL The parameter 'param' is invalid or does not make sense for the
+ * current scheduling policy.
+ * EPERM The calling task does not have appropriate privileges.
+ * ESRCH The task whose ID is pid could not be found.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sched_reprioritize(FAR _TCB *tcb, int sched_priority)
+{
+ /* This function is equivalent to sched_setpriority() BUT it also has the
+ * side effect of discarding all priority inheritance history. This is
+ * done only on explicit, user-initiated reprioritization.
+ */
+
+ int ret = sched_setpriority(tcb, sched_priority);
+ if (ret == 0)
+ {
+ /* Reset the base_priority -- the priority that the thread would return
+ * to once it posts the semaphore.
+ */
+
+ tcb->base_priority = (uint8_t)sched_priority;
+
+ /* Discard any pending reprioritizations as well */
+
+#if CONFIG_SEM_NNESTPRIO > 0
+ tcb->npend_reprio = 0;
+#endif
+ }
+ return ret;
+}
+#endif /* CONFIG_PRIORITY_INHERITANCE */
diff --git a/nuttx/sched/sched_rrgetinterval.c b/nuttx/sched/sched_rrgetinterval.c
new file mode 100644
index 000000000..961c58ec5
--- /dev/null
+++ b/nuttx/sched/sched_rrgetinterval.c
@@ -0,0 +1,157 @@
+/************************************************************************
+ * sched/sched_rrgetinterval.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sched.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "clock_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_rr_get_interval
+ *
+ * Description:
+ * sched_rr_get_interval() writes the timeslice interval for task
+ * identified by 'pid' into the timespec structure pointed to by
+ * 'interval.' If pid is zero, the timeslice for the calling process
+ * is written into 'interval. The identified process should be running
+ * under the SCHED_RRscheduling policy.'
+ *
+ * Inputs:
+ * pid - the task ID of the task. If pid is zero, the priority of the
+ * calling task is returned.
+ * interval - a structure used to return the time slice
+ *
+ * Return Value:
+ * On success, sched_rr_get_interval() returns OK (0). On error,
+ * ERROR (-1) is returned, and errno is set to:
+ *
+ * EFAULT -- Cannot copy to interval
+ * EINVAL Invalid pid.
+ * ENOSYS The system call is not yet implemented.
+ * ESRCH The process whose ID is pid could not be found.
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+int sched_rr_get_interval(pid_t pid, struct timespec *interval)
+{
+#if CONFIG_RR_INTERVAL > 0
+ FAR _TCB *rrtcb;
+
+ /* If pid is zero, the timeslice for the calling process is written
+ * into 'interval.'
+ */
+
+ if (!pid)
+ {
+ rrtcb = (FAR _TCB*)g_readytorun.head;
+ }
+
+ /* Return a special error code on invalid PID */
+
+ else if (pid < 0)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ /* Otherwise, lookup the TCB associated with this pid */
+
+ else
+ {
+ rrtcb = sched_gettcb(pid);
+ if (!rrtcb)
+ {
+ set_errno(ESRCH);
+ return ERROR;
+ }
+ }
+
+ if (!interval)
+ {
+ set_errno(EFAULT);
+ return ERROR;
+ }
+
+ /* Convert the timeslice value from ticks to timespec */
+
+ interval->tv_sec = CONFIG_RR_INTERVAL / MSEC_PER_SEC;
+ interval->tv_nsec = (CONFIG_RR_INTERVAL % MSEC_PER_SEC) * NSEC_PER_MSEC;
+
+ return OK;
+#else
+ set_errno(ENOSYS);
+ return ERROR;
+#endif
+}
diff --git a/nuttx/sched/sched_self.c b/nuttx/sched/sched_self.c
new file mode 100644
index 000000000..9517e6306
--- /dev/null
+++ b/nuttx/sched/sched_self.c
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * sched/sched_self.c
+ *
+ * Copyright (C) 2011 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 <sys/types.h>
+#include <sched.h>
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_self
+ *
+ * Description:
+ * Return the current threads TCB. Basically, this function just wraps the
+ * head of the ready-to-run list and manages access to the TCB from outside
+ * of the sched/ sub-directory.
+ *
+ ****************************************************************************/
+
+FAR _TCB *sched_self(void)
+{
+ return (FAR _TCB*)g_readytorun.head;
+}
+
+
diff --git a/nuttx/sched/sched_setparam.c b/nuttx/sched/sched_setparam.c
new file mode 100644
index 000000000..6ea4e8f74
--- /dev/null
+++ b/nuttx/sched/sched_setparam.c
@@ -0,0 +1,156 @@
+/****************************************************************************
+ * sched/sched_setparam.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sched.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_setparam
+ *
+ * Description:
+ * This function sets the priority of a specified task.
+ *
+ * NOTE: Setting a task's priority to the same value has a similar effect
+ * to sched_yield() -- The task will be moved to after all other tasks
+ * with the same priority.
+ *
+ * Inputs:
+ * pid - the task ID of the task to reprioritize. If pid is zero, the
+ * priority of the calling task is changed.
+ * param - A structure whose member sched_priority is the integer priority.
+ * The range of valid priority numbers is from SCHED_PRIORITY_MIN
+ * through SCHED_PRIORITY_MAX.
+ *
+ * Return Value:
+ * On success, sched_setparam() returns 0 (OK). On error, -1 (ERROR) is
+ * returned, and errno is set appropriately.
+ *
+ * EINVAL The parameter 'param' is invalid or does not make sense for the
+ * current scheduling policy.
+ * EPERM The calling task does not have appropriate privileges.
+ * ESRCH The task whose ID is pid could not be found.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sched_setparam(pid_t pid, const struct sched_param *param)
+{
+ FAR _TCB *rtcb;
+ FAR _TCB *tcb;
+ int ret;
+
+ /* Verify that the requested priority is in the valid range */
+
+ if (!param)
+ {
+ errno = EINVAL;
+ return ERROR;
+ }
+
+ /* Prohibit modifications to the head of the ready-to-run task
+ * list while adjusting the priority
+ */
+
+ sched_lock();
+
+ /* Check if the task to reprioritize is the calling task */
+
+ rtcb = (FAR _TCB*)g_readytorun.head;
+ if (pid == 0 || pid == rtcb->pid)
+ {
+ tcb = rtcb;
+ }
+
+ /* The pid is not the calling task, we will have to search for it */
+
+ else
+ {
+ tcb = sched_gettcb(pid);
+ if (!tcb)
+ {
+ /* No task with this pid was found */
+
+ errno = ESRCH;
+ sched_unlock();
+ return ERROR;
+ }
+ }
+
+ /* Then perform the reprioritization */
+
+ ret = sched_reprioritize(tcb, param->sched_priority);
+ sched_unlock();
+ return ret;
+}
diff --git a/nuttx/sched/sched_setpriority.c b/nuttx/sched/sched_setpriority.c
new file mode 100644
index 000000000..6aa0789ea
--- /dev/null
+++ b/nuttx/sched/sched_setpriority.c
@@ -0,0 +1,233 @@
+/****************************************************************************
+ * sched/sched_setpriority.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <sched.h>
+#include <errno.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_setpriority
+ *
+ * Description:
+ * This function sets the priority of a specified task.
+ *
+ * NOTE: Setting a task's priority to the same value has a similar effect
+ * to sched_yield() -- The task will be moved to after all other tasks
+ * with the same priority.
+ *
+ * Inputs:
+ * tcb - the TCB of task to reprioritize.
+ * sched_priority - The new task priority
+ *
+ * Return Value:
+ * On success, sched_setparam() returns 0 (OK). On error, -1 (ERROR) is
+ * returned, and errno is set appropriately.
+ *
+ * EINVAL The parameter 'param' is invalid or does not make sense for the
+ * current scheduling policy.
+ * EPERM The calling task does not have appropriate privileges.
+ * ESRCH The task whose ID is pid could not be found.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sched_setpriority(FAR _TCB *tcb, int sched_priority)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ tstate_t task_state;
+ irqstate_t saved_state;
+
+ /* Verify that the requested priority is in the valid range */
+
+ if (sched_priority < SCHED_PRIORITY_MIN ||
+ sched_priority > SCHED_PRIORITY_MAX)
+ {
+ errno = EINVAL;
+ return ERROR;
+ }
+
+ /* We need to assure that there there is no interrupt activity while
+ * performing the following.
+ */
+
+ saved_state = irqsave();
+
+ /* There are four cases that must be considered: */
+
+ task_state = tcb->task_state;
+ switch (task_state)
+ {
+ /* CASE 1. The task is running or ready-to-run and a context switch
+ * may be caused by the re-prioritization
+ */
+
+ case TSTATE_TASK_RUNNING:
+
+ /* A context switch will occur if the new priority of the running
+ * task becomes less than OR EQUAL TO the next highest priority
+ * ready to run task.
+ */
+
+ if (sched_priority <= tcb->flink->sched_priority)
+ {
+ /* A context switch will occur. */
+
+ up_reprioritize_rtr(tcb, (uint8_t)sched_priority);
+ }
+
+ /* Otherwise, we can just change priority since it has no effect */
+
+ else
+ {
+ /* Change the task priority */
+
+ tcb->sched_priority = (uint8_t)sched_priority;
+ }
+ break;
+
+ /* CASE 2. The task is running or ready-to-run and a context switch
+ * may be caused by the re-prioritization
+ */
+
+ case TSTATE_TASK_READYTORUN:
+
+ /* A context switch will occur if the new priority of the ready-to
+ * run task is (strictly) greater than the current running task
+ */
+
+ if (sched_priority > rtcb->sched_priority)
+ {
+ /* A context switch will occur. */
+
+ up_reprioritize_rtr(tcb, (uint8_t)sched_priority);
+ }
+
+ /* Otherwise, we can just change priority and re-schedule (since it
+ * have no other effect).
+ */
+
+ else
+ {
+ /* Remove the TCB from the ready-to-run task list */
+
+ ASSERT(!sched_removereadytorun(tcb));
+
+ /* Change the task priority */
+
+ tcb->sched_priority = (uint8_t)sched_priority;
+
+ /* Put it back into the ready-to-run task list */
+
+ ASSERT(!sched_addreadytorun(tcb));
+ }
+ break;
+
+ /* CASE 3. The task is not in the ready to run list. Changing its
+ * Priority cannot effect the currently executing task.
+ */
+
+ default:
+
+ /* CASE 3a. The task resides in a prioritized list. */
+
+ if (g_tasklisttable[task_state].prioritized)
+ {
+ /* Remove the TCB from the prioritized task list */
+
+ dq_rem((FAR dq_entry_t*)tcb, (FAR dq_queue_t*)g_tasklisttable[task_state].list);
+
+ /* Change the task priority */
+
+ tcb->sched_priority = (uint8_t)sched_priority;
+
+ /* Put it back into the prioritized list at the correct
+ * position
+ */
+
+ sched_addprioritized(tcb, (FAR dq_queue_t*)g_tasklisttable[task_state].list);
+ }
+
+ /* CASE 3b. The task resides in a non-prioritized list. */
+
+ else
+ {
+ /* Just change the task's priority */
+
+ tcb->sched_priority = (uint8_t)sched_priority;
+ }
+ break;
+ }
+
+ irqrestore(saved_state);
+ return OK;
+}
diff --git a/nuttx/sched/sched_setscheduler.c b/nuttx/sched/sched_setscheduler.c
new file mode 100644
index 000000000..7f7f345b4
--- /dev/null
+++ b/nuttx/sched/sched_setscheduler.c
@@ -0,0 +1,187 @@
+/****************************************************************************
+ * sched/sched_setscheduler.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sched.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "clock_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name:sched_setscheduler
+ *
+ * Description:
+ * sched_setscheduler() sets both the scheduling policy and the priority
+ * for the task identified by pid. If pid equals zero, the scheduler of
+ * the calling task will be set. The parameter 'param' holds the priority
+ * of the thread under the new policy.
+ *
+ * Inputs:
+ * pid - the task ID of the task to modify. If pid is zero, the calling
+ * task is modified.
+ * policy - Scheduling policy requested (either SCHED_FIFO or SCHED_RR)
+ * param - A structure whose member sched_priority is the new priority.
+ * The range of valid priority numbers is from SCHED_PRIORITY_MIN
+ * through SCHED_PRIORITY_MAX.
+ *
+ * Return Value:
+ * On success, sched_setscheduler() returns OK (zero). On error, ERROR
+ * (-1) is returned, and errno is set appropriately:
+ *
+ * EINVAL The scheduling policy is not one of the recognized policies.
+ * ESRCH The task whose ID is pid could not be found.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sched_setscheduler(pid_t pid, int policy,
+ const struct sched_param *param)
+{
+ FAR _TCB *tcb;
+#if CONFIG_RR_INTERVAL > 0
+ irqstate_t saved_state;
+#endif
+ int ret;
+
+ /* Check for supported scheduling policy */
+
+#if CONFIG_RR_INTERVAL > 0
+ if (policy != SCHED_FIFO && policy != SCHED_RR)
+#else
+ if (policy != SCHED_FIFO)
+#endif
+ {
+ errno = EINVAL;
+ return ERROR;
+ }
+
+ /* Check if the task to modify the calling task */
+
+ if (pid == 0 )
+ {
+ pid = getpid();
+ }
+
+ /* Verify that the pid corresponds to a real task */
+
+ tcb = sched_gettcb(pid);
+ if (!tcb)
+ {
+ errno = ESRCH;
+ return ERROR;
+ }
+
+ /* Prohibit any context switches while we muck with priority and scheduler
+ * settings.
+ */
+
+ sched_lock();
+
+#if CONFIG_RR_INTERVAL > 0
+ /* Further, disable timer interrupts while we set up scheduling policy. */
+
+ saved_state = irqsave();
+ if (policy == SCHED_RR)
+ {
+ /* Set round robin scheduling */
+
+ tcb->flags |= TCB_FLAG_ROUND_ROBIN;
+ tcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK;
+ }
+ else
+ {
+ /* Set FIFO scheduling */
+
+ tcb->flags &= ~TCB_FLAG_ROUND_ROBIN;
+ tcb->timeslice = 0;
+ }
+
+ irqrestore(saved_state);
+#endif
+
+ /* Set the new priority */
+
+ ret = sched_reprioritize(tcb, param->sched_priority);
+ sched_unlock();
+
+ if (ret != OK)
+ {
+ return ERROR;
+ }
+ else
+ {
+ return OK;
+ }
+}
+
diff --git a/nuttx/sched/sched_setupidlefiles.c b/nuttx/sched/sched_setupidlefiles.c
new file mode 100644
index 000000000..ae814e1a6
--- /dev/null
+++ b/nuttx/sched/sched_setupidlefiles.c
@@ -0,0 +1,148 @@
+/****************************************************************************
+ * sched/sched_setupidlefiles.c
+ *
+ * Copyright (C) 2007-2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/net/net.h>
+
+#include "os_internal.h"
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_setupidlefiles
+ *
+ * Description:
+ * Configure the idle thread's TCB.
+ *
+ * Parameters:
+ * tcb - tcb of the idle task.
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sched_setupidlefiles(FAR _TCB *tcb)
+{
+#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_DEV_CONSOLE)
+ int fd;
+#endif
+
+ /* Allocate file descriptors for the TCB */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+ tcb->filelist = files_alloclist();
+ if (!tcb->filelist)
+ {
+ return -ENOMEM;
+ }
+#endif
+
+ /* Allocate socket descriptors for the TCB */
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+ tcb->sockets = net_alloclist();
+ if (!tcb->sockets)
+ {
+ return -ENOMEM;
+ }
+#endif
+
+ /* Open stdin, dup to get stdout and stderr. This should always
+ * be the first file opened and, hence, should always get file
+ * descriptor 0.
+ */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_DEV_CONSOLE)
+ fd = open("/dev/console", O_RDWR);
+ if (fd == 0)
+ {
+ /* Successfully opened /dev/console as stdin (fd == 0) */
+
+ (void)file_dup2(0, 1);
+ (void)file_dup2(0, 2);
+ }
+ else
+ {
+ /* We failed to open /dev/console OR for some reason, we opened
+ * it and got some file descriptor other than 0.
+ */
+
+ if (fd > 0)
+ {
+ slldbg("Open /dev/console fd: %d\n", fd);
+ (void)close(fd);
+ }
+ else
+ {
+ slldbg("Failed to open /dev/console: %d\n", errno);
+ }
+ return -ENFILE;
+ }
+#endif
+
+ /* Allocate file/socket streams for the TCB */
+
+#if CONFIG_NFILE_STREAMS > 0
+ return sched_setupstreams(tcb);
+#else
+ return OK;
+#endif
+}
+
+#endif /* CONFIG_NFILE_DESCRIPTORS || CONFIG_NSOCKET_DESCRIPTORS */
diff --git a/nuttx/sched/sched_setuppthreadfiles.c b/nuttx/sched/sched_setuppthreadfiles.c
new file mode 100644
index 000000000..648d9273e
--- /dev/null
+++ b/nuttx/sched/sched_setuppthreadfiles.c
@@ -0,0 +1,108 @@
+/****************************************************************************
+ * sched_setuppthreadfiles.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/net/net.h>
+#include <nuttx/lib.h>
+
+#include "os_internal.h"
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_setuppthreadfiles
+ *
+ * Description:
+ * Configure a newly allocated TCB so that it will inherit file
+ * descriptors and streams from the parent pthread.
+ *
+ * Parameters:
+ * tcb - tcb of the new task.
+ *
+ * Return Value:
+ * OK (if an error were returned, it would need to be a non-negated
+ * errno value).
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sched_setuppthreadfiles(FAR _TCB *tcb)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+ /* The child thread inherits the parent file descriptors */
+
+ tcb->filelist = rtcb->filelist;
+ files_addreflist(tcb->filelist);
+
+#endif /* CONFIG_NFILE_DESCRIPTORS */
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+ /* The child thread inherits the parent socket descriptors */
+
+ tcb->sockets = rtcb->sockets;
+ net_addreflist(tcb->sockets);
+
+#endif /* CONFIG_NSOCKET_DESCRIPTORS */
+
+#if CONFIG_NFILE_STREAMS > 0
+ /* The child thread inherits the parent streams */
+
+ tcb->streams = rtcb->streams;
+ lib_addreflist(tcb->streams);
+
+#endif /* CONFIG_NFILE_STREAMS */
+ return OK;
+}
+
+#endif /* CONFIG_NFILE_DESCRIPTORS || CONFIG_NSOCKET_DESCRIPTORS */
diff --git a/nuttx/sched/sched_setupstreams.c b/nuttx/sched/sched_setupstreams.c
new file mode 100644
index 000000000..22895b047
--- /dev/null
+++ b/nuttx/sched/sched_setupstreams.c
@@ -0,0 +1,98 @@
+/****************************************************************************
+ * sched_setupstreams.c
+ *
+ * Copyright (C) 2007-2008, 2010-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <fcntl.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/net/net.h>
+#include <nuttx/lib.h>
+
+/* Make sure that there are file or socket descriptors in the system and
+ * that some number of streams have been configured.
+ */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+#if CONFIG_NFILE_STREAMS > 0
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_setupstreams
+ *
+ * Description:
+ * Setup streams data structures that may be used for standard C buffered
+ * I/O with underlying socket or file desciptors
+ *
+ ****************************************************************************/
+
+int sched_setupstreams(FAR _TCB *tcb)
+{
+ /* Allocate file streams for the TCB */
+
+ tcb->streams = lib_alloclist();
+ if (tcb->streams)
+ {
+ /* fdopen to get the stdin, stdout and stderr streams.
+ * The following logic depends on the fact that the library
+ * layer will allocate FILEs in order.
+ *
+ * fd = 0 is stdin (read-only)
+ * fd = 1 is stdout (write-only, append)
+ * fd = 2 is stderr (write-only, append)
+ */
+
+ (void)fs_fdopen(0, O_RDONLY, tcb);
+ (void)fs_fdopen(1, O_WROK|O_CREAT, tcb);
+ (void)fs_fdopen(2, O_WROK|O_CREAT, tcb);
+ }
+
+ return OK;
+}
+
+#endif /* CONFIG_NFILE_STREAMS > 0 */
+#endif /* CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0*/
diff --git a/nuttx/sched/sched_setuptaskfiles.c b/nuttx/sched/sched_setuptaskfiles.c
new file mode 100644
index 000000000..fe0b14143
--- /dev/null
+++ b/nuttx/sched/sched_setuptaskfiles.c
@@ -0,0 +1,248 @@
+/****************************************************************************
+ * sched/sched_setuptaskfiles.c
+ *
+ * Copyright (C) 2007-2008, 2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <errno.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/net/net.h>
+
+#include "os_internal.h"
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Determine how many file descriptors to clone. If CONFIG_FDCLONE_DISABLE
+ * is set, no file descriptors will be cloned. If CONFIG_FDCLONE_STDIO is
+ * set, only the first three descriptors (stdin, stdout, and stderr) will
+ * be cloned. Otherwise all file descriptors will be cloned.
+ */
+
+#if defined(CONFIG_FDCLONE_STDIO) && CONFIG_NFILE_DESCRIPTORS > 3
+# define NFDS_TOCLONE 3
+#else
+# define NFDS_TOCLONE CONFIG_NFILE_DESCRIPTORS
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_dupfiles
+ *
+ * Description:
+ * Duplicate parent task's file descriptors.
+ *
+ * Input Parameters:
+ * tcb - tcb of the new task.
+ *
+ * Return Value:
+ * None
+ *
+ ****************************************************************************/
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_FDCLONE_DISABLE)
+static inline void sched_dupfiles(FAR _TCB *tcb)
+{
+ /* The parent task is the one at the head of the ready-to-run list */
+
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ FAR struct file *parent;
+ FAR struct file *child;
+ int i;
+
+ /* Duplicate the file descriptors. This will be either all of the
+ * file descriptors or just the first three (stdin, stdout, and stderr)
+ * if CONFIG_FDCLONE_STDIO is defined. NFSDS_TOCLONE is set
+ * accordingly above.
+ */
+
+ if (rtcb->filelist)
+ {
+ /* Get pointers to the parent and child task file lists */
+
+ parent = rtcb->filelist->fl_files;
+ child = tcb->filelist->fl_files;
+
+ /* Check each file in the parent file list */
+
+ for (i = 0; i < NFDS_TOCLONE; i++)
+ {
+ /* Check if this file is opened by the parent. We can tell if
+ * if the file is open because it contain a reference to a non-NULL
+ * i-node structure.
+ */
+
+ if (parent[i].f_inode)
+ {
+ /* Yes... duplicate it for the child */
+
+ (void)files_dup(&parent[i], &child[i]);
+ }
+ }
+ }
+}
+#else /* CONFIG_NFILE_DESCRIPTORS && !CONFIG_FDCLONE_DISABLE */
+# define sched_dupfiles(tcb)
+#endif /* CONFIG_NFILE_DESCRIPTORS && !CONFIG_FDCLONE_DISABLE */
+
+/****************************************************************************
+ * Name: sched_dupsockets
+ *
+ * Description:
+ * Duplicate the parent task's socket descriptors.
+ *
+ * Input Parameters:
+ * tcb - tcb of the new task.
+ *
+ * Return Value:
+ * None
+ *
+ ****************************************************************************/
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0 && !defined(CONFIG_SDCLONE_DISABLE)
+static inline void sched_dupsockets(FAR _TCB *tcb)
+{
+ /* The parent task is the one at the head of the ready-to-run list */
+
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ FAR struct socket *parent;
+ FAR struct socket *child;
+ int i;
+
+ /* Duplicate the socket descriptors of all sockets opened by the parent
+ * task.
+ */
+
+ if (rtcb->sockets)
+ {
+ /* Get pointers to the parent and child task socket lists */
+
+ parent = rtcb->sockets->sl_sockets;
+ child = tcb->sockets->sl_sockets;
+
+ /* Check each socket in the parent socket list */
+
+ for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; i++)
+ {
+ /* Check if this parent socket is allocated. We can tell if the
+ * socket is allocated because it will have a positive, non-zero
+ * reference count.
+ */
+
+ if (parent[i].s_crefs > 0)
+ {
+ /* Yes... duplicate it for the child */
+
+ (void)net_clone(&parent[i], &child[i]);
+ }
+ }
+ }
+}
+#else /* CONFIG_NSOCKET_DESCRIPTORS && !CONFIG_SDCLONE_DISABLE */
+# define sched_dupsockets(tcb)
+#endif /* CONFIG_NSOCKET_DESCRIPTORS && !CONFIG_SDCLONE_DISABLE */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_setuptaskfiles
+ *
+ * Description:
+ * Configure a newly allocated TCB so that it will inherit
+ * file descriptors and streams from the parent task.
+ *
+ * Parameters:
+ * tcb - tcb of the new task.
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sched_setuptaskfiles(FAR _TCB *tcb)
+{
+ /* Allocate file descriptors for the TCB */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+ tcb->filelist = files_alloclist();
+ if (!tcb->filelist)
+ {
+ return -ENOMEM;
+ }
+#endif
+
+ /* Allocate socket descriptors for the TCB */
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+ tcb->sockets = net_alloclist();
+ if (!tcb->sockets)
+ {
+ return -ENOMEM;
+ }
+#endif
+
+ /* Duplicate the parent task's file descriptors */
+
+ sched_dupfiles(tcb);
+
+ /* Duplicate the parent task's socket descriptors */
+
+ sched_dupsockets(tcb);
+
+ /* Allocate file/socket streams for the new TCB */
+
+#if CONFIG_NFILE_STREAMS > 0
+ return sched_setupstreams(tcb);
+#else
+ return OK;
+#endif
+}
+
+#endif /* CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0*/
diff --git a/nuttx/sched/sched_unlock.c b/nuttx/sched/sched_unlock.c
new file mode 100644
index 000000000..9a52e8358
--- /dev/null
+++ b/nuttx/sched/sched_unlock.c
@@ -0,0 +1,130 @@
+/************************************************************************
+ * sched/sched_unlock.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functionss
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sched_unlock
+ *
+ * Description:
+ * This function decrements the preemption lock count. Typically this
+ * is paired with sched_lock() and concludes a critical section of
+ * code. Preemption will not be unlocked until sched_unlock() has
+ * been called as many times as sched_lock(). When the lockcount is
+ * decremented to zero, any tasks that were eligible to preempt the
+ * current task will execute.
+ *
+ ************************************************************************/
+
+int sched_unlock(void)
+{
+ _TCB *rtcb = (_TCB*)g_readytorun.head;
+
+ /* Check for some special cases: (1) rtcb may be NULL only during
+ * early boot-up phases, and (2) sched_unlock() should have no
+ * effect if called from the interrupt level.
+ */
+
+ if (rtcb && !up_interrupt_context())
+ {
+ /* Prevent context switches throughout the following */
+
+ irqstate_t flags = irqsave();
+
+ /* Decrement the preemption lock counter */
+
+ if (rtcb->lockcount)
+ {
+ rtcb->lockcount--;
+ }
+
+ /* Check if the lock counter has decremented to zero. If so,
+ * then pre-emption has been re-enabled.
+ */
+
+ if (rtcb->lockcount <= 0)
+ {
+ rtcb->lockcount = 0;
+
+ /* Release any ready-to-run tasks that have collected in
+ * g_pendingtasks.
+ */
+
+ if (g_pendingtasks.head)
+ {
+ up_release_pending();
+ }
+ }
+
+ irqrestore(flags);
+ }
+ return OK;
+}
diff --git a/nuttx/sched/sched_verifytcb.c b/nuttx/sched/sched_verifytcb.c
new file mode 100644
index 000000000..bcf097a5c
--- /dev/null
+++ b/nuttx/sched/sched_verifytcb.c
@@ -0,0 +1,86 @@
+/****************************************************************************
+ * sched/ched_verifytcb.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <sched.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_verifytcb
+ *
+ * Description:
+ * Return true if the tcb refers to an active task; false if it is a stale
+ * TCB handle.
+ *
+ ****************************************************************************/
+
+bool sched_verifytcb(FAR _TCB *tcb)
+{
+ /* Return true if the PID hashes to this TCB. */
+
+ return tcb == g_pidhash[PIDHASH(tcb->pid)].tcb;
+}
+
diff --git a/nuttx/sched/sched_waitpid.c b/nuttx/sched/sched_waitpid.c
new file mode 100644
index 000000000..692ef6410
--- /dev/null
+++ b/nuttx/sched/sched_waitpid.c
@@ -0,0 +1,248 @@
+/*****************************************************************************
+ * sched/sched_waitpid.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Included Files
+ *****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/wait.h>
+#include <semaphore.h>
+#include <errno.h>
+
+#include <nuttx/sched.h>
+
+#include "os_internal.h"
+
+#ifdef CONFIG_SCHED_WAITPID /* Experimental */
+
+/*****************************************************************************
+ * Private Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Public Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Name: sched_waitpid
+ *
+ * Description:
+ *
+ * The waitpid() functions will obtain status information pertaining to one
+ * of the caller's child processes. The waitpid() function will suspend
+ * execution of the calling thread until status information for one of the
+ * terminated child processes of the calling process is available, or until
+ * delivery of a signal whose action is either to execute a signal-catching
+ * function or to terminate the process. If more than one thread is suspended
+ * in waitpid() awaiting termination of the same process, exactly one thread
+ * will return the process status at the time of the target process
+ * termination. If status information is available prior to the call to
+ * waitpid(), return will be immediate.
+ *
+ * The pid argument specifies a set of child processes for which status is
+ * requested. The waitpid() function will only return the status of a child
+ * process from this set:
+ *
+ * - If pid is equal to (pid_t)-1, status is requested for any child process.
+ * In this respect, waitpid() is then equivalent to wait().
+ * - If pid is greater than 0, it specifies the process ID of a single child
+ * process for which status is requested.
+ * - If pid is 0, status is requested for any child process whose process
+ * group ID is equal to that of the calling process.
+ * - If pid is less than (pid_t)-1, status is requested for any child process
+ * whose process group ID is equal to the absolute value of pid.
+ *
+ * The options argument is constructed from the bitwise-inclusive OR of zero
+ * or more of the following flags, defined in the <sys/wait.h> header:
+ *
+ * WCONTINUED - The waitpid() function will report the status of any
+ * continued child process specified by pid whose status has not been
+ * reported since it continued from a job control stop.
+ * WNOHANG - The waitpid() function will not suspend execution of the
+ * calling thread if status is not immediately available for one of the
+ * child processes specified by pid.
+ * WUNTRACED - The status of any child processes specified by pid that are
+ * stopped, and whose status has not yet been reported since they stopped,
+ * will also be reported to the requesting process.
+ *
+ * If the calling process has SA_NOCLDWAIT set or has SIGCHLD set to
+ * SIG_IGN, and the process has no unwaited-for children that were
+ * transformed into zombie processes, the calling thread will block until all
+ * of the children of the process containing the calling thread terminate, and
+ * waitpid() will fail and set errno to ECHILD.
+ *
+ * If waitpid() returns because the status of a child process is available,
+ * these functions will return a value equal to the process ID of the child
+ * process. In this case, if the value of the argument stat_loc is not a
+ * null pointer, information will be stored in the location pointed to by
+ * stat_loc. The value stored at the location pointed to by stat_loc will be
+ * 0 if and only if the status returned is from a terminated child process
+ * that terminated by one of the following means:
+ *
+ * 1. The process returned 0 from main().
+ * 2. The process called _exit() or exit() with a status argument of 0.
+ * 3. The process was terminated because the last thread in the process terminated.
+ *
+ * Regardless of its value, this information may be interpreted using the
+ * following macros, which are defined in <sys/wait.h> and evaluate to
+ * integral expressions; the stat_val argument is the integer value pointed
+ * to by stat_loc.
+ *
+ * WIFEXITED(stat_val) - Evaluates to a non-zero value if status was
+ * returned for a child process that terminated normally.
+ * WEXITSTATUS(stat_val) - If the value of WIFEXITED(stat_val) is non-zero,
+ * this macro evaluates to the low-order 8 bits of the status argument
+ * that the child process passed to _exit() or exit(), or the value the
+ * child process returned from main().
+ * WIFSIGNALED(stat_val) - Evaluates to a non-zero value if status was
+ * returned for a child process that terminated due to the receipt of a
+ * signal that was not caught (see <signal.h>).
+ * WTERMSIG(stat_val) - If the value of WIFSIGNALED(stat_val) is non-zero,
+ * this macro evaluates to the number of the signal that caused the
+ * termination of the child process.
+ * WIFSTOPPED(stat_val) - Evaluates to a non-zero value if status was
+ * returned for a child process that is currently stopped.
+ * WSTOPSIG(stat_val) - If the value of WIFSTOPPED(stat_val) is non-zero,
+ * this macro evaluates to the number of the signal that caused the child
+ * process to stop.
+ * WIFCONTINUED(stat_val) - Evaluates to a non-zero value if status was
+ * returned for a child process that has continued from a job control stop.
+ *
+ * Parameters:
+ * pid - The task ID of the thread to waid for
+ * stat_loc - The location to return the exit status
+ * options - ignored
+ *
+ * Return Value:
+ * If waitpid() returns because the status of a child process is available,
+ * it will return a value equal to the process ID of the child process for
+ * which status is reported.
+ *
+ * If waitpid() returns due to the delivery of a signal to the calling
+ * process, -1 will be returned and errno set to EINTR.
+ *
+ * If waitpid() was invoked with WNOHANG set in options, it has at least
+ * one child process specified by pid for which status is not available, and
+ * status is not available for any process specified by pid, 0 is returned.
+ *
+ * Otherwise, (pid_t)-1 will be returned, and errno set to indicate the error:
+ *
+ * ECHILD - The process specified by pid does not exist or is not a child of
+ * the calling process, or the process group specified by pid does not exist
+ * or does not have any member process that is a child of the calling process.
+ * EINTR - The function was interrupted by a signal. The value of the location
+ * pointed to by stat_loc is undefined.
+ * EINVAL - The options argument is not valid.
+ *
+ * Assumptions:
+ *
+ *****************************************************************************/
+
+/***************************************************************************/
+/* NOTE: This is a partially functional, experimental version of waitpid() */
+/***************************************************************************/
+
+pid_t waitpid(pid_t pid, int *stat_loc, int options)
+{
+ _TCB *tcb;
+ bool mystat;
+ int err;
+ int ret;
+
+ /* Disable pre-emption so that nothing changes in the following tests */
+
+ sched_lock();
+ tcb = sched_gettcb(pid);
+ if (!tcb)
+ {
+ err = ECHILD;
+ goto errout_with_errno;
+ }
+
+ /* None of the options are supported */
+
+#ifdef CONFIG_DEBUG
+ if (options != 0)
+ {
+ err = ENOSYS;
+ goto errout_with_errno;
+ }
+#endif
+
+ /* "If more than one thread is suspended in waitpid() awaiting termination of
+ * the same process, exactly one thread will return the process status at the
+ * time of the target process termination." Hmmm.. what do we return to the
+ * others?
+ */
+
+ if (stat_loc != NULL && tcb->stat_loc == NULL)
+ {
+ tcb->stat_loc = stat_loc;
+ mystat = true;
+ }
+
+ /* Then wait for the task to exit */
+
+ ret = sem_wait(&tcb->exitsem);
+ if (ret < 0)
+ {
+ /* Unlock pre-emption and return the ERROR (sem_wait has already set
+ * the errno). Handle the awkward case of whether or not we need to
+ * nullify the stat_loc value.
+ */
+
+ if (mystat)
+ {
+ tcb->stat_loc = NULL;
+ }
+
+ goto errout;
+ }
+
+ /* On success, return the PID */
+
+ sched_unlock();
+ return pid;
+
+errout_with_errno:
+ set_errno(err);
+errout:
+ sched_unlock();
+ return ERROR;
+}
+
+#endif /* CONFIG_SCHED_WAITPID */
diff --git a/nuttx/sched/sched_yield.c b/nuttx/sched/sched_yield.c
new file mode 100644
index 000000000..b2e6493d0
--- /dev/null
+++ b/nuttx/sched/sched_yield.c
@@ -0,0 +1,101 @@
+/****************************************************************************
+ * sched/sched_yield.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sched_yield
+ *
+ * Description:
+ * This function forces the calling task to give up the CPU (only to other
+ * tasks at the same priority).
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * 0 (OK) or -1 (ERROR) (errno is not set)
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sched_yield(void)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+
+ /* This equivalent to just resetting the task priority to its current value
+ * since this will cause the task to be rescheduled behind any other tasks
+ * at the same priority.
+ */
+
+ return sched_setpriority(rtcb, rtcb->sched_priority);
+}
diff --git a/nuttx/sched/sem_close.c b/nuttx/sched/sem_close.c
new file mode 100644
index 000000000..169fc0448
--- /dev/null
+++ b/nuttx/sched/sem_close.c
@@ -0,0 +1,140 @@
+/****************************************************************************
+ * sched/sem_close.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <errno.h>
+#include <semaphore.h>
+#include <sched.h>
+
+#include "os_internal.h"
+#include "sem_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_close
+ *
+ * Description:
+ * This function is called to indicate that the calling task is finished
+ * with the specified named semaphore, 'sem'. The sem_close() deallocates
+ * any system resources allocated by the system for this named semaphore.
+ *
+ * If the semaphore has not been removed with a call to sem_unlink(), then
+ * sem_close() has no effect on the named semaphore. However, when the
+ * named semaphore has been fully unlinked, the semaphore will vanish when
+ * the last task closes it.
+ *
+ * Parameters:
+ * sem - semaphore descriptor
+ *
+ * Return Value:
+ * 0 (OK), or -1 (ERROR) if unsuccessful.
+ *
+ * Assumptions:
+ * - Care must be taken to avoid risking the deletion of a semaphore that
+ * another calling task has already locked.
+ * - sem_close must not be called for an un-named semaphore
+ *
+ ****************************************************************************/
+
+int sem_close(FAR sem_t *sem)
+{
+ FAR nsem_t *psem;
+ int ret = ERROR;
+
+ /* Verify the inputs */
+
+ if (sem)
+ {
+ sched_lock();
+
+ /* Search the list of named semaphores */
+
+ for (psem = (FAR nsem_t*)g_nsems.head;
+ ((psem) && (sem != &psem->sem));
+ psem = psem->flink);
+
+ /* Check if we found it */
+
+ if (psem)
+ {
+ /* Decrement the count of sem_open connections to this semaphore */
+
+ if (psem->nconnect) psem->nconnect--;
+
+ /* If the semaphore is no long connected to any processes AND the
+ * semaphore was previously unlinked, then deallocate it.
+ */
+
+ if (!psem->nconnect && psem->unlinked)
+ {
+ dq_rem((FAR dq_entry_t*)psem, &g_nsems);
+ sched_free(psem);
+ }
+ ret = OK;
+ }
+
+ sched_unlock();
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/sem_destroy.c b/nuttx/sched/sem_destroy.c
new file mode 100644
index 000000000..90a2b95ef
--- /dev/null
+++ b/nuttx/sched/sem_destroy.c
@@ -0,0 +1,126 @@
+/****************************************************************************
+ * lib/semaphore/sem_destroy.c
+ *
+ * Copyright (C) 2007-2009, 2011 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 <semaphore.h>
+#include <errno.h>
+
+#include "sem_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_destroy
+ *
+ * Description:
+ * This function is used to destroy the un-named semaphore indicated by
+ * 'sem'. Only a semaphore that was created using sem_init() may be
+ * destroyed using sem_destroy(); the effect of calling sem_destroy() with
+ * a named semaphore is undefined. The effect of subsequent use of the
+ * semaphore sem is undefined until sem is re-initialized by another call
+ * to sem_init().
+ *
+ * The effect of destroying a semaphore upon which other processes are
+ * currently blocked is undefined.
+ *
+ * Parameters:
+ * sem - Semaphore to be destroyed.
+ *
+ * Return Value:
+ * 0 (OK), or -1 (ERROR) if unsuccessful.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sem_destroy (FAR sem_t *sem)
+{
+ /* Assure a valid semaphore is specified */
+
+ if (sem)
+ {
+ /* There is really no particular action that we need
+ * take to destroy a semaphore. We will just reset
+ * the count to some reasonable value (1) and release
+ * ownership.
+ *
+ * Check if other threads are waiting on the semaphore.
+ * In this case, the behavior is undefined. We will:
+ * leave the count unchanged but still return OK.
+ */
+
+ if (sem->semcount >= 0)
+ {
+ sem->semcount = 1;
+ }
+
+ /* Release holders of the semaphore */
+
+ sem_destroyholder(sem);
+ return OK;
+ }
+ else
+ {
+ errno = -EINVAL;
+ return ERROR;
+ }
+}
diff --git a/nuttx/sched/sem_findnamed.c b/nuttx/sched/sem_findnamed.c
new file mode 100644
index 000000000..bcba47a8a
--- /dev/null
+++ b/nuttx/sched/sem_findnamed.c
@@ -0,0 +1,100 @@
+/************************************************************************
+ * sem_findnamed.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+
+#include "sem_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sem_findnamed
+ *
+ * Description:
+ * Search the g_nsems list to find the semaphore with the matching name.
+ *
+ * Parameters:
+ * name - semaphore name
+ *
+ * Return Value:
+ * Pointer to the semaphore or NULL if not found
+ *
+ ************************************************************************/
+
+FAR nsem_t *sem_findnamed(const char *name)
+{
+ FAR nsem_t *psem;
+
+ /* Search the list of named semaphores */
+
+ for (psem = (FAR nsem_t*)g_nsems.head; (psem); psem = psem->flink)
+ {
+ if (!strcmp(name, psem->name))
+ {
+ break;
+ }
+ }
+
+ return(psem);
+}
+
diff --git a/nuttx/sched/sem_holder.c b/nuttx/sched/sem_holder.c
new file mode 100644
index 000000000..c850a3b5a
--- /dev/null
+++ b/nuttx/sched/sem_holder.c
@@ -0,0 +1,1055 @@
+/****************************************************************************
+ * sched/sem_holder.c
+ *
+ * Copyright (C) 2009-2011 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 <semaphore.h>
+#include <sched.h>
+#include <assert.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sem_internal.h"
+
+#ifdef CONFIG_PRIORITY_INHERITANCE
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_SEM_PREALLOCHOLDERS
+# define CONFIG_SEM_PREALLOCHOLDERS 0
+#endif
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+typedef int (*holderhandler_t)(FAR struct semholder_s *pholder,
+ FAR sem_t *sem, FAR void *arg);
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/* Preallocated holder structures */
+
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+static struct semholder_s g_holderalloc[CONFIG_SEM_PREALLOCHOLDERS];
+static FAR struct semholder_s *g_freeholders;
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_allocholder
+ ****************************************************************************/
+
+static inline FAR struct semholder_s *sem_allocholder(sem_t *sem)
+{
+ FAR struct semholder_s *pholder;
+
+ /* Check if the "built-in" holder is being used. We have this built-in
+ * holder to optimize for the simplest case where semaphores are only
+ * used to implement mutexes.
+ */
+
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ pholder = g_freeholders;
+ if (pholder)
+ {
+ /* Remove the holder from the free list an put it into the semaphore's holder list */
+
+ g_freeholders = pholder->flink;
+ pholder->flink = sem->hhead;
+ sem->hhead = pholder;
+
+ /* Make sure the initial count is zero */
+
+ pholder->counts = 0;
+ }
+#else
+ if (!sem->holder.htcb)
+ {
+ pholder = &sem->holder;
+ pholder->counts = 0;
+ }
+#endif
+ else
+ {
+ sdbg("Insufficient pre-allocated holders\n");
+ pholder = NULL;
+ }
+
+ return pholder;
+}
+
+/****************************************************************************
+ * Name: sem_findholder
+ ****************************************************************************/
+
+static FAR struct semholder_s *sem_findholder(sem_t *sem, FAR _TCB *htcb)
+{
+ FAR struct semholder_s *pholder;
+
+ /* Try to find the holder in the list of holders associated with this semaphore */
+
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ for (pholder = sem->hhead; pholder; pholder = pholder->flink)
+#else
+ pholder = &sem->holder;
+#endif
+ {
+ if (pholder->htcb == htcb)
+ {
+ /* Got it! */
+
+ return pholder;
+ }
+ }
+
+ /* The holder does not appear in the list */
+
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: sem_findorallocateholder
+ ****************************************************************************/
+
+static inline FAR struct semholder_s *sem_findorallocateholder(sem_t *sem, FAR _TCB *htcb)
+{
+ FAR struct semholder_s *pholder = sem_findholder(sem, htcb);
+ if (!pholder)
+ {
+ pholder = sem_allocholder(sem);
+ }
+
+ return pholder;
+}
+
+/****************************************************************************
+ * Name: sem_freeholder
+ ****************************************************************************/
+
+static inline void sem_freeholder(sem_t *sem, FAR struct semholder_s *pholder)
+{
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ FAR struct semholder_s *curr;
+ FAR struct semholder_s *prev;
+#endif
+
+ /* Release the holder and counts */
+
+ pholder->htcb = NULL;
+ pholder->counts = 0;
+
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ /* Search the list for the matching holder */
+
+ for (prev = NULL, curr = sem->hhead;
+ curr && curr != pholder;
+ prev = curr, curr = curr->flink);
+
+ if (curr)
+ {
+ /* Remove the holder from the list */
+
+ if (prev)
+ {
+ prev->flink = pholder->flink;
+ }
+ else
+ {
+ sem->hhead = pholder->flink;
+ }
+
+ /* And put it in the free list */
+
+ pholder->flink = g_freeholders;
+ g_freeholders = pholder;
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: sem_foreachholder
+ ****************************************************************************/
+
+static int sem_foreachholder(FAR sem_t *sem, holderhandler_t handler, FAR void *arg)
+{
+ FAR struct semholder_s *pholder;
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ FAR struct semholder_s *next;
+#endif
+ int ret = 0;
+
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ for (pholder = sem->hhead; pholder && ret == 0; pholder = next)
+#else
+ pholder = &sem->holder;
+#endif
+ {
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ /* In case this holder gets deleted */
+
+ next = pholder->flink;
+#endif
+ /* The initial "built-in" container may hold a NULL holder */
+
+ if (pholder->htcb)
+ {
+ /* Call the handler */
+
+ ret = handler(pholder, sem, arg);
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: sem_recoverholders
+ ****************************************************************************/
+
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+static int sem_recoverholders(FAR struct semholder_s *pholder, FAR sem_t *sem, FAR void *arg)
+{
+ sem_freeholder(sem, pholder);
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: sem_boostholderprio
+ ****************************************************************************/
+
+static int sem_boostholderprio(FAR struct semholder_s *pholder,
+ FAR sem_t *sem, FAR void *arg)
+{
+ FAR _TCB *htcb = (FAR _TCB *)pholder->htcb;
+ FAR _TCB *rtcb = (FAR _TCB*)arg;
+
+ /* Make sure that the holder thread is still active. If it exited without
+ * releasing its counts, then that would be a bad thing. But we can take no
+ * real action because we don't know know that the program is doing. Perhaps
+ * its plan is to kill a thread, then destroy the semaphore.
+ */
+
+ if (!sched_verifytcb(htcb))
+ {
+ sdbg("TCB 0x%08x is a stale handle, counts lost\n", htcb);
+ sem_freeholder(sem, pholder);
+ }
+
+#if CONFIG_SEM_NNESTPRIO > 0
+
+ /* If the priority of the thread that is waiting for a count is greater than
+ * the base priority of the thread holding a count, then we may need to
+ * adjust the holder's priority now or later to that priority.
+ */
+
+ else if (rtcb->sched_priority > htcb->base_priority)
+ {
+ /* If the new priority is greater than the current, possibly already
+ * boosted priority of the holder thread, then we will have to raise
+ * the holder's priority now.
+ */
+
+ if (rtcb->sched_priority > htcb->sched_priority)
+ {
+ /* If the current priority of holder thread has already been
+ * boosted, then add the boost priority to the list of restoration
+ * priorities. When the higher priority waiter thread gets its
+ * count, then we need to revert the holder thread to this saved
+ * priority (not to its base priority).
+ */
+
+ if (htcb->sched_priority > htcb->base_priority)
+ {
+ /* Save the current, boosted priority of the holder thread. */
+
+ if (htcb->npend_reprio < CONFIG_SEM_NNESTPRIO)
+ {
+ htcb->pend_reprios[htcb->npend_reprio] = htcb->sched_priority;
+ htcb->npend_reprio++;
+ }
+ else
+ {
+ sdbg("CONFIG_SEM_NNESTPRIO exceeded\n");
+ }
+ }
+
+ /* Raise the priority of the thread holding of the semaphore.
+ * This cannot cause a context switch because we have preemption
+ * disabled. The holder thread may be marked "pending" and the
+ * switch may occur during up_block_task() processing.
+ */
+
+ (void)sched_setpriority(htcb, rtcb->sched_priority);
+ }
+ else
+ {
+ /* The new priority is above the base priority of the holder,
+ * but not as high as its current working priority. Just put it
+ * in the list of pending restoration priorities so that when the
+ * higher priority thread gets its count, we can revert to this
+ * saved priority and not to the base priority.
+ */
+
+ htcb->pend_reprios[htcb->npend_reprio] = rtcb->sched_priority;
+ htcb->npend_reprio++;
+ }
+ }
+
+#else
+ /* If the priority of the thread that is waiting for a count is less than
+ * of equal to the priority of the thread holding a count, then do nothing
+ * because the thread is already running at a sufficient priority.
+ */
+
+ else if (rtcb->sched_priority > htcb->sched_priority)
+ {
+ /* Raise the priority of the holder of the semaphore. This
+ * cannot cause a context switch because we have preemption
+ * disabled. The task will be marked "pending" and the switch
+ * will occur during up_block_task() processing.
+ */
+
+ (void)sched_setpriority(htcb, rtcb->sched_priority);
+ }
+#endif
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: sem_verifyholder
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG
+static int sem_verifyholder(FAR struct semholder_s *pholder, FAR sem_t *sem, FAR void *arg)
+{
+#if 0 // Need to revisit this, but these assumptions seem to be untrue -- OR there is a bug???
+ FAR _TCB *htcb = (FAR _TCB *)pholder->htcb;
+
+ /* Called after a semaphore has been released (incremented), the semaphore
+ * could is non-negative, and there is no thread waiting for the count.
+ * In this case, the priority of the holder should not be boosted.
+ */
+
+#if CONFIG_SEM_NNESTPRIO > 0
+ DEBUGASSERT(htcb->npend_reprio == 0);
+#endif
+ DEBUGASSERT(htcb->sched_priority == htcb->base_priority);
+#endif
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: sem_dumpholder
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_SEM_PHDEBUG)
+static int sem_dumpholder(FAR struct semholder_s *pholder, FAR sem_t *sem, FAR void *arg)
+{
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ dbg(" %08x: %08x %08x %04x\n",
+ pholder, pholder->flink, pholder->htcb, pholder->counts);
+#else
+ dbg(" %08x: %08x %04x\n", pholder, pholder->htcb, pholder->counts);
+#endif
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: sem_restoreholderprio
+ ****************************************************************************/
+
+static int sem_restoreholderprio(FAR struct semholder_s *pholder, FAR sem_t *sem, FAR void *arg)
+{
+ FAR _TCB *htcb = (FAR _TCB *)pholder->htcb;
+#if CONFIG_SEM_NNESTPRIO > 0
+ FAR _TCB *stcb = (FAR _TCB *)arg;
+ int rpriority;
+ int i;
+ int j;
+#endif
+
+ /* Make sure that the hdoler thread is still active. If it exited without
+ * releasing its counts, then that would be a bad thing. But we can take no
+ * real action because we don't know know that the program is doing. Perhaps
+ * its plan is to kill a thread, then destroy the semaphore.
+ */
+
+ if (!sched_verifytcb(htcb))
+ {
+ sdbg("TCB 0x%08x is a stale handle, counts lost\n", htcb);
+ sem_freeholder(sem, pholder);
+ }
+
+ /* Was the priority of the holder thread boosted? If so, then drop its
+ * priority back to the correct level. What is the correct level?
+ */
+
+ else if (htcb->sched_priority != htcb->base_priority)
+ {
+#if CONFIG_SEM_NNESTPRIO > 0
+ /* Are there other, pending priority levels to revert to? */
+
+ if (htcb->npend_reprio < 1)
+ {
+ /* No... the holder thread has only been boosted once. Reset all
+ * priorities back to the base priority.
+ */
+
+ DEBUGASSERT(htcb->sched_priority == stcb->sched_priority && htcb->npend_reprio == 0);
+ sched_reprioritize(htcb, htcb->base_priority);
+ }
+
+ /* There are multiple pending priority levels. The holder thread's "boosted"
+ * priority could greater than or equal to "stcb->sched_priority" (it could be
+ * greater if its priority we boosted becuase it also holds another semaphore).
+ */
+
+ else if (htcb->sched_priority <= stcb->sched_priority)
+ {
+ /* The holder thread has been boosted to the same priority as the waiter
+ * thread that just received the count. We will simply reprioritize
+ * to the next highest priority that we have in rpriority.
+ */
+
+ /* Find the highest pending priority and remove it from the list */
+
+ for (i = 1, j = 0; i < htcb->npend_reprio; i++)
+ {
+ if (htcb->pend_reprios[i] > htcb->pend_reprios[j])
+ {
+ j = i;
+ }
+ }
+
+ /* Remove the highest priority pending priority from the list */
+
+ rpriority = htcb->pend_reprios[j];
+ i = htcb->npend_reprio - 1;
+ if (i > 0)
+ {
+ htcb->pend_reprios[j] = htcb->pend_reprios[i];
+ }
+
+ htcb->npend_reprio = i;
+
+ /* And apply that priority to the thread (while retaining the base_priority) */
+
+ sched_setpriority(htcb, rpriority);
+ }
+ else
+ {
+ /* The holder thread has been boosted to a higher priority than the
+ * waiter task. The pending priority should be in the list (unless it
+ * was lost because of of list overflow or because the holder was
+ * reporioritize again unbeknownst to the priority inheritance logic).
+ *
+ * Search the list for the matching priority.
+ */
+
+ for (i = 0; i < htcb->npend_reprio; i++)
+ {
+ /* Does this pending priority match the priority of the thread
+ * that just received the count?
+ */
+
+ if (htcb->pend_reprios[i] == stcb->sched_priority)
+ {
+ /* Yes, remove it from the list */
+
+ j = htcb->npend_reprio - 1;
+ if (j > 0)
+ {
+ htcb->pend_reprios[i] = htcb->pend_reprios[j];
+ }
+
+ htcb->npend_reprio = j;
+ break;
+ }
+ }
+ }
+#else
+ /* There is no alternative restore priorities, drop the priority
+ * of the holder thread all the way back to the threads "base"
+ * priority.
+ */
+
+ sched_reprioritize(htcb, htcb->base_priority);
+#endif
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: sem_restoreholderprioA
+ *
+ * Description:
+ * Reprioritize all holders except the currently executing task
+ *
+ ****************************************************************************/
+
+static int sem_restoreholderprioA(FAR struct semholder_s *pholder,
+ FAR sem_t *sem, FAR void *arg)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ if (pholder->htcb != rtcb)
+ {
+ return sem_restoreholderprio(pholder, sem, arg);
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: sem_restoreholderprioB
+ *
+ * Description:
+ * Reprioritize only the currently executing task
+ *
+ ****************************************************************************/
+
+static int sem_restoreholderprioB(FAR struct semholder_s *pholder,
+ FAR sem_t *sem, FAR void *arg)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ if (pholder->htcb == rtcb)
+ {
+ (void)sem_restoreholderprio(pholder, sem, arg);
+ return 1;
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: sem_restorebaseprio_irq
+ *
+ * Description:
+ * This function is called after the an interrupt handler posts a count on
+ * the semaphore. It will check if we need to drop the priority of any
+ * threads holding a count on the semaphore. Their priority could have
+ * been boosted while they held the count.
+ *
+ * Parameters:
+ * stcb - The TCB of the task that was just started (if any). If the
+ * post action caused a count to be given to another thread, then stcb
+ * is the TCB that received the count. Note, just because stcb received
+ * the count, it does not mean that it it is higher priority than other
+ * threads.
+ * sem - A reference to the semaphore being posted.
+ * - If the semaphore count is <0 then there are still threads waiting
+ * for a count. stcb should be non-null and will be higher priority
+ * than all of the other threads still waiting.
+ * - If it is ==0 then stcb refers to the thread that got the last count;
+ * no other threads are waiting.
+ * - If it is >0 then there should be no threads waiting for counts and
+ * stcb should be null.
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * The scheduler is locked.
+ *
+ ****************************************************************************/
+
+static inline void sem_restorebaseprio_irq(FAR _TCB *stcb, FAR sem_t *sem)
+{
+ /* Perfom the following actions only if a new thread was given a count.
+ * The thread that received the count should be the highest priority
+ * of all threads waiting for a count from the semphore. So in that
+ * case, the priority of all holder threads should be dropped to the
+ * next highest pending priority.
+ */
+
+ if (stcb)
+ {
+ /* Drop the priority of all holder threads */
+
+ (void)sem_foreachholder(sem, sem_restoreholderprio, stcb);
+ }
+
+ /* If there are no tasks waiting for available counts, then all holders
+ * should be at their base priority.
+ */
+
+#ifdef CONFIG_DEBUG
+ else
+ {
+ (void)sem_foreachholder(sem, sem_verifyholder, NULL);
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: sem_restorebaseprio_task
+ *
+ * Description:
+ * This function is called after the current running task releases a
+ * count on the semaphore. It will check if we need to drop the priority
+ * of any threads holding a count on the semaphore. Their priority could
+ * have been boosted while they held the count.
+ *
+ * Parameters:
+ * stcb - The TCB of the task that was just started (if any). If the
+ * post action caused a count to be given to another thread, then stcb
+ * is the TCB that received the count. Note, just because stcb received
+ * the count, it does not mean that it it is higher priority than other
+ * threads.
+ * sem - A reference to the semaphore being posted.
+ * - If the semaphore count is <0 then there are still threads waiting
+ * for a count. stcb should be non-null and will be higher priority
+ * than all of the other threads still waiting.
+ * - If it is ==0 then stcb refers to the thread that got the last count;
+ * no other threads are waiting.
+ * - If it is >0 then there should be no threads waiting for counts and
+ * stcb should be null.
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * The scheduler is locked.
+ *
+ ****************************************************************************/
+
+static inline void sem_restorebaseprio_task(FAR _TCB *stcb, FAR sem_t *sem)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ FAR struct semholder_s *pholder;
+
+ /* Perfom the following actions only if a new thread was given a count.
+ * The thread that received the count should be the highest priority
+ * of all threads waiting for a count from the semphore. So in that
+ * case, the priority of all holder threads should be dropped to the
+ * next highest pending priority.
+ */
+
+ if (stcb)
+ {
+ /* The currently executed thread should be the lower priority
+ * thread that just posted the count and caused this action.
+ * However, we cannot drop the priority of the currently running
+ * thread -- becuase that will cause it to be suspended.
+ *
+ * So, do this in two passes. First, reprioritizing all holders
+ * except for the running thread.
+ */
+
+ (void)sem_foreachholder(sem, sem_restoreholderprioA, stcb);
+
+ /* Now, find an reprioritize only the ready to run task */
+
+ (void)sem_foreachholder(sem, sem_restoreholderprioB, stcb);
+ }
+
+ /* If there are no tasks waiting for available counts, then all holders
+ * should be at their base priority.
+ */
+
+#ifdef CONFIG_DEBUG
+ else
+ {
+ (void)sem_foreachholder(sem, sem_verifyholder, NULL);
+ }
+#endif
+
+ /* In any case, the currently executing task should have an entry in the
+ * list. Its counts were previously decremented; if it now holds no
+ * counts, then we need to remove it from the list of holders.
+ */
+
+ pholder = sem_findholder(sem, rtcb);
+ if (pholder)
+ {
+ /* When no more counts are held, remove the holder from the list. The
+ * count was decremented in sem_releaseholder.
+ */
+
+ if (pholder->counts <= 0)
+ {
+ sem_freeholder(sem, pholder);
+ }
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_initholders
+ *
+ * Description:
+ * Called from sem_initialize() to set up semaphore holder information.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void sem_initholders(void)
+{
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ int i;
+
+ /* Put all of the pre-allocated holder structures into free list */
+
+ g_freeholders = g_holderalloc;
+ for (i = 0; i < (CONFIG_SEM_PREALLOCHOLDERS-1); i++)
+ {
+ g_holderalloc[i].flink = &g_holderalloc[i+1];
+ }
+
+ g_holderalloc[CONFIG_SEM_PREALLOCHOLDERS-1].flink = NULL;
+#endif
+}
+
+/****************************************************************************
+ * Name: sem_destroyholder
+ *
+ * Description:
+ * Called from sem_destroy() to handle any holders of a semaphore when
+ * it is destroyed.
+ *
+ * Parameters:
+ * sem - A reference to the semaphore being destroyed
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void sem_destroyholder(FAR sem_t *sem)
+{
+ /* It is an error if a semaphore is destroyed while there are any holders
+ * (except perhaps the thread release the semaphore itself). Hmmm.. but
+ * we actually have to assume that the caller knows what it is doing because
+ * could have killed another thread that is the actual holder of the semaphore.
+ * We cannot make any assumptions about the state of the semaphore or the
+ * state of any of the holder threads.
+ *
+ * So just recover any stranded holders and hope the task knows what it is
+ * doing.
+ */
+
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ if (sem->hhead)
+ {
+ sdbg("Semaphore destroyed with holders\n");
+ (void)sem_foreachholder(sem, sem_recoverholders, NULL);
+ }
+#else
+ if (sem->holder.htcb)
+ {
+ sdbg("Semaphore destroyed with holder\n");
+ }
+
+ sem->holder.htcb = NULL;
+#endif
+}
+
+/****************************************************************************
+ * Name: sem_addholder
+ *
+ * Description:
+ * Called from sem_wait() when the calling thread obtains the semaphore
+ *
+ * Parameters:
+ * sem - A reference to the incremented semaphore
+ *
+ * Return Value:
+ * 0 (OK) or -1 (ERROR) if unsuccessful
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void sem_addholder(FAR sem_t *sem)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ FAR struct semholder_s *pholder;
+
+ /* Find or allocate a container for this new holder */
+
+ pholder = sem_findorallocateholder(sem, rtcb);
+ if (pholder)
+ {
+ /* Then set the holder and increment the number of counts held by this holder */
+
+ pholder->htcb = rtcb;
+ pholder->counts++;
+ }
+}
+
+/****************************************************************************
+ * Name: void sem_boostpriority(sem_t *sem)
+ *
+ * Description:
+ *
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * 0 (OK) or -1 (ERROR) if unsuccessful
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void sem_boostpriority(FAR sem_t *sem)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+
+ /* Boost the priority of every thread holding counts on this semaphore
+ * that are lower in priority than the new thread that is waiting for a
+ * count.
+ */
+
+ (void)sem_foreachholder(sem, sem_boostholderprio, rtcb);
+}
+
+/****************************************************************************
+ * Name: sem_releaseholder
+ *
+ * Description:
+ * Called from sem_post() after a thread releases one count on the
+ * semaphore.
+ *
+ * Parameters:
+ * sem - A reference to the semaphore being posted
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void sem_releaseholder(FAR sem_t *sem)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ FAR struct semholder_s *pholder;
+
+ /* Find the container for this holder */
+
+ pholder = sem_findholder(sem, rtcb);
+ if (pholder && pholder->counts > 0)
+ {
+ /* Decrement the counts on this holder -- the holder will be freed
+ * later in sem_restorebaseprio.
+ */
+
+ pholder->counts--;
+ }
+}
+
+/****************************************************************************
+ * Name: sem_restorebaseprio
+ *
+ * Description:
+ * This function is called after the current running task releases a
+ * count on the semaphore or an interrupt handler posts a new count. It
+ * will check if we need to drop the priority of any threads holding a
+ * count on the semaphore. Their priority could have been boosted while
+ * they held the count.
+ *
+ * Parameters:
+ * stcb - The TCB of the task that was just started (if any). If the
+ * post action caused a count to be given to another thread, then stcb
+ * is the TCB that received the count. Note, just because stcb received
+ * the count, it does not mean that it it is higher priority than other
+ * threads.
+ * sem - A reference to the semaphore being posted.
+ * - If the semaphore count is <0 then there are still threads waiting
+ * for a count. stcb should be non-null and will be higher priority
+ * than all of the other threads still waiting.
+ * - If it is ==0 then stcb refers to the thread that got the last count;
+ * no other threads are waiting.
+ * - If it is >0 then there should be no threads waiting for counts and
+ * stcb should be null.
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * The scheduler is locked.
+ *
+ ****************************************************************************/
+
+void sem_restorebaseprio(FAR _TCB *stcb, FAR sem_t *sem)
+{
+ /* Check our assumptions */
+
+ DEBUGASSERT((sem->semcount > 0 && stcb == NULL) ||
+ (sem->semcount <= 0 && stcb != NULL));
+
+ /* Handler semaphore counts posed from an interrupt handler differently
+ * from interrupts posted from threads. The primary difference is that
+ * if the semaphore is posted from a thread, then the poster thread is
+ * a player in the priority inheritance scheme. The interrupt handler
+ * externally injects the new count without otherwise participating
+ * itself.
+ */
+
+ if (up_interrupt_context())
+ {
+ sem_restorebaseprio_irq(stcb, sem);
+ }
+ else
+ {
+ sem_restorebaseprio_task(stcb, sem);
+ }
+}
+
+/****************************************************************************
+ * Name: sem_canceled
+ *
+ * Description:
+ * Called from sem_waitirq() after a thread that was waiting for a semaphore
+ * count was awakened because of a signal and the semaphore wait has been
+ * canceled. This function restores the correct thread priority of each
+ * holder of the semaphore.
+ *
+ * Parameters:
+ * sem - A reference to the semaphore no longer being waited for
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_DISABLE_SIGNALS
+void sem_canceled(FAR _TCB *stcb, FAR sem_t *sem)
+{
+ /* Check our assumptions */
+
+ DEBUGASSERT(sem->semcount <= 0);
+
+ /* Adjust the priority of every holder as necessary */
+
+ (void)sem_foreachholder(sem, sem_restoreholderprio, stcb);
+}
+#endif
+
+/****************************************************************************
+ * Name: sem_enumholders
+ *
+ * Description:
+ * Show information about threads currently waiting on this semaphore
+ *
+ * Parameters:
+ * sem - A reference to the semaphore
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_SEM_PHDEBUG)
+void sem_enumholders(FAR sem_t *sem)
+{
+ (void)sem_foreachholder(sem, sem_dumpholder, NULL);
+}
+#endif
+
+/****************************************************************************
+ * Name: sem_nfreeholders
+ *
+ * Description:
+ * Return the number of available holder containers. This is a good way
+ * to find out which threads are not calling sem_destroy.
+ *
+ * Parameters:
+ * sem - A reference to the semaphore
+ *
+ * Return Value:
+ * The number of available holder containers
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_SEM_PHDEBUG)
+int sem_nfreeholders(void)
+{
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ FAR struct semholder_s *pholder;
+ int n;
+
+ for (pholder = g_freeholders, n = 0; pholder; pholder = pholder->flink) n++;
+ return n;
+#else
+ return 0;
+#endif
+}
+#endif
+
+#endif /* CONFIG_PRIORITY_INHERITANCE */
diff --git a/nuttx/sched/sem_initialize.c b/nuttx/sched/sem_initialize.c
new file mode 100644
index 000000000..d8b402825
--- /dev/null
+++ b/nuttx/sched/sem_initialize.c
@@ -0,0 +1,100 @@
+/****************************************************************************
+ * schec/sem_initialize.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <queue.h>
+
+#include "sem_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/* This is a list of dyanamically allocated named semaphores */
+
+dq_queue_t g_nsems;
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_initialize
+ *
+ * Description:
+ * The control structures for all semaphores may be initialized by calling
+ * sem_initialize(). This should be done once at poweron.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void sem_initialize(void)
+{
+ /* Initialize the queue of named semaphores */
+
+ dq_init(&g_nsems);
+
+ /* Initialize holder structures needed to support priority inheritiance */
+
+ sem_initholders();
+}
diff --git a/nuttx/sched/sem_internal.h b/nuttx/sched/sem_internal.h
new file mode 100644
index 000000000..434c551a4
--- /dev/null
+++ b/nuttx/sched/sem_internal.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+ * sched/sem_internal.h
+ *
+ * Copyright (C) 2007, 2009-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_SEM_INTERNAL_H
+#define __SCHED_SEM_INTERNAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <queue.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Type Declarations
+ ****************************************************************************/
+
+/* This is the named semaphore structure */
+
+struct nsem_s
+{
+ FAR struct nsem_s *flink; /* Forward link */
+ FAR struct nsem_s *blink; /* Backward link */
+ uint16_t nconnect; /* Number of connections to semaphore */
+ FAR char *name; /* Semaphore name (NULL if un-named) */
+ bool unlinked; /* true if the semaphore has been unlinked */
+ sem_t sem; /* The semaphore itself */
+};
+
+typedef struct nsem_s nsem_t;
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/* This is a list of dyanamically allocated named semaphores */
+
+extern dq_queue_t g_nsems;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/* Common semaphore logic */
+
+EXTERN void weak_function sem_initialize(void);
+EXTERN void sem_waitirq(FAR _TCB *wtcb, int errcode);
+EXTERN FAR nsem_t *sem_findnamed(const char *name);
+
+/* Special logic needed only by priority inheritance to manage collections of
+ * holders of semaphores.
+ */
+
+#ifdef CONFIG_PRIORITY_INHERITANCE
+EXTERN void sem_initholders(void);
+EXTERN void sem_destroyholder(FAR sem_t *sem);
+EXTERN void sem_addholder(FAR sem_t *sem);
+EXTERN void sem_boostpriority(FAR sem_t *sem);
+EXTERN void sem_releaseholder(FAR sem_t *sem);
+EXTERN void sem_restorebaseprio(FAR _TCB *stcb, FAR sem_t *sem);
+# ifndef CONFIG_DISABLE_SIGNALS
+EXTERN void sem_canceled(FAR _TCB *stcb, FAR sem_t *sem);
+# else
+# define sem_canceled(stcb, sem)
+# endif
+#else
+# define sem_initholders()
+# define sem_destroyholder(sem)
+# define sem_addholder(sem)
+# define sem_boostpriority(sem)
+# define sem_releaseholder(sem)
+# define sem_restorebaseprio(stcb,sem)
+# define sem_canceled(stcb, sem)
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SCHED_SEM_INTERNAL_H */
+
diff --git a/nuttx/sched/sem_open.c b/nuttx/sched/sem_open.c
new file mode 100644
index 000000000..817c36b49
--- /dev/null
+++ b/nuttx/sched/sem_open.c
@@ -0,0 +1,209 @@
+/****************************************************************************
+ * sched/sem_open.c
+ *
+ * Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <string.h>
+#include <semaphore.h>
+#include <errno.h>
+
+#include <nuttx/kmalloc.h>
+
+#include "sem_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_open
+ *
+ * Description:
+ * This function establishes a connection between named semaphores and a
+ * task. Following a call to sem_open() with the semaphore name, the task
+ * may reference the semaphore associated with name using the address
+ * returned by this call. The semaphore may be used in subsequent calls
+ * to sem_wait(), sem_trywait(), and sem_post(). The semaphore remains
+ * usable until the semaphore is closed by a successful call to sem_close().
+ *
+ * If a task makes multiple calls to sem_open() with the same name, then
+ * the same semaphore address is returned (provided there have been no
+ * calls to sem_unlink()).
+ *
+ * Parameters:
+ * name - Semaphore name
+ * oflag - Semaphore creation options. This may either or both of the
+ * following bit settings.
+ * oflag = 0: Connect to the semaphore only if it already exists.
+ * oflag = O_CREAT: Connect to the semaphore if it exists, otherwise
+ * create the semaphore.
+ * oflag = O_CREAT|O_EXCL: Create a new semaphore
+ * unless one of this name already exists.
+ * Optional parameters. When the O_CREAT flag is specified, two optional
+ * parameters are expected:
+ * 1. mode_t mode (ignored), and
+ * 2. unsigned int value. This initial value of the semaphore. Valid
+ * initial values of the semaphore must be less than or equal to
+ * SEM_VALUE_MAX.
+ *
+ * Return Value:
+ * A pointer to sem_t or -1 (ERROR) if unsuccessful.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+FAR sem_t *sem_open (FAR const char *name, int oflag, ...)
+{
+ int namelen;
+ FAR nsem_t *psem;
+ FAR sem_t *sem = (FAR sem_t*)ERROR;
+ va_list arg; /* Points to each un-named argument */
+ mode_t mode; /* Creation mode parameter (ignored) */
+ unsigned int value; /* Semaphore value parameter */
+
+ /* Make sure that a non-NULL name is supplied */
+
+ if (name)
+ {
+ /* The POSIX specification requires that the "check for the
+ * existence of a semaphore and the creation of the semaphore
+ * if it does not exist shall be atomic with respect to other
+ * processes executing sem_open()..." A simple sched_lock()
+ * should be sufficient to meet this requirement.
+ */
+
+ sched_lock();
+ namelen = strlen(name);
+ if (namelen > 0)
+ {
+ /* See if the semaphore already exists */
+
+ psem = sem_findnamed(name);
+ if (psem)
+ {
+ /* It does. Check if the caller wanted to created
+ * a new semahore with this name.
+ */
+
+ if (!(oflag & O_CREAT) || !(oflag & O_EXCL))
+ {
+ /* Allow a new connection to the semaphore */
+
+ psem->nconnect++;
+ sem = &psem->sem;
+ }
+ }
+
+ /* It doesn't exist. Should we create one? */
+
+ else if ((oflag & O_CREAT) != 0)
+ {
+ /* Set up to get the optional arguments needed to create
+ * a message queue.
+ */
+
+ va_start(arg, oflag);
+ mode = va_arg(arg, mode_t);
+ value = va_arg(arg, unsigned int);
+
+ /* Verify that a legal initial value was selected. */
+
+ if (value <= SEM_VALUE_MAX)
+ {
+ /* Allocate memory for the new semaphore */
+
+ psem = (FAR nsem_t*)kmalloc((sizeof(nsem_t) + namelen + 1));
+ if (psem)
+ {
+ /* Initialize the named semaphore */
+
+ sem = &psem->sem;
+ sem_init(sem, 0, value);
+
+ psem->nconnect = 1;
+ psem->unlinked = false;
+ psem->name = (FAR char*)psem + sizeof(nsem_t);
+ strcpy(psem->name, name);
+
+ /* Add the new semaphore to the list of named
+ * semaphores
+ */
+
+ dq_addfirst((FAR dq_entry_t*)psem, &g_nsems);
+ }
+
+ /* Clean-up variable argument stuff */
+
+ va_end(arg);
+ }
+ }
+ }
+
+ sched_unlock();
+ }
+
+ return sem;
+}
+
diff --git a/nuttx/sched/sem_post.c b/nuttx/sched/sem_post.c
new file mode 100644
index 000000000..1c694b68c
--- /dev/null
+++ b/nuttx/sched/sem_post.c
@@ -0,0 +1,182 @@
+/****************************************************************************
+ * sched/sem_post.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <limits.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sem_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_post
+ *
+ * Description:
+ * When a task has finished with a semaphore, it will call sem_post().
+ * This function unlocks the semaphore referenced by sem by performing the
+ * semaphore unlock operation on that semaphore.
+ *
+ * If the semaphore value resulting from this operation is positive, then
+ * no tasks were blocked waiting for the semaphore to become unlocked; the
+ * semaphore is simply incremented.
+ *
+ * If the value of the semaphore resulting from this operation is zero,
+ * then one of the tasks blocked waiting for the semaphore shall be
+ * allowed to return successfully from its call to sem_wait().
+ *
+ * Parameters:
+ * sem - Semaphore descriptor
+ *
+ * Return Value:
+ * 0 (OK) or -1 (ERROR) if unsuccessful
+ *
+ * Assumptions:
+ * This function cannot be called from an interrupt handler.
+ * It assumes the currently executing task is the one that
+ * is performing the unlock.
+ *
+ ****************************************************************************/
+
+int sem_post(FAR sem_t *sem)
+{
+ FAR _TCB *stcb = NULL;
+ int ret = ERROR;
+ irqstate_t saved_state;
+
+ /* Make sure we were supplied with a valid semaphore. */
+
+ if (sem)
+ {
+ /* The following operations must be performed with interrupts
+ * disabled because sem_post() may be called from an interrupt
+ * handler.
+ */
+
+ saved_state = irqsave();
+
+ /* Perform the semaphore unlock operation. */
+
+ ASSERT(sem->semcount < SEM_VALUE_MAX);
+ sem_releaseholder(sem);
+ sem->semcount++;
+
+#ifdef CONFIG_PRIORITY_INHERITANCE
+ /* Don't let any unblocked tasks run until we complete any priority
+ * restoration steps. Interrupts are disabled, but we do not want
+ * the head of the read-to-run list to be modified yet.
+ *
+ * NOTE: If this sched_lock is called from an interrupt handler, it
+ * will do nothing.
+ */
+
+ sched_lock();
+#endif
+ /* If the result of of semaphore unlock is non-positive, then
+ * there must be some task waiting for the semaphore.
+ */
+
+ if (sem->semcount <= 0)
+ {
+ /* Check if there are any tasks in the waiting for semaphore
+ * task list that are waiting for this semaphore. This is a
+ * prioritized list so the first one we encounter is the one
+ * that we want.
+ */
+
+ for (stcb = (FAR _TCB*)g_waitingforsemaphore.head;
+ (stcb && stcb->waitsem != sem);
+ stcb = stcb->flink);
+
+ if (stcb)
+ {
+ /* It is, let the task take the semaphore */
+
+ stcb->waitsem = NULL;
+
+ /* Restart the waiting task. */
+
+ up_unblock_task(stcb);
+ }
+ }
+
+ /* Check if we need to drop the priority of any threads holding
+ * this semaphore. The priority could have been boosted while they
+ * held the semaphore.
+ */
+
+#ifdef CONFIG_PRIORITY_INHERITANCE
+ sem_restorebaseprio(stcb, sem);
+ sched_unlock();
+#endif
+ ret = OK;
+
+ /* Interrupts may now be enabled. */
+
+ irqrestore(saved_state);
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/sem_timedwait.c b/nuttx/sched/sem_timedwait.c
new file mode 100644
index 000000000..6a4724406
--- /dev/null
+++ b/nuttx/sched/sem_timedwait.c
@@ -0,0 +1,286 @@
+/****************************************************************************
+ * sched/sem_timedwait.c
+ *
+ * Copyright (C) 2011 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 <stdint.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <time.h>
+#include <errno.h>
+#include <wdog.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "clock_internal.h"
+#include "sem_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_timeout
+ *
+ * Description:
+ * This function is called if the timeout elapses before the message queue
+ * becomes non-empty.
+ *
+ * Parameters:
+ * argc - the number of arguments (should be 1)
+ * pid - the task ID of the task to wakeup
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void sem_timeout(int argc, uint32_t pid)
+{
+ FAR _TCB *wtcb;
+ irqstate_t flags;
+
+ /* Disable interrupts to avoid race conditions */
+
+ flags = irqsave();
+
+ /* Get the TCB associated with this pid. It is possible that
+ * task may no longer be active when this watchdog goes off.
+ */
+
+ wtcb = sched_gettcb((pid_t)pid);
+
+ /* It is also possible that an interrupt/context switch beat us to the
+ * punch and already changed the task's state.
+ */
+
+ if (wtcb && wtcb->task_state == TSTATE_WAIT_SEM)
+ {
+ /* Cancel the semaphore wait */
+
+ sem_waitirq(wtcb, ETIMEDOUT);
+ }
+
+ /* Interrupts may now be enabled. */
+
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_timedwait
+ *
+ * Description:
+ * This function will lock the semaphore referenced by sem as in the
+ * sem_wait() function. However, if the semaphore cannot be locked without
+ * waiting for another process or thread to unlock the semaphore by
+ * performing a sem_post() function, this wait will be terminated when the
+ * specified timeout expires.
+ *
+ * The timeout will expire when the absolute time specified by abstime
+ * passes, as measured by the clock on which timeouts are based (that is,
+ * when the value of that clock equals or exceeds abstime), or if the
+ * absolute time specified by abstime has already been passed at the
+ * time of the call.
+ *
+ * Parameters:
+ * sem - Semaphore object
+ * abstime - The absolute time to wait until a timeout is declared.
+ *
+ * Return Value:
+ * One success, the length of the selected message in bytes.is
+ * returned. On failure, -1 (ERROR) is returned and the errno
+ * is set appropriately:
+ *
+ * EINVAL The sem argument does not refer to a valid semaphore. Or the
+ * thread would have blocked, and the abstime parameter specified
+ * a nanoseconds field value less than zero or greater than or
+ * equal to 1000 million.
+ * ETIMEDOUT The semaphore could not be locked before the specified timeout
+ * expired.
+ * EDEADLK A deadlock condition was detected.
+ * EINTR A signal interrupted this function.
+ *
+ ****************************************************************************/
+
+int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
+{
+ WDOG_ID wdog;
+ irqstate_t flags;
+ int ticks;
+ int err;
+ int ret = ERROR;
+
+ DEBUGASSERT(up_interrupt_context() == false);
+
+ /* Verify the input parameters and, in case of an error, set
+ * errno appropriately.
+ */
+
+#ifdef CONFIG_DEBUG
+ if (!abstime || !sem)
+ {
+ err = EINVAL;
+ goto errout;
+ }
+#endif
+
+ /* Create a watchdog. We will not actually need this watchdog
+ * unless the the semaphore is unavailable, but we will reserve it up
+ * front before we enter the following critical section.
+ */
+
+ wdog = wd_create();
+ if (!wdog)
+ {
+ err = ENOMEM;
+ goto errout;
+ }
+
+ /* We will disable interrupts until we have completed the semaphore
+ * wait. We need to do this (as opposed to just disabling pre-emption)
+ * because there could be interrupt handlers that are asynchronoulsy
+ * posting semaphores and to prevent race conditions with watchdog
+ * timeout. This is not too bad because interrupts will be re-
+ * enabled while we are blocked waiting for the semaphore.
+ */
+
+ flags = irqsave();
+
+ /* Try to take the semaphore without waiting. */
+
+ ret = sem_trywait(sem);
+ if (ret == 0)
+ {
+ /* We got it! */
+
+ irqrestore(flags);
+ wd_delete(wdog);
+ return OK;
+ }
+
+ /* We will have to wait for the semphore. Make sure that we were provided
+ * with a valid timeout.
+ */
+
+ if (abstime->tv_sec < 0 || abstime->tv_nsec > 1000000000)
+ {
+ err = EINVAL;
+ goto errout_disabled;
+ }
+
+ /* Convert the timespec to clock ticks. We must have interrupts
+ * disabled here so that this time stays valid until the wait begins.
+ */
+
+ err = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
+
+ /* If the time has already expired return immediately. */
+
+ if (err == OK && ticks <= 0)
+ {
+ err = ETIMEDOUT;
+ goto errout_disabled;
+ }
+
+ /* Handle any time-related errors */
+
+ if (err != OK)
+ {
+ goto errout_disabled;
+ }
+
+ /* Start the watchdog */
+
+ err = OK;
+ wd_start(wdog, ticks, (wdentry_t)sem_timeout, 1, getpid());
+
+ /* Now perform the blocking wait */
+
+ ret = sem_wait(sem);
+
+ /* Stop the watchdog timer */
+
+ wd_cancel(wdog);
+
+ /* We can now restore interrupts and delete the watchdog */
+
+ irqrestore(flags);
+ wd_delete(wdog);
+
+ /* We are either returning success or an error detected by sem_wait()
+ * or the timeout detected by sem_timeout(). The 'errno' value has
+ * been set appropriately by sem_wait() or sem_timeout() in those
+ * cases.
+ */
+
+ return ret;
+
+/* Error exits */
+
+errout_disabled:
+ irqrestore(flags);
+ wd_delete(wdog);
+errout:
+ set_errno(err);
+ return ERROR;
+}
diff --git a/nuttx/sched/sem_trywait.c b/nuttx/sched/sem_trywait.c
new file mode 100644
index 000000000..cbd8dae69
--- /dev/null
+++ b/nuttx/sched/sem_trywait.c
@@ -0,0 +1,142 @@
+/****************************************************************************
+ * sched/sem_trywait.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <errno.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sem_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_trywait
+ *
+ * Description:
+ * This function locks the specified semaphore only if the semaphore is
+ * currently not locked. Otherwise, it locks the semaphore. In either
+ * case, the call returns without blocking.
+ *
+ * Parameters:
+ * sem - the semaphore descriptor
+ *
+ * Return Value:
+ * 0 (OK) or -1 (ERROR) if unsuccessful. If this function returns -1
+ * (ERROR),then the cause of the failure will be reported in "errno" as:
+ *
+ * EINVAL: Invalid attempt to get the semaphore
+ * EAGAIN: The semaphore is not available.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sem_trywait(FAR sem_t *sem)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ irqstate_t saved_state;
+ int ret = ERROR;
+
+ /* This API should not be called from interrupt handlers */
+
+ DEBUGASSERT(up_interrupt_context() == false)
+
+ /* Assume any errors reported are due to invalid arguments. */
+
+ set_errno(EINVAL);
+
+ if (sem)
+ {
+ /* The following operations must be performed with interrupts disabled
+ * because sem_post() may be called from an interrupt handler.
+ */
+
+ saved_state = irqsave();
+
+ /* Any further errors could only be occurred because the semaphore
+ * is not available.
+ */
+
+ set_errno(EAGAIN);
+
+ /* If the semaphore is available, give it to the requesting task */
+
+ if (sem->semcount > 0)
+ {
+ /* It is, let the task take the semaphore */
+
+ sem->semcount--;
+ rtcb->waitsem = NULL;
+ ret = OK;
+ }
+
+ /* Interrupts may now be enabled. */
+
+ irqrestore(saved_state);
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/sem_unlink.c b/nuttx/sched/sem_unlink.c
new file mode 100644
index 000000000..6fe011540
--- /dev/null
+++ b/nuttx/sched/sem_unlink.c
@@ -0,0 +1,140 @@
+/****************************************************************************
+ * sched/sem_unlink.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <queue.h>
+
+#include "os_internal.h"
+#include "sem_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_unlink
+ *
+ * Description:
+ * This function removes the semaphore named by the input parameter 'name.'
+ * If the semaphore named by 'name' is currently referenced by other task,
+ * the sem_unlink() will have no effect on the state of the semaphore. If
+ * one or more processes have the semaphore open when sem_unlink() is
+ * called, destruction of the semaphore will be postponed until all
+ * references to the semaphore have been destroyed by calls of sem_close().
+ *
+ * Parameters:
+ * name - Semaphore name
+ *
+ * Return Value:
+ * 0 (OK), or -1 (ERROR) if unsuccessful.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sem_unlink(FAR const char *name)
+{
+ FAR nsem_t *psem;
+ int ret = ERROR;
+
+ /* Verify the input values */
+
+ if (name)
+ {
+ sched_lock();
+
+ /* Find the named semaphore */
+
+ psem = sem_findnamed(name);
+
+ /* Check if the semaphore was found */
+
+ if (psem)
+ {
+ /* If the named semaphore was found and if there are no
+ * connects to it, then deallocate it
+ */
+
+ if (!psem->nconnect)
+ {
+ dq_rem((FAR dq_entry_t*)psem, &g_nsems);
+ sched_free(psem);
+ }
+
+ /* If one or more process still has the semaphore open,
+ * then just mark it as unlinked. The unlinked semaphore will
+ * be deleted when the final process closes the semaphore.
+ */
+
+ else
+ {
+ psem->unlinked = true;
+ }
+ ret = OK;
+ }
+
+ sched_unlock();
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/sem_wait.c b/nuttx/sched/sem_wait.c
new file mode 100644
index 000000000..9dfbaa6c3
--- /dev/null
+++ b/nuttx/sched/sem_wait.c
@@ -0,0 +1,216 @@
+/****************************************************************************
+ * sched/sem_wait.c
+ *
+ * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <assert.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sem_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_wait
+ *
+ * Description:
+ * This function attempts to lock the semaphore referenced by 'sem'. If
+ * the semaphore value is (<=) zero, then the calling task will not return
+ * until it successfully acquires the lock.
+ *
+ * Parameters:
+ * sem - Semaphore descriptor.
+ *
+ * Return Value:
+ * 0 (OK), or -1 (ERROR) is unsuccessful
+ * If this function returns -1 (ERROR), then the cause of the failure will
+ * be reported in 'errno' as:
+ * - EINVAL: Invalid attempt to get the semaphore
+ * - EINTR: The wait was interrupted by the receipt of a signal.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sem_wait(FAR sem_t *sem)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ int ret = ERROR;
+ irqstate_t saved_state;
+
+ /* This API should not be called from interrupt handlers */
+
+ DEBUGASSERT(up_interrupt_context() == false)
+
+ /* Assume any errors reported are due to invalid arguments. */
+
+ errno = EINVAL;
+
+ if (sem)
+ {
+ /* The following operations must be performed with interrupts
+ * disabled because sem_post() may be called from an interrupt
+ * handler.
+ */
+
+ saved_state = irqsave();
+
+ /* Check if the lock is available */
+
+ if (sem->semcount > 0)
+ {
+ /* It is, let the task take the semaphore. */
+
+ sem->semcount--;
+ sem_addholder(sem);
+ rtcb->waitsem = NULL;
+ ret = OK;
+ }
+
+ /* The semaphore is NOT available, We will have to block the
+ * current thread of execution.
+ */
+
+ else
+ {
+ /* First, verify that the task is not already waiting on a
+ * semaphore
+ */
+
+ if (rtcb->waitsem != NULL)
+ {
+ PANIC(OSERR_BADWAITSEM);
+ }
+
+ /* Handle the POSIX semaphore (but don't set the owner yet) */
+
+ sem->semcount--;
+
+ /* Save the waited on semaphore in the TCB */
+
+ rtcb->waitsem = sem;
+
+ /* If priority inheritance is enabled, then check the priority of
+ * the holder of the semaphore.
+ */
+
+#ifdef CONFIG_PRIORITY_INHERITANCE
+ /* Disable context switching. The following operations must be
+ * atomic with regard to the scheduler.
+ */
+
+ sched_lock();
+
+ /* Boost the priority of any threads holding a count on the
+ * semaphore.
+ */
+
+ sem_boostpriority(sem);
+#endif
+ /* Add the TCB to the prioritized semaphore wait queue */
+
+ errno = 0;
+ up_block_task(rtcb, TSTATE_WAIT_SEM);
+
+ /* When we resume at this point, either (1) the semaphore has been
+ * assigned to this thread of execution, or (2) the semaphore wait
+ * has been interrupted by a signal or a timeout. We can detect these
+ * latter cases be examining the errno value.
+ *
+ * In the event that the semaphore wait was interrupted by a signal or
+ * a timeout, certain semaphore clean-up operations have already been
+ * performed (see sem_waitirq.c). Specifically:
+ *
+ * - sem_canceled() was called to restore the priority of all threads
+ * that hold a reference to the semaphore,
+ * - The semaphore count was decremented, and
+ * - tcb->waitsem was nullifed.
+ *
+ * It is necesaary to do these things in sem_waitirq.c because a long
+ * time may elapse between the time that the signal was issued and
+ * this thread is awakened and this leaves a door open to several
+ * race conditions.
+ */
+
+ if (errno != EINTR && errno != ETIMEDOUT)
+ {
+ /* Not awakened by a signal or a timeout... We hold the semaphore */
+
+ sem_addholder(sem);
+ ret = OK;
+ }
+
+#ifdef CONFIG_PRIORITY_INHERITANCE
+ sched_unlock();
+#endif
+ }
+
+ /* Interrupts may now be enabled. */
+
+ irqrestore(saved_state);
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/sem_waitirq.c b/nuttx/sched/sem_waitirq.c
new file mode 100644
index 000000000..3d3af18de
--- /dev/null
+++ b/nuttx/sched/sem_waitirq.c
@@ -0,0 +1,145 @@
+/****************************************************************************
+ * sched/sem_waitirq.c
+ *
+ * Copyright (C) 2007-2010 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 <sched.h>
+#include <errno.h>
+#include <nuttx/arch.h>
+
+#include "sem_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sem_waitirq
+ *
+ * Description:
+ * This function is called when a signal is received by a task that is
+ * waiting on a semaphore. According to the POSIX spec, "...the calling
+ * thread shall not return from the call to [sem_wait] until it either
+ * locks the semaphore or the call is interrupted by a signal."
+ *
+ * Parameters:
+ * wtcb - A pointer to the TCB of the task that is waiting on a
+ * semphaphore, but has received a signal or timeout instead.
+ * errcode - EINTR if the semaphore wait was awakened by a signal;
+ * ETIMEDOUT if awakened by a timeout
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void sem_waitirq(FAR _TCB *wtcb, int errcode)
+{
+ irqstate_t saved_state;
+
+ /* Disable interrupts. This is necessary (unfortunately) because an
+ * interrupt handler may attempt to post the semaphore while we are
+ * doing this.
+ */
+
+ saved_state = irqsave();
+
+ /* It is possible that an interrupt/context switch beat us to the punch
+ * and already changed the task's state.
+ */
+
+ if (wtcb->task_state == TSTATE_WAIT_SEM)
+ {
+ sem_t *sem = wtcb->waitsem;
+ DEBUGASSERT(sem != NULL && sem->semcount < 0);
+
+ /* Restore the correct priority of all threads that hold references
+ * to this semaphore.
+ */
+
+ sem_canceled(wtcb, sem);
+
+ /* And increment the count on the semaphore. This releases the count
+ * that was taken by sem_post(). This count decremented the semaphore
+ * count to negative and caused the thread to be blocked in the first
+ * place.
+ */
+
+ sem->semcount++;
+
+ /* Indicate that the semaphore wait is over. */
+
+ wtcb->waitsem = NULL;
+
+ /* Mark the errno value for the thread. */
+
+ wtcb->pterrno = errcode;
+
+ /* Restart the task. */
+
+ up_unblock_task(wtcb);
+ }
+
+ /* Interrupts may now be enabled. */
+
+ irqrestore(saved_state);
+}
+
diff --git a/nuttx/sched/sig_action.c b/nuttx/sched/sig_action.c
new file mode 100644
index 000000000..fef5f1558
--- /dev/null
+++ b/nuttx/sched/sig_action.c
@@ -0,0 +1,272 @@
+/****************************************************************************
+ * sched/sig_action.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <signal.h>
+#include <queue.h>
+#include <sched.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#define COPY_SIGACTION(t,f) \
+ { (t)->sa_sigaction = (f)->sa_sigaction; \
+ (t)->sa_mask = (f)->sa_mask; \
+ (t)->sa_flags = (f)->sa_flags; }
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sig_allocateaction
+ *
+ * Description:
+ * Allocate a new element for a sigaction queue
+ *
+ ****************************************************************************/
+
+static FAR sigactq_t *sig_allocateaction(void)
+{
+ FAR sigactq_t *sigact;
+
+ /* Try to get the signal action structure from the free list */
+
+ sigact = (FAR sigactq_t*)sq_remfirst(&g_sigfreeaction);
+
+ /* Check if we got one. */
+
+ if (!sigact)
+ {
+ /* Add another block of signal actions to the list */
+
+ sig_allocateactionblock();
+
+ /* And try again */
+
+ sigact = (FAR sigactq_t*)sq_remfirst(&g_sigfreeaction);
+ if (!sigact)
+ {
+ PANIC(OSERR_OUTOFMEMORY);
+ }
+ }
+
+ return sigact;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sigaction
+ *
+ * Description:
+ * This function allows the calling process to examine and/or specify the
+ * action to be associated with a specific signal.
+ *
+ * The structure sigaction, used to describe an action to be taken, is
+ * defined to include the following members:
+ *
+ * - sa_u.sa_handler: Pointer to a signal-catching function
+ * - sa_u.sa_sigaction: Alternative form of the signal-catching function
+ * - sa_mask: An additional set of signals to be blocked during execution
+ * of a signal catching function
+ * - sa_flags. Special flags to affect the behavior of a signal.
+ *
+ * If the argument 'act' is not NULL, it points to a structure specifying
+ * the action to be associated with the specified signal. If the argument
+ * 'oact' is not NULL, the action previously associated with the signal
+ * is stored in the location pointed to by the argument 'oact.'
+ *
+ * When a signal is caught by a signal-catching function installed by
+ * sigaction() function, a new signal mask is calculated and installed for
+ * the duration of the signal-catching function. This mask is formed by
+ * taking the union of the current signal mask and the value of the
+ * sa_mask for the signal being delivered and then including the signal
+ * being delivered. If and when the user's signal handler returns, the
+ * original signal mask is restored.
+ *
+ * Once an action is installed for a specific signal, it remains installed
+ * until another action is explicitly requested by another call to sigaction().
+ *
+ * Parameters:
+ * sig - Signal of interest
+ * act - Location of new handler
+ * oact - Location to store only handler
+ *
+ * Return Value:
+ * 0 (OK), or -1 (ERROR) if the signal number is invalid.
+ * (errno is not set)
+ *
+ * Assumptions:
+ *
+ * POSIX Compatibility:
+ * - Special values of sa_handler in the struct sigaction
+ * act input not handled (SIG_DFL, SIG_IGN).
+ * - All sa_flags in struct sigaction of act input are
+ * ignored (all treated like SA_SIGINFO).
+ *
+ ****************************************************************************/
+
+int sigaction(int signo, FAR const struct sigaction *act, FAR struct sigaction *oact)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ FAR sigactq_t *sigact;
+ int ret = ERROR; /* Assume failure */
+
+ /* Since sigactions can only be installed from the running thread of
+ * execution, no special precautions should be necessary.
+ */
+
+ /* Verify the signal */
+
+ if (GOOD_SIGNO(signo))
+ {
+ ret = OK; /* Assume success */
+
+ /* Find the signal in the sigactionq */
+
+ sigact = sig_findaction(rtcb, signo);
+
+ /* Return the old sigaction value if so requested */
+
+ if (oact)
+ {
+ if (sigact)
+ {
+ COPY_SIGACTION(oact, &sigact->act);
+ }
+ else
+ {
+ /* There isn't an old value */
+
+ oact->sa_u._sa_handler = NULL;
+ oact->sa_mask = NULL_SIGNAL_SET;
+ oact->sa_flags = 0;
+ }
+ }
+
+ /* If no sigaction was found, but one is needed, then
+ * allocate one.
+ */
+
+ if (!sigact && act && act->sa_u._sa_handler)
+ {
+ sigact = sig_allocateaction();
+
+ /* An error has occurred if we could not allocate the sigaction */
+
+ if (!sigact)
+ {
+ ret = ERROR;
+ }
+ else
+ {
+ /* Put the signal number in the queue entry */
+
+ sigact->signo = (uint8_t)signo;
+
+ /* Add the new sigaction to sigactionq */
+
+ sq_addlast((FAR sq_entry_t*)sigact, &rtcb->sigactionq);
+ }
+ }
+
+ /* Set the new sigaction if so requested */
+
+ if ((sigact) && (act))
+ {
+ /* Check if it is a request to install a new handler */
+
+ if (act->sa_u._sa_handler)
+ {
+ COPY_SIGACTION(&sigact->act, act);
+ }
+
+ /* No.. It is a request to remove the old handler */
+
+ else
+ {
+ /* Remove the old sigaction from sigactionq */
+
+ sq_rem((FAR sq_entry_t*)sigact, &rtcb->sigactionq);
+
+ /* And deallocate it */
+
+ sig_releaseaction(sigact);
+ }
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: sig_releaseaction
+ *
+ * Description:
+ * Deallocate a sigaction Q entry
+ *
+ ****************************************************************************/
+
+void sig_releaseaction(FAR sigactq_t *sigact)
+{
+ /* Just put it back on the free list */
+
+ sq_addlast((FAR sq_entry_t*)sigact, &g_sigfreeaction);
+}
diff --git a/nuttx/sched/sig_allocatependingsigaction.c b/nuttx/sched/sig_allocatependingsigaction.c
new file mode 100644
index 000000000..15d6470ca
--- /dev/null
+++ b/nuttx/sched/sig_allocatependingsigaction.c
@@ -0,0 +1,137 @@
+/************************************************************************
+ * sched/sig_allocatependingsigaction.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <signal.h>
+#include <assert.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_allocatependingsigaction
+ *
+ * Description:
+ * Allocate a new element for the pending signal action queue
+ *
+ ************************************************************************/
+
+FAR sigq_t *sig_allocatependingsigaction(void)
+{
+ FAR sigq_t *sigq;
+ irqstate_t saved_state;
+
+ /* Check if we were called from an interrupt handler. */
+
+ if (up_interrupt_context())
+ {
+ /* Try to get the pending signal action structure from the free list */
+
+ sigq = (FAR sigq_t*)sq_remfirst(&g_sigpendingaction);
+
+ /* If so, then try the special list of structures reserved for
+ * interrupt handlers
+ */
+
+ if (!sigq)
+ {
+ sigq = (FAR sigq_t*)sq_remfirst(&g_sigpendingirqaction);
+ }
+ }
+
+ /* If we were not called from an interrupt handler, then we are
+ * free to allocate pending signal action structures if necessary. */
+
+ else
+ {
+ /* Try to get the pending signal action structure from the free list */
+
+ saved_state = irqsave();
+ sigq = (FAR sigq_t*)sq_remfirst(&g_sigpendingaction);
+ irqrestore(saved_state);
+
+ /* Check if we got one. */
+
+ if (!sigq)
+ {
+ /* No...Try the resource pool */
+
+ if (!sigq)
+ {
+ sigq = (FAR sigq_t *)kmalloc((sizeof (sigq_t)));
+ }
+
+ /* Check if we got an allocated message */
+
+ if (sigq)
+ {
+ sigq->type = SIG_ALLOC_DYN;
+ }
+ }
+ }
+
+ return sigq;
+}
+
diff --git a/nuttx/sched/sig_cleanup.c b/nuttx/sched/sig_cleanup.c
new file mode 100644
index 000000000..4dcc04f8b
--- /dev/null
+++ b/nuttx/sched/sig_cleanup.c
@@ -0,0 +1,118 @@
+/************************************************************************
+ * sched/sig_cleanup.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_cleanup
+ *
+ * Description:
+ * Deallocate all signal-related lists in a TCB. This function is
+ * called only at task deletion time. The caller is expected to have
+ * assured the critical section necessary to perform this action.
+ *
+ ************************************************************************/
+
+void sig_cleanup(FAR _TCB *stcb)
+{
+ FAR sigactq_t *sigact;
+ FAR sigq_t *sigq;
+ FAR sigpendq_t *sigpend;
+
+ /* Deallocate all entries in the list of signal actions */
+
+ while ((sigact = (FAR sigactq_t*)sq_remfirst(&stcb->sigactionq)) != NULL)
+ {
+ sig_releaseaction(sigact);
+ }
+
+ /* Deallocate all entries in the list of pending signals */
+
+ while ((sigpend = (FAR sigpendq_t*)sq_remfirst(&stcb->sigpendingq)) != NULL)
+ {
+ sig_releasependingsignal(sigpend);
+ }
+
+ /* Deallocate all entries in the list of pending signal actions */
+
+ while ((sigq = (FAR sigq_t*)sq_remfirst(&stcb->sigpendactionq)) != NULL)
+ {
+ sig_releasependingsigaction(sigq);
+ }
+
+ /* Deallocate all entries in the list of posted signal actions */
+
+ while ((sigq = (FAR sigq_t*)sq_remfirst(&stcb->sigpostedq)) != NULL)
+ {
+ sig_releasependingsigaction(sigq);
+ }
+
+ /* Misc. signal-related clean-up */
+
+ stcb->sigprocmask = ALL_SIGNAL_SET;
+ stcb->sigwaitmask = NULL_SIGNAL_SET;
+}
diff --git a/nuttx/sched/sig_deliver.c b/nuttx/sched/sig_deliver.c
new file mode 100644
index 000000000..a1297fbc2
--- /dev/null
+++ b/nuttx/sched/sig_deliver.c
@@ -0,0 +1,159 @@
+/****************************************************************************
+ * sched/sig_deliver.c
+ *
+ * Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sem_internal.h"
+#include "sig_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sig_deliver
+ *
+ * Description:
+ * This function is called on the thread of execution of the signal
+ * receiving task. It processes all queued signals then returns.
+ *
+ ****************************************************************************/
+
+void sig_deliver(FAR _TCB *stcb)
+{
+ FAR sigq_t *sigq;
+ FAR sigq_t *next;
+ sigset_t savesigprocmask;
+ irqstate_t saved_state;
+ int saved_errno;
+
+ sched_lock();
+
+ /* Save the thread errno. When we finished dispatching the
+ * signal actions and resume the task, the errno value must
+ * be unchanged by the operation of the signal handling. In
+ * particular, the EINTR indication that says that the task
+ * was reawakened by a signal must be retained.
+ */
+
+ saved_errno = stcb->pterrno;
+ for (sigq = (FAR sigq_t*)stcb->sigpendactionq.head; (sigq); sigq = next)
+ {
+ next = sigq->flink;
+ sdbg("Sending signal sigq=0x%x\n", sigq);
+
+ /* Remove the signal structure from the sigpendactionq and place it
+ * in the sigpostedq. NOTE: Since signals are processed one at a
+ * time, there should never be more than one signal in the sigpostedq
+ */
+
+ saved_state = irqsave();
+ sq_rem((FAR sq_entry_t*)sigq, &(stcb->sigpendactionq));
+ sq_addlast((FAR sq_entry_t*)sigq, &(stcb->sigpostedq));
+ irqrestore(saved_state);
+
+ /* Call the signal handler (unless the signal was cancelled)
+ *
+ * Save a copy of the old sigprocmask and install the new
+ * (temporary) sigprocmask. The new sigprocmask is the union
+ * of the current sigprocmask and the sa_mask for the signal being
+ * delivered plus the signal being delivered.
+ */
+
+ savesigprocmask = stcb->sigprocmask;
+ stcb->sigprocmask = savesigprocmask | sigq->mask | SIGNO2SET(sigq->info.si_signo);
+
+ /* Deliver the signal */
+
+ (*sigq->action.sighandler)(sigq->info.si_signo, &sigq->info, NULL);
+
+ /* Restore the original sigprocmask */
+
+ stcb->sigprocmask = savesigprocmask;
+
+ /* Now, handle the (rare?) case where (a) a blocked signal was
+ * received while the signal handling executed but (b) restoring the
+ * original sigprocmask will unblock the signal.
+ */
+
+ sig_unmaskpendingsignal();
+
+ /* Remove the signal from the sigpostedq */
+
+ saved_state = irqsave();
+ sq_rem((FAR sq_entry_t*)sigq, &(stcb->sigpostedq));
+ irqrestore(saved_state);
+
+ /* Then deallocate it */
+
+ sig_releasependingsigaction(sigq);
+ }
+
+ stcb->pterrno = saved_errno;
+ sched_unlock();
+}
+
diff --git a/nuttx/sched/sig_findaction.c b/nuttx/sched/sig_findaction.c
new file mode 100644
index 000000000..4115332b6
--- /dev/null
+++ b/nuttx/sched/sig_findaction.c
@@ -0,0 +1,100 @@
+/************************************************************************
+ * sched/sig_findaction.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+#include "sig_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_findaction
+ *
+ * Description:
+ * Allocate a new element for a signal queue
+ *
+ ************************************************************************/
+
+FAR sigactq_t *sig_findaction(FAR _TCB *stcb, int signo)
+{
+ FAR sigactq_t *sigact = NULL;
+
+ /* Verify the caller's sanity */
+
+ if (stcb)
+ {
+ /* Sigactions can only be assigned to the currently executing
+ * thread. So, a simple lock ought to give us sufficient
+ * protection.
+ */
+
+ sched_lock();
+
+ /* Seach the list for a sigaction on this signal */
+
+ for(sigact = (FAR sigactq_t*)stcb->sigactionq.head;
+ ((sigact) && (sigact->signo != signo));
+ sigact = sigact->flink);
+
+ sched_unlock();
+ }
+
+ return sigact;
+}
diff --git a/nuttx/sched/sig_initialize.c b/nuttx/sched/sig_initialize.c
new file mode 100644
index 000000000..966d818a1
--- /dev/null
+++ b/nuttx/sched/sig_initialize.c
@@ -0,0 +1,271 @@
+/************************************************************************
+ * sched/sig_initialize.c
+ *
+ * Copyright (C) 2007, 2009, 2011 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 <stdint.h>
+#include <queue.h>
+#include <nuttx/kmalloc.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/* The g_sigfreeaction data structure is a list of available signal
+ * action structures.
+ */
+
+sq_queue_t g_sigfreeaction;
+
+/* The g_sigpendingaction data structure is a list of available pending
+ * signal action structures.
+ */
+
+sq_queue_t g_sigpendingaction;
+
+/* The g_sigpendingirqaction is a list of available pending signal actions
+ * that are reserved for use by interrupt handlers.
+ */
+
+sq_queue_t g_sigpendingirqaction;
+
+/* The g_sigpendingsignal data structure is a list of available pending
+ * signal structures.
+ */
+
+sq_queue_t g_sigpendingsignal;
+
+/* The g_sigpendingirqsignal data structure is a list of available
+ * pending signal structures that are reserved for use by interrupt
+ * handlers.
+ */
+
+sq_queue_t g_sigpendingirqsignal;
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/* g_sigactionalloc is a pointer to the start of the allocated blocks of
+ * signal actions.
+ */
+
+static sigactq_t *g_sigactionalloc;
+
+/* g_sigpendingactionalloc is a pointer to the start of the allocated
+ * blocks of pending signal actions.
+ */
+
+static sigq_t *g_sigpendingactionalloc;
+
+/* g_sigpendingirqactionalloc is a pointer to the start of the allocated
+ * block of pending signal actions.
+ */
+
+static sigq_t *g_sigpendingirqactionalloc;
+
+/* g_sigpendingsignalalloc is a pointer to the start of the allocated
+ * blocks of pending signals.
+ */
+
+static sigpendq_t *g_sigpendingsignalalloc;
+
+/* g_sigpendingirqsignalalloc is a pointer to the start of the allocated
+ * blocks of pending signals.
+ */
+
+static sigpendq_t *g_sigpendingirqsignalalloc;
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+static sigq_t *sig_allocateblock(sq_queue_t *siglist, uint16_t nsigs,
+ uint8_t sigtype);
+static sigpendq_t *sig_allocatependingsignalblock(sq_queue_t *siglist,
+ uint16_t nsigs, uint8_t sigtype);
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_allocateblock
+ *
+ * Description:
+ * Allocate a block of pending signal actions and place them
+ * on the free list.
+ *
+ ************************************************************************/
+
+static sigq_t *sig_allocateblock(sq_queue_t *siglist, uint16_t nsigs,
+ uint8_t sigtype)
+{
+ sigq_t *sigqalloc;
+ sigq_t *sigq;
+ int i;
+
+ /* Allocate a block of pending signal actions */
+
+ sigqalloc = (sigq_t*)kmalloc((sizeof(sigq_t)) * nsigs);
+
+ sigq = sigqalloc;
+ for (i = 0; i < nsigs; i++)
+ {
+ sigq->type = sigtype;
+ sq_addlast((FAR sq_entry_t*)sigq++, siglist);
+ }
+
+ return sigqalloc;
+}
+
+/************************************************************************
+ * Name: sig_allocatependingsignalblock
+ *
+ * Description:
+ * Allocate a block of pending signal structures and place them on
+ * the free list.
+ *
+ ************************************************************************/
+
+static sigpendq_t *sig_allocatependingsignalblock(sq_queue_t *siglist,
+ uint16_t nsigs, uint8_t sigtype)
+{
+ sigpendq_t *sigpendalloc;
+ sigpendq_t *sigpend;
+ int i;
+
+ /* Allocate a block of pending signal structures */
+
+ sigpendalloc =
+ (sigpendq_t*)kmalloc((sizeof(sigpendq_t)) * nsigs);
+
+ sigpend = sigpendalloc;
+ for (i = 0; i < nsigs; i++)
+ {
+ sigpend->type = sigtype;
+ sq_addlast((FAR sq_entry_t*)sigpend++, siglist);
+ }
+
+ return sigpendalloc;
+}
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_initialize
+ *
+ * Description:
+ * Perform one-time power-up initialization
+ *
+ ************************************************************************/
+
+void sig_initialize(void)
+{
+ /* Initialize free lists */
+
+ sq_init(&g_sigfreeaction);
+ sq_init(&g_sigpendingaction);
+ sq_init(&g_sigpendingirqaction);
+ sq_init(&g_sigpendingsignal);
+ sq_init(&g_sigpendingirqsignal);
+
+ /* Add a block of signal structures to each list */
+
+ g_sigpendingactionalloc =
+ sig_allocateblock(&g_sigpendingaction,
+ NUM_PENDING_ACTIONS,
+ SIG_ALLOC_FIXED);
+
+ g_sigpendingirqactionalloc =
+ sig_allocateblock(&g_sigpendingirqaction,
+ NUM_PENDING_INT_ACTIONS,
+ SIG_ALLOC_IRQ);
+
+ sig_allocateactionblock();
+
+ g_sigpendingsignalalloc =
+ sig_allocatependingsignalblock(&g_sigpendingsignal,
+ NUM_SIGNALS_PENDING,
+ SIG_ALLOC_FIXED);
+
+ g_sigpendingirqsignalalloc =
+ sig_allocatependingsignalblock(&g_sigpendingirqsignal,
+ NUM_INT_SIGNALS_PENDING,
+ SIG_ALLOC_IRQ);
+}
+
+/************************************************************************
+ * Name: sig_allocateactionblock
+ *
+ * Description:
+ * Allocate a block of signal actions and place them
+ * on the free list.
+ *
+ ************************************************************************/
+
+void sig_allocateactionblock(void)
+{
+ sigactq_t *sigact;
+ int i;
+
+ /* Allocate a block of signal actions */
+
+ g_sigactionalloc =
+ (sigactq_t*)kmalloc((sizeof(sigactq_t)) * NUM_SIGNAL_ACTIONS);
+
+ sigact = g_sigactionalloc;
+ for (i = 0; i < NUM_SIGNAL_ACTIONS; i++)
+ {
+ sq_addlast((FAR sq_entry_t*)sigact++, &g_sigfreeaction);
+ }
+}
diff --git a/nuttx/sched/sig_internal.h b/nuttx/sched/sig_internal.h
new file mode 100644
index 000000000..6c0641742
--- /dev/null
+++ b/nuttx/sched/sig_internal.h
@@ -0,0 +1,190 @@
+/****************************************************************************
+ * sched/sig_internal.h
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_SIG_INTERNAL_H
+#define __SCHED_SIG_INTERNAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/compiler.h>
+
+#include <stdint.h>
+#include <queue.h>
+#include <sched.h>
+
+#include <nuttx/kmalloc.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* The following definition determines the number of signal structures to
+ * allocate in a block
+ */
+
+#define NUM_SIGNAL_ACTIONS 16
+#define NUM_PENDING_ACTIONS 16
+#define NUM_PENDING_INT_ACTIONS 8
+#define NUM_SIGNALS_PENDING 16
+#define NUM_INT_SIGNALS_PENDING 8
+
+/****************************************************************************
+ * Public Type Definitions
+ ****************************************************************************/
+
+enum sigalloc_e
+{
+ SIG_ALLOC_FIXED = 0, /* pre-allocated; never freed */
+ SIG_ALLOC_DYN, /* dynamically allocated; free when unused */
+ SIG_ALLOC_IRQ /* Preallocated, reserved for interrupt handling */
+};
+typedef enum sigalloc_e sigalloc_t;
+
+/* The following defines the sigaction queue entry */
+
+struct sigactq
+{
+ FAR struct sigactq *flink; /* Forward link */
+ struct sigaction act; /* Sigaction data */
+ uint8_t signo; /* Signal associated with action */
+};
+typedef struct sigactq sigactq_t;
+
+/* The following defines the queue structure within each TCB to hold pending
+ * signals received by the task. These are signals that cannot be processed
+ * because: (1) the task is not waiting for them, or (2) the task has no
+ * action associated with the signal.
+ */
+
+struct sigpendq
+{
+ FAR struct sigpendq *flink; /* Forward link */
+ siginfo_t info; /* Signal information */
+ uint8_t type; /* (Used to manage allocations) */
+};
+typedef struct sigpendq sigpendq_t;
+
+/* The following defines the queue structure within each TCB to hold queued
+ * signal actions that need action by the task
+ */
+
+struct sigq_s
+{
+ FAR struct sigq_s *flink; /* Forward link */
+ union
+ {
+ void (*sighandler)(int signo, siginfo_t *info, void *context);
+ } action; /* Signal action */
+ sigset_t mask; /* Additional signals to mask while the
+ * the signal-catching function executes */
+ siginfo_t info; /* Signal information */
+ uint8_t type; /* (Used to manage allocations) */
+};
+typedef struct sigq_s sigq_t;
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/* The g_sigfreeaction data structure is a list of available signal action
+ * structures.
+ */
+
+extern sq_queue_t g_sigfreeaction;
+
+/* The g_sigpendingaction data structure is a list of available pending
+ * signal action structures.
+ */
+
+extern sq_queue_t g_sigpendingaction;
+
+/* The g_sigpendingirqaction is a list of available pending signal actions
+ * that are reserved for use by interrupt handlers.
+ */
+
+extern sq_queue_t g_sigpendingirqaction;
+
+/* The g_sigpendingsignal data structure is a list of available pending
+ * signal structures.
+ */
+
+extern sq_queue_t g_sigpendingsignal;
+
+/* The g_sigpendingirqsignal data structure is a list of available pending
+ * signal structures that are reserved for use by interrupt handlers.
+ */
+
+extern sq_queue_t g_sigpendingirqsignal;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/* Internal signal-related interfaces ***************************************/
+
+/* sig_intialize.c */
+
+void weak_function sig_initialize(void);
+void sig_allocateactionblock(void);
+
+/* sig_action.c */
+
+void sig_releaseaction(FAR sigactq_t *sigact);
+
+/* sig_pending.c */
+
+sigset_t sig_pendingset(FAR _TCB *stcb);
+
+/* In files of the same name */
+
+FAR sigq_t *sig_allocatependingsigaction(void);
+void sig_cleanup(FAR _TCB *stcb);
+void sig_deliver(FAR _TCB *stcb);
+FAR sigactq_t *sig_findaction(FAR _TCB *stcb, int signo);
+int sig_lowest(FAR sigset_t *set);
+#ifdef CONFIG_CAN_PASS_STRUCTS
+int sig_mqnotempty(int tid, int signo, union sigval value);
+#else
+int sig_mqnotempty(int tid, int signo, FAR void *sival_ptr);
+#endif
+int sig_received(FAR _TCB *stcb, FAR siginfo_t *info);
+void sig_releasependingsigaction(FAR sigq_t *sigq);
+void sig_releasependingsignal(FAR sigpendq_t *sigpend);
+FAR sigpendq_t *sig_removependingsignal(FAR _TCB *stcb, int signo);
+void sig_unmaskpendingsignal(void);
+
+#endif /* __SCHED_SIG_INTERNAL_H */
diff --git a/nuttx/sched/sig_kill.c b/nuttx/sched/sig_kill.c
new file mode 100644
index 000000000..17921015f
--- /dev/null
+++ b/nuttx/sched/sig_kill.c
@@ -0,0 +1,135 @@
+/************************************************************************
+ * sched/sig_kill.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/************************************************************************
+ * Global Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: kill
+ *
+ * Description:
+ * The kill() system call can be used to send any signal to any task.
+ *
+ * Limitation: Sending of signals to 'process groups' is not
+ * supported in NuttX
+ *
+ * Parameters:
+ * pid - The id of the task to receive the signal. The POSIX kill
+ * specification encodes process group information as zero and
+ * negative pid values. Only positive, non-zero values of pid are
+ * supported by this implementation.
+ * signo - The signal number to send. If signo is zero, no signal is
+ * sent, but all error checking is performed.
+ *
+ * Returned Value:
+ * On success (at least one signal was sent), zero is returned. On
+ * error, -1 is returned, and errno is set appropriately:
+ *
+ * EINVAL An invalid signal was specified.
+ * EPERM The process does not have permission to send the
+ * signal to any of the target processes.
+ * ESRCH The pid or process group does not exist.
+ * ENOSYS Do not support sending signals to process groups.
+ *
+ * Assumptions:
+ *
+ ************************************************************************/
+
+int kill(pid_t pid, int signo)
+{
+ FAR _TCB *stcb;
+ siginfo_t info;
+ int ret = ERROR;
+
+ /* We do not support sending signals to process groups */
+
+ if (pid <= 0)
+ {
+ errno = ENOSYS;
+ return ERROR;
+ }
+
+ /* Make sure that the signal is valid */
+
+ if (!GOOD_SIGNO(signo))
+ {
+ errno = EINVAL;
+ return ERROR;
+ }
+
+ /* Keep things stationary through the following */
+
+ sched_lock();
+
+ /* Get the TCB of the receiving task */
+
+ stcb = sched_gettcb(pid);
+ sdbg("TCB=0x%08x signo=%d\n", stcb, signo);
+ if (!stcb)
+ {
+ errno = ESRCH;
+ sched_unlock();
+ return ERROR;
+ }
+
+ /* Create the siginfo structure */
+
+ info.si_signo = signo;
+ info.si_code = SI_USER;
+ info.si_value.sival_ptr = NULL;
+
+ /* Send the signal */
+
+ ret = sig_received(stcb, &info);
+ sched_unlock();
+ return ret;
+}
+
+
diff --git a/nuttx/sched/sig_lowest.c b/nuttx/sched/sig_lowest.c
new file mode 100644
index 000000000..f5654eb47
--- /dev/null
+++ b/nuttx/sched/sig_lowest.c
@@ -0,0 +1,91 @@
+/************************************************************************
+ * sched/sig_lowest.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <signal.h>
+
+#include "sig_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_lowest
+ *
+ * Description:
+ * Return the lowest signal number that is a member of a set of signals.
+ *
+ ************************************************************************/
+
+int sig_lowest(sigset_t *set)
+{
+ int signo;
+
+ for (signo = MIN_SIGNO; signo <= MAX_SIGNO; signo++)
+ {
+ if (sigismember(set, signo))
+ {
+ return signo;
+ }
+ }
+
+ return ERROR;
+}
diff --git a/nuttx/sched/sig_mqnotempty.c b/nuttx/sched/sig_mqnotempty.c
new file mode 100644
index 000000000..9a1fd7243
--- /dev/null
+++ b/nuttx/sched/sig_mqnotempty.c
@@ -0,0 +1,128 @@
+/****************************************************************************
+ * sched/sig_mqnotempty.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <signal.h>
+#include <sched.h>
+#include <debug.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functionss
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sig_mqnotempty
+ *
+ * Description:
+ * This function is equivalent to sigqueue(), but supports the messaging
+ * system's requirement to signal a task when a message queue becomes
+ * non-empty. It is identical to sigqueue(), except that it sets the
+ * si_code field in the siginfo structure to SI_MESGQ rather than SI_QUEUE.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+int sig_mqnotempty (int pid, int signo, union sigval value)
+#else
+int sig_mqnotempty (int pid, int signo, void *sival_ptr)
+#endif
+{
+ FAR _TCB *stcb;
+ siginfo_t info;
+ int ret = ERROR;
+
+ sched_lock();
+
+ /* Get the TCB of the receiving task */
+
+ stcb = sched_gettcb(pid);
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ sdbg("TCB=%p signo=%d value=%d\n", stcb, signo, value.sival_int);
+#else
+ sdbg("TCB=%p signo=%d sival_ptr=%p\n", stcb, signo, sival_ptr);
+#endif
+
+ /* Create the siginfo structure */
+
+ info.si_signo = signo;
+ info.si_code = SI_MESGQ;
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ info.si_value = value;
+#else
+ info.si_value.sival_ptr = sival_ptr;
+#endif
+
+ /* Verify that we can perform the signalling operation */
+
+ if ((stcb) && (GOOD_SIGNO(signo)))
+ {
+ /* Process the receipt of the signal */
+
+ ret = sig_received(stcb, &info);
+ }
+
+ sched_unlock();
+ return ret;
+}
diff --git a/nuttx/sched/sig_pending.c b/nuttx/sched/sig_pending.c
new file mode 100644
index 000000000..eaabbff6b
--- /dev/null
+++ b/nuttx/sched/sig_pending.c
@@ -0,0 +1,130 @@
+/****************************************************************************
+ * sched/sig_pending.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <signal.h>
+#include <sched.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sigpending
+ *
+ * Description:
+ * This function stores the returns the set of signals that are blocked
+ * for delivery and that are pending for the calling process in the space
+ * pointed to by set.
+ *
+ * Parameters:
+ * set - The location to return the pending signal set.
+ *
+ * Return Value:
+ * 0 (OK) or -1 (ERROR)
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sigpending(FAR sigset_t *set)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ int ret = ERROR;
+
+ if (set)
+ {
+ *set = sig_pendingset(rtcb);
+ ret = OK;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: sig_pendingset
+ *
+ * Description:
+ * Convert the list of pending signals into a signal set
+ *
+ ****************************************************************************/
+
+sigset_t sig_pendingset(FAR _TCB *stcb)
+{
+ sigset_t sigpendset;
+ FAR sigpendq_t *sigpend;
+ irqstate_t saved_state;
+
+ sigpendset = NULL_SIGNAL_SET;
+
+ saved_state = irqsave();
+ for (sigpend = (FAR sigpendq_t*)stcb->sigpendingq.head;
+ (sigpend); sigpend = sigpend->flink)
+ {
+ sigaddset(&sigpendset, sigpend->info.si_signo);
+ }
+
+ irqrestore(saved_state);
+
+ return sigpendset;
+}
diff --git a/nuttx/sched/sig_procmask.c b/nuttx/sched/sig_procmask.c
new file mode 100644
index 000000000..c67159589
--- /dev/null
+++ b/nuttx/sched/sig_procmask.c
@@ -0,0 +1,180 @@
+/****************************************************************************
+ * sched/sig_procmask.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <signal.h>
+#include <time.h>
+#include <wdog.h>
+#include <assert.h>
+#include <debug.h>
+#include <sched.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sigprocmask
+ *
+ * Description:
+ * This function allows the calling process to examine and/or change its
+ * signal mask. If the 'set' is not NULL, then it points to a set of
+ * signals to be used to change the currently blocked set. The value of
+ * 'how' indicates the manner in which the set is changed.
+ *
+ * If there any pending unblocked signals after the call to sigprocmask(),
+ * those signals will be delivered before sigprocmask() returns.
+ *
+ * If sigprocmask() fails, the signal mask of the process is not changed
+ * by this function call.
+ *
+ * Parameters:
+ * how - How the signal mast will be changed:
+ * SIG_BLOCK - The resulting set is the union of the current set
+ * and the signal set pointed to by 'set'.
+ * SIG_UNBLOCK - The resulting set is the intersection of the current
+ * set and the complement of the signal set pointed to
+ * by 'set'.
+ * SIG_SETMASK - The resulting set is the signal set pointed to by
+ * 'set'.
+ * set - Location of the new signal mask
+ * oset - Location to store the old signal mask
+ *
+ * Return Value:
+ * 0 (OK), or -1 (ERROR) if how is invalid.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sigprocmask(int how, FAR const sigset_t *set, FAR sigset_t *oset)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ sigset_t oldsigprocmask;
+ irqstate_t saved_state;
+ int ret = OK;
+
+ sched_lock();
+
+ /* Return the old signal mask if requested */
+
+ oldsigprocmask = rtcb->sigprocmask;
+ if (oset)
+ {
+ *oset = oldsigprocmask;
+ }
+
+ /* Modify the current signal mask if so requested */
+
+ if (set)
+ {
+ /* Some of these operations are non-atomic. We need to protect
+ * ourselves from attempts to process signals from interrupts
+ */
+
+ saved_state = irqsave();
+
+ /* Okay, determine what we are supposed to do */
+
+ switch (how)
+ {
+ /* The resulting set is the union of the current set and the
+ * signal set pointed to by set.
+ */
+
+ case SIG_BLOCK:
+ rtcb->sigprocmask |= *set;
+ break;
+
+ /* The resulting set is the intersection of the current set and
+ * the complement of the signal set pointed to by _set.
+ */
+
+ case SIG_UNBLOCK:
+ rtcb->sigprocmask &= ~(*set);
+ break;
+
+ /* The resulting set is the signal set pointed to by set. */
+
+ case SIG_SETMASK:
+ rtcb->sigprocmask = *set;
+ break;
+
+ default:
+ ret = ERROR;
+ break;
+ }
+
+ irqrestore(saved_state);
+
+ /* Now, process any pending signals that were just unmasked */
+
+ sig_unmaskpendingsignal();
+ }
+
+ sched_unlock();
+ return ret;
+}
diff --git a/nuttx/sched/sig_queue.c b/nuttx/sched/sig_queue.c
new file mode 100644
index 000000000..dee1c798a
--- /dev/null
+++ b/nuttx/sched/sig_queue.c
@@ -0,0 +1,159 @@
+/****************************************************************************
+ * sched/sig_queue.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <signal.h>
+#include <debug.h>
+#include <sched.h>
+#include <errno.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sigqueue
+ *
+ * Description:
+ * This function sends the signal specified by signo with the signal
+ * parameter value to the process specified by pid.
+ *
+ * If the receiving process has the signal blocked via the sigprocmask,
+ * the signal will pend until it is unmasked. Only one pending signal (per
+ * signo) is retained. This is consistent with POSIX which states, "If
+ * a subsequent occurrence of a pending signal is generated, it is
+ * implementation defined as to whether the signal is delivered more than
+ * once."
+ *
+ * Parameters:
+ * pid - Process ID of task to receive signal
+ * signo - Signal number
+ * value - Value to pass to task with signal
+ *
+ * Return Value:
+ * On success (at least one signal was sent), zero is returned. On
+ * error, -1 is returned, and errno is set appropriately:
+ *
+ * EGAIN The limit of signals which may be queued has been reached.
+ * EINVAL sig was invalid.
+ * EPERM The process does not have permission to send the
+ * signal to the receiving process.
+ * ESRCH No process has a PID matching pid.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+int sigqueue (int pid, int signo, union sigval value)
+#else
+int sigqueue(int pid, int signo, void *sival_ptr)
+#endif
+{
+ FAR _TCB *stcb;
+ siginfo_t info;
+ int ret = ERROR;
+
+ /* Sanity checks */
+
+ if (!GOOD_SIGNO(signo))
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ sched_lock();
+
+ /* Get the TCB of the receiving task */
+
+ stcb = sched_gettcb(pid);
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ sdbg("TCB=0x%08x signo=%d value=%d\n", stcb, signo, value.sival_int);
+#else
+ sdbg("TCB=0x%08x signo=%d value=%p\n", stcb, signo, sival_ptr);
+#endif
+ if (pid == 0 || !stcb)
+ {
+ set_errno(ESRCH);
+ sched_unlock();
+ return ERROR;
+ }
+
+ /* Create the siginfo structure */
+
+ info.si_signo = signo;
+ info.si_code = SI_QUEUE;
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ info.si_value = value;
+#else
+ info.si_value.sival_ptr = sival_ptr;
+#endif
+
+ /* Send the signal */
+
+ ret = sig_received(stcb, &info);
+ sched_unlock();
+ return ret;
+}
+
diff --git a/nuttx/sched/sig_received.c b/nuttx/sched/sig_received.c
new file mode 100644
index 000000000..cf4d00165
--- /dev/null
+++ b/nuttx/sched/sig_received.c
@@ -0,0 +1,404 @@
+/************************************************************************
+ * sched/sig_received.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sem_internal.h"
+#include "sig_internal.h"
+#include "mq_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_queueaction
+ *
+ * Description:
+ * Queue a signal action for delivery to a task.
+ *
+ ************************************************************************/
+
+static int sig_queueaction(FAR _TCB *stcb, siginfo_t *info)
+{
+ FAR sigactq_t *sigact;
+ FAR sigq_t *sigq;
+ irqstate_t saved_state;
+ int ret = OK;
+
+ sched_lock();
+
+ /* Find the sigaction associated with this signal */
+
+ sigact = sig_findaction(stcb, info->si_signo);
+
+ /* Check if a valid signal handler is available and if the signal is
+ * unblocked. NOTE: There is no default action.
+ */
+
+ if ((sigact) && (sigact->act.sa_u._sa_sigaction))
+ {
+ /* Allocate a new element for the signal queue. NOTE: sig_allocatependingsigaction
+ * will force a system crash if it is unable to allocate memory for the
+ * signal data */
+
+ sigq = sig_allocatependingsigaction();
+ if (!sigq) ret = ERROR;
+ else
+ {
+ /* Populate the new signal queue element */
+
+ sigq->action.sighandler = sigact->act.sa_u._sa_sigaction;
+ sigq->mask = sigact->act.sa_mask;
+ memcpy(&sigq->info, info, sizeof(siginfo_t));
+
+ /* Put it at the end of the pending signals list */
+
+ saved_state = irqsave();
+ sq_addlast((FAR sq_entry_t*)sigq, &(stcb->sigpendactionq));
+ irqrestore(saved_state);
+ }
+ }
+
+ sched_unlock();
+ return ret;
+}
+
+/************************************************************************
+ * Name: sig_findpendingsignal
+ *
+ * Description:
+ * Find a specified element in the pending signal list
+ *
+ ************************************************************************/
+
+static FAR sigpendq_t *sig_findpendingsignal(FAR _TCB *stcb, int signo)
+{
+ FAR sigpendq_t *sigpend = NULL;
+ irqstate_t saved_state;
+
+ /* Verify the caller's sanity */
+
+ if (stcb)
+ {
+ /* Pending sigals can be added from interrupt level. */
+
+ saved_state = irqsave();
+
+ /* Seach the list for a sigpendion on this signal */
+
+ for(sigpend = (FAR sigpendq_t*)stcb->sigpendingq.head;
+ (sigpend && sigpend->info.si_signo != signo);
+ sigpend = sigpend->flink);
+ irqrestore(saved_state);
+ }
+
+ return sigpend;
+}
+
+/************************************************************************
+ * Name: sig_allocatependingsignal
+ *
+ * Description:
+ * Allocate a pending signal list entry
+ *
+ ************************************************************************/
+
+static FAR sigpendq_t *sig_allocatependingsignal(void)
+{
+ FAR sigpendq_t *sigpend;
+ irqstate_t saved_state;
+
+ /* Check if we were called from an interrupt handler. */
+
+ if (up_interrupt_context())
+ {
+ /* Try to get the pending signal structure from the free list */
+
+ sigpend = (FAR sigpendq_t*)sq_remfirst(&g_sigpendingsignal);
+ if (!sigpend)
+ {
+ /* If no pending signal structure is available in the free list,
+ * then try the special list of structures reserved for
+ * interrupt handlers
+ */
+
+ sigpend = (FAR sigpendq_t*)sq_remfirst(&g_sigpendingirqsignal);
+ }
+ }
+
+ /* If we were not called from an interrupt handler, then we are
+ * free to allocate pending action structures if necessary. */
+
+ else
+ {
+ /* Try to get the pending signal structure from the free list */
+
+ saved_state = irqsave();
+ sigpend = (FAR sigpendq_t*)sq_remfirst(&g_sigpendingsignal);
+ irqrestore(saved_state);
+
+ /* Check if we got one. */
+
+ if (!sigpend)
+ {
+ /* No... Allocate the pending signal */
+
+ if (!sigpend)
+ {
+ sigpend = (FAR sigpendq_t *)kmalloc((sizeof (sigpendq_t)));
+ }
+
+ /* Check if we got an allocated message */
+
+ if (sigpend)
+ {
+ sigpend->type = SIG_ALLOC_DYN;
+ }
+ }
+ }
+
+ return sigpend;
+}
+
+/************************************************************************
+ * Name: sig_addpendingsignal
+ *
+ * Description:
+ * Add the specified signal to the signal pending list. NOTE: This
+ * function will queue only one entry for each pending signal. This
+ * was done intentionally so that a run-away sender cannot consume
+ * all of memory.
+ *
+ ************************************************************************/
+
+static FAR sigpendq_t *sig_addpendingsignal(FAR _TCB *stcb,
+ siginfo_t *info)
+{
+ FAR sigpendq_t *sigpend;
+ irqstate_t saved_state;
+
+ /* Check if the signal is already pending */
+
+ sigpend = sig_findpendingsignal(stcb, info->si_signo);
+ if (sigpend)
+ {
+ /* The signal is already pending... retain only one copy */
+
+ memcpy(&sigpend->info, info, sizeof(siginfo_t));
+ }
+
+ /* No... There is nothing pending for this signo */
+
+ else
+ {
+ /* Allocate a new pending signal entry */
+
+ sigpend = sig_allocatependingsignal();
+ if (sigpend)
+ {
+ /* Put the signal information into the allocated structure */
+
+ memcpy(&sigpend->info, info, sizeof(siginfo_t));
+
+ /* Add the structure to the pending signal list */
+
+ saved_state = irqsave();
+ sq_addlast((FAR sq_entry_t*)sigpend, &stcb->sigpendingq);
+ irqrestore(saved_state);
+ }
+ }
+
+ return sigpend;
+}
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_received
+ *
+ * Description:
+ * All signals received the task (whatever the source) go through this
+ * function to be processed. This function is responsible for:
+ *
+ * - Determining if the signal is blocked.
+ * - Queuing and dispatching signal actions
+ * - Unblocking tasks that are waiting for signals
+ * - Queuing pending signals.
+ *
+ ************************************************************************/
+
+int sig_received(FAR _TCB *stcb, siginfo_t *info)
+{
+ irqstate_t saved_state;
+ int ret = ERROR;
+
+ sdbg("TCB=0x%08x signo=%d code=%d value=%d mask=%08x\n",
+ stcb, info->si_signo, info->si_code,
+ info->si_value.sival_int, stcb->sigprocmask);
+
+ if (stcb && info)
+ {
+ ret = OK;
+
+ /****************** MASKED SIGNAL HANDLING ******************/
+
+ /* Check if the signal is masked -- if it is, it will be added to the
+ * list of pending signals.
+ */
+
+ if (sigismember(&stcb->sigprocmask, info->si_signo))
+ {
+ /* Check if the task is waiting for this pending signal. If so,
+ * then unblock it. This must be performed in a critical section
+ * because signals can be queued from the interrupt level.
+ */
+
+ saved_state = irqsave();
+ if (stcb->task_state == TSTATE_WAIT_SIG &&
+ sigismember(&stcb->sigwaitmask, info->si_signo))
+ {
+ memcpy(&stcb->sigunbinfo, info, sizeof(siginfo_t));
+ stcb->sigwaitmask = NULL_SIGNAL_SET;
+ up_unblock_task(stcb);
+ irqrestore(saved_state);
+ }
+
+ /* Its not one we are waiting for... Add it to the list of pending
+ * signals.
+ */
+
+ else
+ {
+ irqrestore(saved_state);
+ if (!sig_addpendingsignal(stcb, info))
+ {
+ PANIC(OSERR_FAILEDTOADDSIGNAL);
+ }
+ }
+ }
+
+ /****************** UNMASKED SIGNAL HANDLING ******************/
+
+ else
+ {
+ /* Queue any sigaction's requested by this task. */
+
+ ret = sig_queueaction(stcb, info);
+
+ /* Then schedule execution of the signal handling action on
+ * the recipients thread.
+ */
+
+ up_schedule_sigaction(stcb, sig_deliver);
+
+ /* Check if the task is waiting for an unmasked signal. If so,
+ * then unblock it. This must be performed in a critical section
+ * because signals can be queued from the interrupt level.
+ */
+
+ saved_state = irqsave();
+ if (stcb->task_state == TSTATE_WAIT_SIG)
+ {
+ memcpy(&stcb->sigunbinfo, info, sizeof(siginfo_t));
+ stcb->sigwaitmask = NULL_SIGNAL_SET;
+ up_unblock_task(stcb);
+ }
+ irqrestore(saved_state);
+
+ /* If the task neither was waiting for the signal nor had a signal
+ * handler attached to the signal, then the default action is
+ * simply to ignore the signal
+ */
+
+ /****************** OTHER SIGNAL HANDLING ******************/
+
+ /* If the task is blocked waiting for a semaphore, then that
+ * task must be unblocked when a signal is received.
+ */
+
+ if (stcb->task_state == TSTATE_WAIT_SEM)
+ {
+ sem_waitirq(stcb, EINTR);
+ }
+
+ /* If the task is blocked waiting on a message queue, then that
+ * task must be unblocked when a signal is received.
+ */
+
+#ifndef CONFIG_DISABLE_MQUEUE
+ if (stcb->task_state == TSTATE_WAIT_MQNOTEMPTY ||
+ stcb->task_state == TSTATE_WAIT_MQNOTFULL)
+ {
+ mq_waitirq(stcb, EINTR);
+ }
+#endif
+ }
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/sig_releasependingsigaction.c b/nuttx/sched/sig_releasependingsigaction.c
new file mode 100644
index 000000000..69252f284
--- /dev/null
+++ b/nuttx/sched/sig_releasependingsigaction.c
@@ -0,0 +1,120 @@
+/************************************************************************
+ * sched/sig_releasependingsigaction.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_releasependingsigaction
+ *
+ * Description:
+ * Deallocate a pending signal action Q entry
+ *
+ ************************************************************************/
+
+void sig_releasependingsigaction(FAR sigq_t *sigq)
+{
+ irqstate_t saved_state;
+
+ /* If this is a generally available pre-allocated structyre,
+ * then just put it back in the free list.
+ */
+
+ if (sigq->type == SIG_ALLOC_FIXED)
+ {
+ /* Make sure we avoid concurrent access to the free
+ * list from interrupt handlers. */
+
+ saved_state = irqsave();
+ sq_addlast((FAR sq_entry_t*)sigq, &g_sigpendingaction);
+ irqrestore(saved_state);
+ }
+
+ /* If this is a message pre-allocated for interrupts,
+ * then put it back in the correct free list.
+ */
+
+ else if (sigq->type == SIG_ALLOC_IRQ)
+ {
+ /* Make sure we avoid concurrent access to the free
+ * list from interrupt handlers. */
+
+ saved_state = irqsave();
+ sq_addlast((FAR sq_entry_t*)sigq, &g_sigpendingirqaction);
+ irqrestore(saved_state);
+ }
+
+ /* Otherwise, deallocate it. Note: interrupt handlers
+ * will never deallocate signals because they will not
+ * receive them.
+ */
+
+ else if (sigq->type == SIG_ALLOC_DYN)
+ {
+ sched_free(sigq);
+ }
+}
diff --git a/nuttx/sched/sig_releasependingsignal.c b/nuttx/sched/sig_releasependingsignal.c
new file mode 100644
index 000000000..5b847bc64
--- /dev/null
+++ b/nuttx/sched/sig_releasependingsignal.c
@@ -0,0 +1,131 @@
+/************************************************************************
+ * sched/sig_releasependingsignal.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <signal.h>
+#include <time.h>
+#include <wdog.h>
+#include <assert.h>
+#include <debug.h>
+#include <sched.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_releasependingsignal
+ *
+ * Description:
+ * Deallocate a pending signal list entry
+ *
+ ************************************************************************/
+
+void sig_releasependingsignal(FAR sigpendq_t *sigpend)
+{
+ irqstate_t saved_state;
+
+ /* If this is a generally available pre-allocated structyre,
+ * then just put it back in the free list.
+ */
+
+ if (sigpend->type == SIG_ALLOC_FIXED)
+ {
+ /* Make sure we avoid concurrent access to the free
+ * list from interrupt handlers.
+ */
+
+ saved_state = irqsave();
+ sq_addlast((FAR sq_entry_t*)sigpend, &g_sigpendingsignal);
+ irqrestore(saved_state);
+ }
+
+ /* If this is a message pre-allocated for interrupts,
+ * then put it back in the correct free list.
+ */
+
+ else if (sigpend->type == SIG_ALLOC_IRQ)
+ {
+ /* Make sure we avoid concurrent access to the free
+ * list from interrupt handlers.
+ */
+
+ saved_state = irqsave();
+ sq_addlast((FAR sq_entry_t*)sigpend, &g_sigpendingirqsignal);
+ irqrestore(saved_state);
+ }
+
+ /* Otherwise, deallocate it. Note: interrupt handlers
+ * will never deallocate signals because they will not
+ * receive them.
+ */
+
+ else if (sigpend->type == SIG_ALLOC_DYN)
+ {
+ sched_free(sigpend);
+ }
+}
diff --git a/nuttx/sched/sig_removependingsignal.c b/nuttx/sched/sig_removependingsignal.c
new file mode 100644
index 000000000..c82bf983b
--- /dev/null
+++ b/nuttx/sched/sig_removependingsignal.c
@@ -0,0 +1,115 @@
+/************************************************************************
+ * sched/sig_removependingsignal.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <signal.h>
+#include <time.h>
+#include <wdog.h>
+#include <assert.h>
+#include <debug.h>
+#include <sched.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_removependingsignal
+ *
+ * Description:
+ * Remove the specified signal from the signal pending list
+ *
+ ************************************************************************/
+
+FAR sigpendq_t *sig_removependingsignal(FAR _TCB *stcb, int signo)
+{
+ FAR sigpendq_t *currsig;
+ FAR sigpendq_t *prevsig;
+ irqstate_t saved_state;
+
+ saved_state = irqsave();
+
+ for (prevsig = NULL, currsig = (FAR sigpendq_t*)stcb->sigpendingq.head;
+ (currsig && currsig->info.si_signo != signo);
+ prevsig = currsig, currsig = currsig->flink);
+
+ if (currsig)
+ {
+ if (prevsig)
+ {
+ sq_remafter((FAR sq_entry_t*)prevsig, &stcb->sigpendingq);
+ }
+ else
+ {
+ sq_remfirst(&stcb->sigpendingq);
+ }
+ }
+
+ irqrestore(saved_state);
+
+ return currsig;
+}
diff --git a/nuttx/sched/sig_suspend.c b/nuttx/sched/sig_suspend.c
new file mode 100644
index 000000000..09f47dee9
--- /dev/null
+++ b/nuttx/sched/sig_suspend.c
@@ -0,0 +1,180 @@
+/****************************************************************************
+ * sched/sig_suspend.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <signal.h>
+#include <assert.h>
+#include <debug.h>
+#include <sched.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sigsuspend
+ *
+ * Description:
+ *
+ * The sigsuspend() function replaces the signal mask of the task with the
+ * set of signals pointed to by the argument 'set' and then suspends the
+ * process until delivery of a signal to the task.
+ *
+ * If the effect of the set argument is to unblock a pending signal, then
+ * no wait is performed.
+ *
+ * The original signal mask is restored when this function returns.
+ *
+ * Waiting for an empty signal set stops a task without freeing any
+ * resources.
+ *
+ * Parameters:
+ * set - signal mask to use while suspended.
+ *
+ * Return Value:
+ * -1 (ERROR) always
+ *
+ * Assumptions:
+ *
+ * POSIX Compatibility:
+ * int sigsuspend(const sigset_t *set);
+ *
+ * POSIX states that sigsuspend() "suspends the process until delivery of
+ * a signal whose action is either to execute a signal-catching function
+ * or to terminate the process." Only the deliver of a signal is required
+ * in the present implementation (even if the signal is ignored).
+ *
+ ****************************************************************************/
+
+int sigsuspend(FAR const sigset_t *set)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ sigset_t intersection;
+ sigset_t saved_sigprocmask;
+ FAR sigpendq_t *sigpend;
+ irqstate_t saved_state;
+ int unblocksigno;
+
+ /* Several operations must be performed below: We must determine if any
+ * 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
+ * can only be eliminated by disabling interrupts!
+ */
+
+ sched_lock(); /* Not necessary */
+ saved_state = irqsave();
+
+ /* Check if there is a pending signal corresponding to one of the
+ * signals that will be unblocked by the new sigprocmask.
+ */
+
+ intersection = ~(*set) & sig_pendingset(rtcb);
+ if (intersection != NULL_SIGNAL_SET)
+ {
+ /* One or more of the signals in intersections is sufficient to cause
+ * us to not wait. Pick the lowest numbered signal and mark it not
+ * pending.
+ */
+
+ unblocksigno = sig_lowest(&intersection);
+ sigpend = sig_removependingsignal(rtcb, unblocksigno);
+ if (!sigpend)
+ {
+ PANIC(OSERR_FAILEDTOREMOVESIGNAL);
+ }
+
+ sig_releasependingsignal(sigpend);
+ irqrestore(saved_state);
+ }
+ else
+ {
+ /* Its time to wait. Save a copy of the old sigprocmask and install
+ * the new (temporary) sigprocmask
+ */
+
+ saved_sigprocmask = rtcb->sigprocmask;
+ rtcb->sigprocmask = *set;
+ rtcb->sigwaitmask = NULL_SIGNAL_SET;
+
+ /* And wait until one of the unblocked signals is posted */
+
+ up_block_task(rtcb, TSTATE_WAIT_SIG);
+
+ /* We are running again, restore the original sigprocmask */
+
+ rtcb->sigprocmask = saved_sigprocmask;
+ irqrestore(saved_state);
+
+ /* Now, handle the (rare?) case where (a) a blocked signal was received
+ * while the task was suspended but (b) restoring the original
+ * sigprocmask will unblock the signal.
+ */
+
+ sig_unmaskpendingsignal();
+ }
+
+ sched_unlock();
+ return ERROR;
+}
diff --git a/nuttx/sched/sig_timedwait.c b/nuttx/sched/sig_timedwait.c
new file mode 100644
index 000000000..1b8dfd162
--- /dev/null
+++ b/nuttx/sched/sig_timedwait.c
@@ -0,0 +1,334 @@
+/****************************************************************************
+ * sched/sig_timedwait.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <signal.h>
+#include <time.h>
+#include <wdog.h>
+#include <assert.h>
+#include <debug.h>
+#include <sched.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+#include "clock_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* This is a special value of si_signo that means that it was the timeout
+ * that awakened the wait... not the receipt of a signal.
+ */
+
+#define SIG_WAIT_TIMEOUT 0xff
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functionss
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sig_timeout
+ *
+ * Description:
+ * A timeout elapsed while waiting for signals to be queued.
+ *
+ ****************************************************************************/
+
+static void sig_timeout(int argc, uint32_t itcb)
+{
+ /* On many small machines, pointers are encoded and cannot be simply cast
+ * from uint32_t to _TCB*. The following union works around this
+ * (see wdogparm_t). This odd logic could be conditioned on
+ * CONFIG_CAN_CAST_POINTERS, but it is not too bad in any case.
+ */
+
+ union
+ {
+ FAR _TCB *wtcb;
+ uint32_t itcb;
+ } u;
+
+ u.itcb = itcb;
+
+ if (!u.wtcb)
+ {
+ PANIC(OSERR_TIMEOUTNOTCB);
+ }
+
+ /* There may be a race condition -- make sure the task is
+ * still waiting for a signal
+ */
+
+ if (u.wtcb->task_state == TSTATE_WAIT_SIG)
+ {
+ u.wtcb->sigunbinfo.si_signo = SIG_WAIT_TIMEOUT;
+ u.wtcb->sigunbinfo.si_code = SI_TIMER;
+ u.wtcb->sigunbinfo.si_value.sival_int = 0;
+ up_unblock_task(u.wtcb);
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sigtimedwait
+ *
+ * Description:
+ * This function selects the pending signal set specified by the argument
+ * set. If multiple signals are pending in set, it will remove and return
+ * the lowest numbered one. If no signals in set are pending at the time
+ * of the call, the calling process will be suspended until one of the
+ * signals in set becomes pending, OR until the process is interrupted by
+ * an unblocked signal, OR until the time interval specified by timeout
+ * (if any), has expired. If timeout is NULL, then the timeout interval
+ * is forever.
+ *
+ * If the info argument is non-NULL, the selected signal number is stored
+ * in the si_signo member and the cause of the signal is store in the
+ * si_code emember. The content of si_value is only meaningful if the
+ * signal was generated by sigqueue().
+ *
+ * The following values for si_code are defined in signal.h:
+ * SI_USER - Signal sent from kill, raise, or abort
+ * SI_QUEUE - Signal sent from sigqueue
+ * SI_TIMER - Signal is result of timer expiration
+ * SI_ASYNCIO - Signal is the result of asynch IO completion
+ * SI_MESGQ - Signal generated by arrival of a message on an
+ * empty message queue.
+ *
+ * Parameters:
+ * set - The pending signal set.
+ * info - The returned value
+ * timeout - The amount of time to wait
+ *
+ * Return Value:
+ * Signal number that cause the wait to be terminated, otherwise -1 (ERROR)
+ * is returned with errno set to either:
+ *
+ * EAGAIN - No signal specified by set was generated within the specified
+ * timeout period.
+ * EINTR - The wait was interrupted by an unblocked, caught signal.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info,
+ FAR const struct timespec *timeout)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ sigset_t intersection;
+ FAR sigpendq_t *sigpend;
+ WDOG_ID wdog;
+ irqstate_t saved_state;
+ int32_t waitticks;
+ int ret = ERROR;
+
+ sched_lock(); /* Not necessary */
+
+ /* Several operations must be performed below: We must determine if any
+ * 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
+ * can only be eliminated by disabling interrupts!
+ */
+
+ saved_state = irqsave();
+
+ /* Check if there is a pending signal corresponding to one of the
+ * signals in the pending signal set argument.
+ */
+
+ intersection = *set & sig_pendingset(rtcb);
+ if (intersection != NULL_SIGNAL_SET)
+ {
+ /* One or more of the signals in intersections is sufficient to cause
+ * us to not wait. Pick the lowest numbered signal and mark it not
+ * pending.
+ */
+
+ sigpend = sig_removependingsignal(rtcb, sig_lowest(&intersection));
+ if (!sigpend)
+ {
+ PANIC(OSERR_NOPENDINGSIGNAL);
+ }
+
+ /* Return the signal info to the caller if so requested */
+
+ if (info)
+ {
+ memcpy(info, &sigpend->info, sizeof(struct siginfo));
+ }
+
+ /* Then dispose of the pending signal structure properly */
+
+ sig_releasependingsignal(sigpend);
+ irqrestore(saved_state);
+
+ /* The return value is the number of the signal that awakened us */
+
+ ret = info->si_signo;
+ }
+
+ /* We will have to wait for a signal to be posted to this task. */
+
+ else
+ {
+ /* Save the set of pending signals to wait for */
+
+ rtcb->sigwaitmask = *set;
+
+ /* Check if we should wait for the timeout */
+
+ if (timeout)
+ {
+ /* Convert the timespec to milliseconds */
+
+ waitticks = MSEC2TICK(timeout->tv_sec * MSEC_PER_SEC
+ + timeout->tv_nsec / NSEC_PER_MSEC);
+
+ /* Create a watchdog */
+
+ wdog = wd_create();
+ if (wdog)
+ {
+ /* This little of nonsense is necessary for some
+ * processors where sizeof(pointer) < sizeof(uint32_t).
+ * see wdog.h.
+ */
+
+ wdparm_t wdparm;
+ wdparm.pvarg = (FAR void*)rtcb;
+
+ /* Start the watchdog */
+
+ wd_start(wdog, waitticks, (wdentry_t)sig_timeout, 1, wdparm.dwarg);
+
+ /* Now wait for either the signal or the watchdog */
+
+ up_block_task(rtcb, TSTATE_WAIT_SIG);
+
+ /* We no longer need the watchdog */
+
+ wd_delete(wdog);
+ }
+ }
+
+ /* No timeout, just wait */
+
+ else
+ {
+ /* And wait until one of the unblocked signals is posted */
+
+ up_block_task(rtcb, TSTATE_WAIT_SIG);
+ }
+
+ /* We are running again, clear the sigwaitmask */
+
+ rtcb->sigwaitmask = NULL_SIGNAL_SET;
+
+ /* When we awaken, the cause will be in the TCB. Get the signal number
+ * or timeout) that awakened us.
+ */
+
+ if (GOOD_SIGNO(rtcb->sigunbinfo.si_signo))
+ {
+ /* We were awakened by a signal... but is it one of the signals that
+ * we were waiting for?
+ */
+
+ if (sigismember(set, rtcb->sigunbinfo.si_signo))
+ {
+ /* Yes.. the return value is the number of the signal that
+ * awakened us.
+ */
+
+ ret = rtcb->sigunbinfo.si_signo;
+ }
+ else
+ {
+ /* No... then set EINTR and report an error */
+
+ set_errno(EINTR);
+ ret = ERROR;
+ }
+ }
+ else
+ {
+ /* Otherwise, we must have been awakened by the timeout. Set EGAIN
+ * and return an error.
+ */
+
+ DEBUGASSERT(rtcb->sigunbinfo.si_signo == SIG_WAIT_TIMEOUT);
+ set_errno(EAGAIN);
+ ret = ERROR;
+ }
+
+ /* Return the signal info to the caller if so requested */
+
+ if (info)
+ {
+ memcpy(info, &rtcb->sigunbinfo, sizeof(struct siginfo));
+ }
+ irqrestore(saved_state);
+ }
+
+ sched_unlock();
+ return ret;
+}
diff --git a/nuttx/sched/sig_unmaskpendingsignal.c b/nuttx/sched/sig_unmaskpendingsignal.c
new file mode 100644
index 000000000..a7bcc7a29
--- /dev/null
+++ b/nuttx/sched/sig_unmaskpendingsignal.c
@@ -0,0 +1,138 @@
+/************************************************************************
+ * sched/sig_unmaskpendingsignal.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: sig_unmaskpendingsignal
+ *
+ * Description:
+ * Based upon the current setting of the sigprocmask, this function
+ * unmasks and processes any pending signals. This function should
+ * be called whenever the sigprocmask is changed.
+ *
+ ************************************************************************/
+
+void sig_unmaskpendingsignal(void)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ sigset_t unmaskedset;
+ FAR sigpendq_t *pendingsig;
+ int signo;
+
+ /* Prohibit any context switches until we are done with this.
+ * We may still be performing signal operations from interrupt
+ * handlers, however, none of the pending signals that we
+ * are concerned with here should be effected.
+ */
+
+ sched_lock();
+
+ /* Get the set of pending signals that were just unmasked. The
+ * following operation should be safe because the sigprocmask
+ * can only be changed on this thread of execution.
+ */
+
+ unmaskedset = ~(rtcb->sigprocmask) & sig_pendingset(rtcb);
+
+ /* Loop while there are unmasked pending signals to be processed. */
+
+ while (unmaskedset != NULL_SIGNAL_SET)
+ {
+ /* Pending signals will be processed from lowest numbered signal
+ * to highest
+ */
+
+ signo = sig_lowest(&unmaskedset);
+ if (signo != ERROR)
+ {
+ /* Remove the signal from the set of unmasked signals. NOTE:
+ * this implicitly assumes that only one instance for a given
+ * signal number is pending.
+ */
+
+ sigdelset(&unmaskedset, signo);
+
+ /* Remove the pending signal from the list of pending signals */
+
+ if ((pendingsig = sig_removependingsignal(rtcb, signo)) != NULL)
+ {
+ /* If there is one, then process it like a normal signal */
+
+ sig_received(rtcb, &pendingsig->info);
+
+ /* Then remove it from the pending signal list */
+
+ sig_releasependingsignal(pendingsig);
+ }
+ }
+ }
+
+ sched_unlock();
+}
+
diff --git a/nuttx/sched/sig_waitinfo.c b/nuttx/sched/sig_waitinfo.c
new file mode 100644
index 000000000..0172ec47d
--- /dev/null
+++ b/nuttx/sched/sig_waitinfo.c
@@ -0,0 +1,89 @@
+/****************************************************************************
+ * sched/sig_waitinfo.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <signal.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sigwaitinfo
+ *
+ * Description:
+ * This function is equivalent to sigtimedwait with a NULL timeout
+ * parameter.
+ *
+ * Parameters:
+ * set - The pending signal set
+ * info - The returned value
+ *
+ * Return Value:
+ * Signal number that cause the wait to be terminated, otherwise -1 (ERROR)
+ * is returned.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int sigwaitinfo(FAR const sigset_t *set, FAR struct siginfo *info)
+{
+ return sigtimedwait(set, info, NULL);
+}
diff --git a/nuttx/sched/sleep.c b/nuttx/sched/sleep.c
new file mode 100644
index 000000000..03884a5b6
--- /dev/null
+++ b/nuttx/sched/sleep.c
@@ -0,0 +1,196 @@
+/****************************************************************************
+ * sched/sleep.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <signal.h>
+
+#include <nuttx/clock.h>
+#include <arch/irq.h>
+
+/****************************************************************************
+ * Preprocessor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sleep
+ *
+ * Description:
+ * The sleep() function will cause the calling thread to be suspended from
+ * execution until either the number of real-time seconds specified by the
+ * argument 'seconds' has elapsed or a signal is delivered to the calling
+ * thread and its action is to invoke a signal-catching function or to
+ * terminate the process. The suspension time may be longer than requested
+ * due to the scheduling of other activity by the system.
+ *
+ * If a SIGALRM signal is generated for the calling process during
+ * execution of sleep() and if the SIGALRM signal is being ignored or
+ * blocked from delivery, it is unspecified whether sleep() returns
+ * when the SIGALRM signal is scheduled. If the signal is being blocked, it
+ * is also unspecified whether it remains pending after sleep() returns or
+ * it is discarded.
+ *
+ * If a SIGALRM signal is generated for the calling process during
+ * execution of sleep(), except as a result of a prior call to alarm(),
+ * and if the SIGALRM signal is not being ignored or blocked from delivery,
+ * it is unspecified whether that signal has any effect other than causing
+ * sleep() to return.
+ *
+ * If a signal-catching function interrupts sleep() and examines or changes
+ * either the time a SIGALRM is scheduled to be generated, the action
+ * associated with the SIGALRM signal, or whether the SIGALRM signal is
+ * blocked from delivery, the results are unspecified.
+ *
+ * If a signal-catching function interrupts sleep() and calls siglongjmp()
+ * or longjmp() to restore an environment saved prior to the sleep() call,
+ * the action associated with the SIGALRM signal and the time at which a
+ * SIGALRM signal is scheduled to be generated are unspecified. It is also
+ * unspecified whether the SIGALRM signal is blocked, unless the process'
+ * signal mask is restored as part of the environment.
+ *
+ * Implementations may place limitations on the granularity of timer values.
+ * For each interval timer, if the requested timer value requires a finer
+ * granularity than the implementation supports, the actual timer value will
+ * be rounded up to the next supported value.
+ *
+ * Interactions between sleep() and any of setitimer(), ualarm() or sleep()
+ * are unspecified.
+ *
+ * Parameters:
+ * seconds
+ *
+ * Returned Value:
+ * If sleep() returns because the requested time has elapsed, the value
+ * returned will be 0. If sleep() returns because of premature arousal due
+ * to delivery of a signal, the return value will be the "unslept" amount
+ * (the requested time minus the time actually slept) in seconds.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+unsigned int sleep(unsigned int seconds)
+{
+ sigset_t set;
+ struct timespec ts;
+ struct siginfo value;
+ irqstate_t flags;
+ uint32_t start;
+ int32_t elapsed;
+ int32_t remaining = 0;
+
+ /* Don't sleep if seconds == 0 */
+
+ if (seconds)
+ {
+ /* Set up for the sleep. Using the empty set means that we are not
+ * waiting for any particualar signal. However, any unmasked signal
+ * can still awaken sigtimedwait().
+ */
+
+ (void)sigemptyset(&set);
+ ts.tv_sec = seconds;
+ ts.tv_nsec = 0;
+
+ /* Interrupts are disabled around the following so that it is atomic */
+
+ flags = irqsave();
+
+ /* Get the current time then sleep for the requested time.
+ * sigtimedwait() cannot succeed. It should always return error with
+ * either (1) EAGAIN meaning that the timeout occurred, or (2) EINTR
+ * meaning that some other unblocked signal was caught.
+ */
+
+ start = clock_systimer();
+ (void)sigtimedwait(&set, &value, &ts);
+
+ /* Calculate the elapsed time (in clock ticks) when we wake up from the sleep.
+ * This is really only necessary if we were awakened from the sleep early
+ * due to the receipt of a signal.
+ */
+
+ elapsed = clock_systimer() - start;
+ irqrestore(flags);
+
+ /* Get the remaining, un-waited seconds. Note that this calculation
+ * truncates the elapsed seconds in the division. We may have slept some
+ * fraction of a second longer than this! But if the calculation is less
+ * than the 'seconds', we certainly did not sleep for the complete
+ * requested interval.
+ */
+
+ remaining = (int32_t)seconds - elapsed / TICK_PER_SEC;
+
+ /* Make sure that the elapsed time is non-negative (this should always
+ * be the case unless something exceptional happened while were we
+ * sleeping -- like the clock was reset or we went into a low power mode,
+ * OR if we had to wait a long time to run again after calling
+ * sigtimedwait() making 'elapsed' bigger than it should have been).
+ */
+
+ if (remaining < 0)
+ {
+ remaining = 0;
+ }
+ }
+
+ return (unsigned int)remaining;
+}
diff --git a/nuttx/sched/task_activate.c b/nuttx/sched/task_activate.c
new file mode 100644
index 000000000..bae2856a1
--- /dev/null
+++ b/nuttx/sched/task_activate.c
@@ -0,0 +1,117 @@
+/****************************************************************************
+ * sched/task_activate.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_activate
+ *
+ * Description:
+ * This function activates tasks initialized by task_schedsetup(). Without
+ * activation, a task is ineligible for execution by the scheduler.
+ *
+ * Input Parameters:
+ * tcb - The TCB for the task for the task (same as the task_init argument).
+ *
+ * Return Value:
+ * Always returns OK
+ *
+ ****************************************************************************/
+
+int task_activate(FAR _TCB *tcb)
+{
+ irqstate_t flags = irqsave();
+
+#ifdef CONFIG_SCHED_INSTRUMENTATION
+
+ /* Check if this is really a re-start */
+
+ if (tcb->task_state != TSTATE_TASK_INACTIVE)
+ {
+ /* Inform the instrumentation layer that the task
+ * has stopped
+ */
+
+ sched_note_stop(tcb);
+ }
+
+ /* Inform the instrumentation layer that the task
+ * has started
+ */
+
+ sched_note_start(tcb);
+#endif
+
+ up_unblock_task(tcb);
+ irqrestore(flags);
+ return OK;
+}
diff --git a/nuttx/sched/task_create.c b/nuttx/sched/task_create.c
new file mode 100644
index 000000000..4d92c9bb0
--- /dev/null
+++ b/nuttx/sched/task_create.c
@@ -0,0 +1,269 @@
+/****************************************************************************
+ * sched/task_create.c
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/kmalloc.h>
+
+#include "os_internal.h"
+#include "env_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: thread_create
+ *
+ * Description:
+ * This function creates and activates a new thread of the specified type
+ * with a specified priority and returns its system-assigned ID. It is the
+ * internal, commn implementation of task_create() and kernel_thread().
+ * See comments with task_create() for further information.
+ *
+ * Input Parameters:
+ * name - Name of the new task
+ * type - Type of the new task
+ * priority - Priority of the new task
+ * stack_size - size (in bytes) of the stack needed
+ * entry - Entry point of a new task
+ * arg - A pointer to an array of input parameters. Up to
+ * CONFIG_MAX_TASK_ARG parameters may be provided. If fewer
+ * than CONFIG_MAX_TASK_ARG parameters are passed, the list
+ * should be terminated with a NULL argv[] value. If no
+ * parameters are required, argv may be NULL.
+ *
+ * Return Value:
+ * Returns the non-zero process ID of the new task or ERROR if memory is
+ * insufficient or the task cannot be created. The errno will be set to
+ * indicate the nature of the error (always ENOMEM).
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_CUSTOM_STACK
+static int thread_create(const char *name, uint8_t type, int priority,
+ int stack_size, main_t entry, const char **argv)
+#else
+static int thread_create(const char *name, uint8_t type, int priority,
+ main_t entry, const char **argv)
+#endif
+{
+ FAR _TCB *tcb;
+ pid_t pid;
+ int ret;
+
+ /* Allocate a TCB for the new task. */
+
+ tcb = (FAR _TCB*)kzalloc(sizeof(_TCB));
+ if (!tcb)
+ {
+ goto errout;
+ }
+
+ /* Associate file descriptors with the new task */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+ ret = sched_setuptaskfiles(tcb);
+ if (ret != OK)
+ {
+ goto errout_with_tcb;
+ }
+#endif
+
+ /* Clone the parent's task environment */
+
+ (void)env_dup(tcb);
+
+ /* Allocate the stack for the TCB */
+
+#ifndef CONFIG_CUSTOM_STACK
+ ret = up_create_stack(tcb, stack_size);
+ if (ret != OK)
+ {
+ goto errout_with_tcb;
+ }
+#endif
+
+ /* Mark the type of this thread (this setting will be needed in
+ * task_schedsetup() when up_initial_state() is called.
+ */
+
+ tcb->flags |= type;
+
+ /* Initialize the task control block */
+
+ ret = task_schedsetup(tcb, priority, task_start, entry);
+ if (ret != OK)
+ {
+ goto errout_with_tcb;
+ }
+
+ /* Setup to pass parameters to the new task */
+
+ (void)task_argsetup(tcb, name, argv);
+
+ /* Get the assigned pid before we start the task */
+
+ pid = (int)tcb->pid;
+
+ /* Activate the task */
+
+ ret = task_activate(tcb);
+ if (ret != OK)
+ {
+ dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks);
+ goto errout_with_tcb;
+ }
+
+ return pid;
+
+errout_with_tcb:
+ sched_releasetcb(tcb);
+
+errout:
+ errno = ENOMEM;
+ return ERROR;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_create
+ *
+ * Description:
+ * This function creates and activates a new task with a specified
+ * priority and returns its system-assigned ID.
+ *
+ * The entry address entry is the address of the "main" function of the
+ * task. This function will be called once the C environment has been
+ * set up. The specified function will be called with four arguments.
+ * Should the specified routine return, a call to exit() will
+ * automatically be made.
+ *
+ * Note that four (and only four) arguments must be passed for the spawned
+ * functions.
+ *
+ * Input Parameters:
+ * name - Name of the new task
+ * priority - Priority of the new task
+ * stack_size - size (in bytes) of the stack needed
+ * entry - Entry point of a new task
+ * arg - A pointer to an array of input parameters. Up to
+ * CONFIG_MAX_TASK_ARG parameters may be provided. If fewer
+ * than CONFIG_MAX_TASK_ARG parameters are passed, the list
+ * should be terminated with a NULL argv[] value. If no
+ * parameters are required, argv may be NULL.
+ *
+ * Return Value:
+ * Returns the non-zero process ID of the new task or ERROR if memory is
+ * insufficient or the task cannot be created. The errno will be set to
+ * indicate the nature of the error (always ENOMEM).
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_CUSTOM_STACK
+int task_create(const char *name, int priority,
+ int stack_size, main_t entry, const char *argv[])
+#else
+int task_create(const char *name, int priority,
+ main_t entry, const char *argv[])
+#endif
+{
+#ifndef CONFIG_CUSTOM_STACK
+ return thread_create(name, TCB_FLAG_TTYPE_TASK, priority, stack_size, entry, argv);
+#else
+ return thread_create(name, TCB_FLAG_TTYPE_TASK, priority, entry, argv);
+#endif
+}
+
+/****************************************************************************
+ * Name: kernel_thread
+ *
+ * Description:
+ * This function creates and activates a kernel thread task with kernel-
+ * mode privileges. It is identical to task_create() except that it
+ * configures the newly started thread to run in kernel model.
+ *
+ * Input Parameters:
+ * (same as task_create())
+ *
+ * Return Value:
+ * (same as task_create())
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_CUSTOM_STACK
+int kernel_thread(const char *name, int priority,
+ int stack_size, main_t entry, const char *argv[])
+#else
+int kernel_thread(const char *name, int priority,
+ main_t entry, const char *argv[])
+#endif
+{
+#ifndef CONFIG_CUSTOM_STACK
+ return thread_create(name, TCB_FLAG_TTYPE_KERNEL, priority, stack_size, entry, argv);
+#else
+ return thread_create(name, TCB_FLAG_TTYPE_KERNEL, priority, entry, argv);
+#endif
+}
+
diff --git a/nuttx/sched/task_delete.c b/nuttx/sched/task_delete.c
new file mode 100644
index 000000000..ea0e251db
--- /dev/null
+++ b/nuttx/sched/task_delete.c
@@ -0,0 +1,194 @@
+/****************************************************************************
+ * sched/task_delete.c
+ *
+ * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <sched.h>
+
+#include "os_internal.h"
+#ifndef CONFIG_DISABLE_SIGNALS
+# include "sig_internal.h"
+#endif
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_delete
+ *
+ * Description:
+ * This function causes a specified task to cease to exist. Its stack and
+ * TCB will be deallocated. This function is the companion to task_create().
+ *
+ * The logic in this function only deletes non-running tasks. If the 'pid'
+ * parameter refers to to the currently runing task, then processing is
+ * redirected to exit().
+ *
+ * Control will still be returned to task_delete() after the exit() logic
+ * finishes. In fact, this function is the final function called all task
+ * termination sequences. Here are all possible exit scenarios:
+ *
+ * - pthread_exit(). Calls exit()
+ * - exit(). Calls _exit()
+ * - _exit(). Calls task_deletecurrent() making the currently running task
+ * non-running then calls task_delete() to terminate the non-running
+ * task.
+ * - task_delete()
+ *
+ * Inputs:
+ * pid - The task ID of the task to delete. A pid of zero
+ * signifies the calling task.
+ *
+ * Return Value:
+ * OK on success; or ERROR on failure
+ *
+ * This function can fail if the provided pid does not correspond to a
+ * task (errno is not set)
+ *
+ ****************************************************************************/
+
+int task_delete(pid_t pid)
+{
+ FAR _TCB *rtcb;
+ FAR _TCB *dtcb;
+ irqstate_t saved_state;
+ int ret = ERROR;
+
+ /* Check if the task to delete is the calling task */
+
+ rtcb = (FAR _TCB*)g_readytorun.head;
+ if (pid == 0 || pid == rtcb->pid)
+ {
+ /* If it is, then what we really wanted to do was exit. Note that we
+ * don't bother to unlock the TCB since it will be going away.
+ */
+
+ exit(EXIT_SUCCESS);
+ }
+
+ /* Make sure the task does not become ready-to-run while we are futzing with
+ * its TCB by locking ourselves as the executing task.
+ */
+
+ sched_lock();
+
+ /* Find for the TCB associated with matching pid */
+
+ dtcb = sched_gettcb(pid);
+ if (!dtcb)
+ {
+ /* This pid does not correspond to any known task */
+
+ sched_unlock();
+ return ERROR;
+ }
+
+ /* Verify our internal sanity */
+
+ if (dtcb->task_state == TSTATE_TASK_RUNNING ||
+ dtcb->task_state >= NUM_TASK_STATES)
+ {
+ sched_unlock();
+ PANIC(OSERR_BADDELETESTATE);
+ }
+
+ /* Perform common task termination logic (flushing streams, calling
+ * functions registered by at_exit/on_exit, etc.). We need to do
+ * this as early as possible so that higher level clean-up logic
+ * can run in a healthy tasking environment.
+ *
+ * In the case where the task exits via exit(), task_exithook()
+ * may be called twice.
+ *
+ * I suppose EXIT_SUCCESS is an appropriate return value???
+ */
+
+ task_exithook(dtcb, EXIT_SUCCESS);
+
+ /* Remove the task from the OS's tasks lists. */
+
+ saved_state = irqsave();
+ dq_rem((FAR dq_entry_t*)dtcb, (dq_queue_t*)g_tasklisttable[dtcb->task_state].list);
+ dtcb->task_state = TSTATE_TASK_INVALID;
+ irqrestore(saved_state);
+
+ /* At this point, the TCB should no longer be accessible to the system */
+
+ sched_unlock();
+
+ /* Since all tasks pass through this function as the final step in their
+ * exit sequence, this is an appropriate place to inform any instrumentation
+ * layer that the task no longer exists.
+ */
+
+ sched_note_stop(dtcb);
+
+ /* Deallocate its TCB */
+
+ sched_releasetcb(dtcb);
+ return ret;
+}
+
diff --git a/nuttx/sched/task_deletecurrent.c b/nuttx/sched/task_deletecurrent.c
new file mode 100644
index 000000000..77025f5e0
--- /dev/null
+++ b/nuttx/sched/task_deletecurrent.c
@@ -0,0 +1,140 @@
+/****************************************************************************
+ * sched/task_deletecurrent.c
+ *
+ * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sched.h>
+#include "os_internal.h"
+#ifndef CONFIG_DISABLE_SIGNALS
+# include "sig_internal.h"
+#endif
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_delete
+ *
+ * Description:
+ * This function causes the currently running task (i.e., the task at the
+ * head of the ready-to-run list) to cease to exist. This is a part of
+ * the logic used to implement _exit(). The full implementation of _exit()
+ * is architecture-dependent. This function should never be called from
+ * normal user code, but only from the architecture-specific implementation
+ * of exit.
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * OK on success; or ERROR on failure
+ *
+ ****************************************************************************/
+
+int task_deletecurrent(void)
+{
+ FAR _TCB *dtcb = (FAR _TCB*)g_readytorun.head;
+ FAR _TCB *rtcb;
+
+ /* Remove the TCB of the current task from the ready-to-run list. A context
+ * switch will definitely be necessary -- that must be done by the
+ * architecture-specific logic.
+ *
+ * sched_removereadytorun will mark the task at the head of the ready-to-run
+ * with state == TSTATE_TASK_RUNNING
+ */
+
+ (void)sched_removereadytorun(dtcb);
+ rtcb = (FAR _TCB*)g_readytorun.head;
+
+ /* We are not in a bad state -- the head of the ready to run task list
+ * does not correspond to the thread that is running. Disabling pre-
+ * emption on this TCB and marking the new ready-to-run task as not
+ * running (see, for example, get_errno_ptr()).
+ */
+
+ sched_lock();
+ rtcb->task_state = TSTATE_TASK_READYTORUN;
+
+ /* Move the TCB to the specified blocked task list and delete it */
+
+ sched_addblocked(dtcb, TSTATE_TASK_INACTIVE);
+ task_delete(dtcb->pid);
+ rtcb->task_state = TSTATE_TASK_RUNNING;
+
+ /* If there are any pending tasks, then add them to the ready-to-run
+ * task list now
+ */
+
+ if (g_pendingtasks.head)
+ {
+ (void)sched_mergepending();
+ }
+
+ /* Now calling sched_unlock() should have no effect */
+
+ sched_unlock();
+ return OK;
+}
+
diff --git a/nuttx/sched/task_exithook.c b/nuttx/sched/task_exithook.c
new file mode 100644
index 000000000..e94476f2a
--- /dev/null
+++ b/nuttx/sched/task_exithook.c
@@ -0,0 +1,290 @@
+/****************************************************************************
+ * sched/task_exithook.c
+ *
+ * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/sched.h>
+#include <nuttx/fs/fs.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_atexit
+ *
+ * Description:
+ * Call any registerd atexit function(s)
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SCHED_ATEXIT
+static inline void task_atexit(FAR _TCB *tcb)
+{
+#if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1
+ int index;
+
+ /* Call each atexit function in reverse order of registration atexit()
+ * functions are registered from lower to higher arry indices; they must
+ * be called in the reverse order of registration when task exists, i.e.,
+ * from higher to lower indices.
+ */
+
+ for (index = CONFIG_SCHED_ATEXIT_MAX-1; index >= 0; index--)
+ {
+ if (tcb->atexitfunc[index])
+ {
+ /* Call the atexit function */
+
+ (*tcb->atexitfunc[index])();
+
+ /* Nullify the atexit function. task_exithook may be called more then
+ * once in most task exit scenarios. Nullifying the atext function
+ * pointer will assure that the callback is performed only once.
+ */
+
+ tcb->atexitfunc[index] = NULL;
+ }
+ }
+
+#else
+ if (tcb->atexitfunc)
+ {
+ /* Call the atexit function */
+
+ (*tcb->atexitfunc)();
+
+ /* Nullify the atexit function. task_exithook may be called more then
+ * once in most task exit scenarios. Nullifying the atext function
+ * pointer will assure that the callback is performed only once.
+ */
+
+ tcb->atexitfunc = NULL;
+ }
+#endif
+#else
+# define task_atexit(tcb)
+#endif
+
+/****************************************************************************
+ * Name: task_onexit
+ *
+ * Description:
+ * Call any registerd on)exit function(s)
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SCHED_ONEXIT
+static inline void task_onexit(FAR _TCB *tcb, int status)
+{
+#if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1
+ int index;
+
+ /* Call each on_exit function in reverse order of registration. on_exit()
+ * functions are registered from lower to higher arry indices; they must
+ * be called in the reverse order of registration when task exists, i.e.,
+ * from higher to lower indices.
+ */
+
+ for (index = CONFIG_SCHED_ONEXIT_MAX-1; index >= 0; index--)
+ {
+ if (tcb->onexitfunc[index])
+ {
+ /* Call the on_exit function */
+
+ (*tcb->onexitfunc[index])(status, tcb->onexitarg[index]);
+
+ /* Nullify the on_exit function. task_exithook may be called more then
+ * once in most task exit scenarios. Nullifying the atext function
+ * pointer will assure that the callback is performed only once.
+ */
+
+ tcb->onexitfunc[index] = NULL;
+ }
+ }
+#else
+ if (tcb->onexitfunc)
+ {
+ /* Call the on_exit function */
+
+ (*tcb->onexitfunc)(status, tcb->onexitarg);
+
+ /* Nullify the on_exit function. task_exithook may be called more then
+ * once in most task exit scenarios. Nullifying the on_exit function
+ * pointer will assure that the callback is performed only once.
+ */
+
+ tcb->onexitfunc = NULL;
+ }
+#endif
+}
+#else
+# define task_onexit(tcb,status)
+#endif
+
+/****************************************************************************
+ * Name: task_exitwakeup
+ *
+ * Description:
+ * Wakeup any tasks waiting for this task to exit
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SCHED_WAITPID
+static inline void task_exitwakeup(FAR _TCB *tcb, int status)
+{
+ /* Wakeup any tasks waiting for this task to exit */
+
+ while (tcb->exitsem.semcount < 0)
+ {
+ /* "If more than one thread is suspended in waitpid() awaiting
+ * termination of the same process, exactly one thread will return
+ * the process status at the time of the target process termination."
+ * Hmmm.. what do we return to the others?
+ */
+
+ if (tcb->stat_loc)
+ {
+ *tcb->stat_loc = status << 8;
+ tcb->stat_loc = NULL;
+ }
+
+ /* Wake up the thread */
+
+ sem_post(&tcb->exitsem);
+ }
+}
+#else
+# define task_exitwakeup(tcb, status)
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_hook
+ *
+ * Description:
+ * This function implements some of the internal logic of exit() and
+ * task_delete(). This function performs some cleanup and other actions
+ * required when a task exists:
+ *
+ * - All open streams are flushed and closed.
+ * - All functions registered with atexit() and on_exit() are called, in
+ * the reverse order of their registration.
+ *
+ * When called from exit(), the tcb still resides at the head of the ready-
+ * to-run list. The following logic is safe because we will not be
+ * returning from the exit() call.
+ *
+ * When called from task_delete() we are operating on a different thread;
+ * on the thread that called task_delete(). In this case, task_delete
+ * will have already removed the tcb from the ready-to-run list to prevent
+ * any further action on this task.
+ *
+ ****************************************************************************/
+
+void task_exithook(FAR _TCB *tcb, int status)
+{
+ /* If exit function(s) were registered, call them now before we do any un-
+ * initialization. NOTE: In the case of task_delete(), the exit function
+ * will *not* be called on the thread execution of the task being deleted!
+ */
+
+ task_atexit(tcb);
+
+ /* Call any registered on_exit function(s) */
+
+ task_onexit(tcb, status);
+
+ /* Wakeup any tasks waiting for this task to exit */
+
+ task_exitwakeup(tcb, status);
+
+ /* Flush all streams (File descriptors will be closed when
+ * the TCB is deallocated).
+ */
+
+#if CONFIG_NFILE_STREAMS > 0
+ (void)lib_flushall(tcb->streams);
+#endif
+
+ /* Free all file-related resources now. This gets called again
+ * just be be certain when the TCB is delallocated. However, we
+ * really need to close files as soon as possible while we still
+ * have a functioning task.
+ */
+
+ (void)sched_releasefiles(tcb);
+
+ /* Deallocate anything left in the TCB's queues */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ sig_cleanup(tcb); /* Deallocate Signal lists */
+#endif
+}
diff --git a/nuttx/sched/task_init.c b/nuttx/sched/task_init.c
new file mode 100644
index 000000000..31fc5ef70
--- /dev/null
+++ b/nuttx/sched/task_init.c
@@ -0,0 +1,154 @@
+/****************************************************************************
+ * sched/task_init.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "env_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_init
+ *
+ * Description:
+ * This function initializes a Task Control Block (TCB) in preparation for
+ * starting a new thread. It performs a subset of the functionality of
+ * task_create()
+ *
+ * Unlike task_create():
+ * 1. Allocate the TCB. The pre-allocated TCB is passed in the arguments.
+ * 2. Allocate the stack. The pre-allocated stack is passed in the arguments.
+ * 3. Activate the task. This must be done by calling task_activate().
+ *
+ * Input Parameters:
+ * tcb - Address of the new task's TCB
+ * name - Name of the new task (not used)
+ * priority - Priority of the new task
+ * stack - Start of the pre-allocated stack
+ * stack_size - Size (in bytes) of the stack allocated
+ * entry - Application start point of the new task
+ * arg - A pointer to an array of input parameters. Up to
+ * CONFIG_MAX_TASK_ARG parameters may be provided. If fewer
+ * than CONFIG_MAX_TASK_ARG parameters are passed, the list
+ * should be terminated with a NULL argv[] value. If no
+ * parameters are required, argv may be NULL.
+ *
+ * Return Value:
+ * OK on success; ERROR on failure. (See task_schedsetup() for possible
+ * failure conditions). On failure, the caller is responsible for freeing
+ * the stack memory and for calling sched_releasetcb() to free the TCB
+ * (which could be in most any state).
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_CUSTOM_STACK
+int task_init(FAR _TCB *tcb, const char *name, int priority,
+ FAR uint32_t *stack, uint32_t stack_size,
+ main_t entry, const char *argv[])
+#else
+int task_init(FAR _TCB *tcb, const char *name, int priority,
+ main_t entry, const char *argv[])
+#endif
+{
+ int ret;
+
+ /* Associate file descriptors with the new task */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+ if (sched_setuptaskfiles(tcb) != OK)
+ {
+ return ERROR;
+ }
+#endif
+
+ /* Clone the parent's task environment */
+
+ (void)env_dup(tcb);
+
+ /* Configure the user provided stack region */
+
+#ifndef CONFIG_CUSTOM_STACK
+ up_use_stack(tcb, stack, stack_size);
+#endif
+
+ /* Initialize the task control block */
+
+ ret = task_schedsetup(tcb, priority, task_start, entry);
+ if (ret == OK)
+ {
+ /* Setup to pass parameters to the new task */
+
+ (void)task_argsetup(tcb, name, argv);
+ }
+
+ return ret;
+}
+
diff --git a/nuttx/sched/task_restart.c b/nuttx/sched/task_restart.c
new file mode 100644
index 000000000..6d9b84917
--- /dev/null
+++ b/nuttx/sched/task_restart.c
@@ -0,0 +1,184 @@
+/****************************************************************************
+ * sched/task_restart.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+#include <sched.h>
+#include <nuttx/arch.h>
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_restart
+ *
+ * Description:
+ * This function "restarts" a task. The task is first terminated and then
+ * reinitialized with same ID, priority, original entry point, stack size,
+ * and parameters it had when it was first started.
+ *
+ * Inputs:
+ * pid - The task ID of the task to delete. An ID of zero signifies the
+ * calling task.
+ *
+ * Return Value:
+ * OK on sucess; ERROR on failure.
+ *
+ * This function can fail if:
+ * (1) A pid of zero or the pid of the calling task is provided
+ * (functionality not implemented)
+ * (2) The pid is not associated with any task known to the system.
+ *
+ ****************************************************************************/
+
+int task_restart(pid_t pid)
+{
+ FAR _TCB *rtcb;
+ FAR _TCB *tcb;
+ int status;
+ irqstate_t state;
+
+ /* Make sure this task does not become ready-to-run while
+ * we are futzing with its TCB
+ */
+
+ sched_lock();
+
+ /* Check if the task to restart is the calling task */
+
+ rtcb = (FAR _TCB*)g_readytorun.head;
+ if ((pid == 0) || (pid == rtcb->pid))
+ {
+ /* Not implemented */
+
+ return ERROR;
+ }
+
+ /* We are restarting some other task than ourselves */
+
+ else
+ {
+ /* Find for the TCB associated with matching pid */
+
+ tcb = sched_gettcb(pid);
+ if (!tcb)
+ {
+ /* There is no TCB with this pid */
+
+ return ERROR;
+ }
+
+ /* Remove the TCB from whatever list it is in. At this point, the
+ * TCB should no longer be accessible to the system
+ */
+
+ state = irqsave();
+ dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)g_tasklisttable[tcb->task_state].list);
+ tcb->task_state = TSTATE_TASK_INVALID;
+ irqrestore(state);
+
+ /* Deallocate anything left in the TCB's queues */
+
+ sig_cleanup(tcb); /* Deallocate Signal lists */
+
+ /* Reset the current task priority */
+
+ tcb->sched_priority = tcb->init_priority;
+
+ /* Reset the base task priority and the number of pending reprioritizations */
+
+#ifdef CONFIG_PRIORITY_INHERITANCE
+ tcb->base_priority = tcb->init_priority;
+# if CONFIG_SEM_NNESTPRIO > 0
+ tcb->npend_reprio = 0;
+# endif
+#endif
+
+ /* Re-initialize the processor-specific portion of the TCB
+ * This will reset the entry point and the start-up parameters
+ */
+
+ up_initial_state(tcb);
+
+ /* Add the task to the inactive task list */
+
+ dq_addfirst((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks);
+ tcb->task_state = TSTATE_TASK_INACTIVE;
+
+ /* Activate the task */
+
+ status = task_activate(tcb);
+ if (status != OK)
+ {
+ dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks);
+ sched_releasetcb(tcb);
+ return ERROR;
+ }
+ }
+
+ sched_unlock();
+ return OK;
+}
diff --git a/nuttx/sched/task_setup.c b/nuttx/sched/task_setup.c
new file mode 100644
index 000000000..a37fb165a
--- /dev/null
+++ b/nuttx/sched/task_setup.c
@@ -0,0 +1,347 @@
+/****************************************************************************
+ * sched/task_setup.c
+ *
+ * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/* This is the name for un-named tasks */
+
+static const char g_noname[] = "<noname>";
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int task_assignpid(FAR _TCB* tcb);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_assignpid
+ *
+ * Description:
+ * This function assigns the next unique task ID to a task.
+ *
+ * Inputs:
+ * tcb - TCB of task
+ *
+ * Return:
+ * OK on success; ERROR on failure (errno is not set)
+ *
+ ****************************************************************************/
+
+static int task_assignpid(FAR _TCB *tcb)
+{
+ pid_t next_pid;
+ int hash_ndx;
+ int tries;
+
+ /* Disable pre-emption. This should provide sufficient protection
+ * for the following operation.
+ */
+
+ (void)sched_lock();
+
+ /* We'll try every allowable pid */
+
+ for (tries = 0; tries < CONFIG_MAX_TASKS; tries++)
+ {
+ /* Get the next process ID candidate */
+
+ next_pid = ++g_lastpid;
+
+ /* Verify that the next_pid is in the valid range */
+
+ if (next_pid <= 0)
+ {
+ g_lastpid = 1;
+ next_pid = 1;
+ }
+
+ /* Get the hash_ndx associated with the next_pid */
+
+ hash_ndx = PIDHASH(next_pid);
+
+ /* Check if there is a (potential) duplicate of this pid */
+
+ if (!g_pidhash[hash_ndx].tcb)
+ {
+ g_pidhash[hash_ndx].tcb = tcb;
+ g_pidhash[hash_ndx].pid = next_pid;
+ tcb->pid = next_pid;
+ (void)sched_unlock();
+ return OK;
+ }
+ }
+
+ /* If we get here, then the g_pidhash[] table is completely full.
+ * We cannot allow another task to be started.
+ */
+
+ (void)sched_unlock();
+ return ERROR;
+}
+
+/****************************************************************************
+ * Name: task_dupdspace
+ *
+ * Description:
+ * When a new task or thread is created from a PIC module, then that
+ * module (probably) intends the task or thread to execute in the same
+ * D-Space. This function will duplicate the D-Space for that purpose.
+ *
+ * Parameters:
+ * tcb - The TCB of the new task.
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_PIC
+static inline void task_dupdspace(FAR _TCB *tcb)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ if (rtcb->dspace != NULL)
+ {
+ /* Copy the D-Space structure reference and increment the reference
+ * count on the memory. The D-Space memory will persist until the
+ * last thread exits (see sched_releasetcb()).
+ */
+
+ tcb->dspace = rtcb->dspace;
+ tcb->dspace->crefs++;
+ }
+}
+#else
+# define task_dupdspace(tcb)
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_schedsetup
+ *
+ * Description:
+ * This functions initializes a Task Control Block (TCB) in preparation
+ * for starting a new thread.
+ *
+ * task_schedsetup() is called from task_init(), task_start(), and
+ * pthread_create();
+ *
+ * Input Parameters:
+ * tcb - Address of the new task's TCB
+ * priority - Priority of the new task
+ * entry - Entry point of a new task
+ * main - Application start point of the new task
+ * type - Type of the new thread: task, pthread, or kernel thread
+ *
+ * Return Value:
+ * OK on success; ERROR on failure.
+ *
+ * This function can only failure is it is unable to assign a new, unique
+ * task ID to the TCB (errno is not set).
+ *
+ ****************************************************************************/
+
+int task_schedsetup(FAR _TCB *tcb, int priority, start_t start, main_t main)
+{
+ int ret;
+
+ /* Assign a unique task ID to the task. */
+
+ ret = task_assignpid(tcb);
+ if (ret == OK)
+ {
+ /* Save task priority and entry point in the TCB */
+
+ tcb->init_priority = (uint8_t)priority;
+ tcb->sched_priority = (uint8_t)priority;
+#ifdef CONFIG_PRIORITY_INHERITANCE
+ tcb->base_priority = (uint8_t)priority;
+#endif
+ tcb->start = start;
+ tcb->entry.main = main;
+
+ /* exec() and pthread_create() inherit the signal mask of the
+ * parent thread. I suppose that task_create() should as well.
+ */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ (void)sigprocmask(SIG_SETMASK, NULL, &tcb->sigprocmask);
+#endif
+
+ /* Initialize the task state. It does not get a valid state
+ * until it is activated.
+ */
+
+ tcb->task_state = TSTATE_TASK_INVALID;
+
+ /* Clone the parent tasks D-Space (if it was running PIC). This
+ * must be done before calling up_initial_state() so that the
+ * state setup will take the PIC address base into account.
+ */
+
+ task_dupdspace(tcb);
+
+ /* Initialize the processor-specific portion of the TCB */
+
+ up_initial_state(tcb);
+
+ /* Add the task to the inactive task list */
+
+ sched_lock();
+ dq_addfirst((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks);
+ tcb->task_state = TSTATE_TASK_INACTIVE;
+ sched_unlock();
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: task_argsetup
+ *
+ * Description:
+ * This functions sets up parameters in the Task Control
+ * Block (TCB) in preparation for starting a new thread.
+ *
+ * task_argsetup() is called only from task_init() and
+ * task_start() to create a new task. Argumens are
+ * cloned via strdup.
+ *
+ * Input Parameters:
+ * tcb - Address of the new task's TCB
+ * name - Name of the new task (not used)
+ * argv - A pointer to an array of input parameters.
+ * Up to CONFIG_MAX_TASK_ARG parameters may be
+ * provided. If fewer than CONFIG_MAX_TASK_ARG
+ * parameters are passed, the list should be
+ * terminated with a NULL argv[] value.
+ * If no parameters are required, argv may be NULL.
+ *
+ * Return Value:
+ * OK
+ *
+ ****************************************************************************/
+
+int task_argsetup(FAR _TCB *tcb, const char *name, const char *argv[])
+{
+ int i;
+
+#if CONFIG_TASK_NAME_SIZE > 0
+ /* Give a name to the unnamed tasks */
+
+ if (!name)
+ {
+ name = (char *)g_noname;
+ }
+
+ /* Copy the name into the TCB */
+
+ strncpy(tcb->name, name, CONFIG_TASK_NAME_SIZE);
+
+ /* Save the name as the first argument */
+
+ tcb->argv[0] = tcb->name;
+#else
+ /* Save the name as the first argument */
+
+ tcb->argv[0] = (char *)g_noname;
+#endif /* CONFIG_TASK_NAME_SIZE */
+
+ /* For tasks, the life of the argument must be as long as
+ * the life of the task and the arguments must be strings.
+ * So for tasks, we have to to dup the strings.
+ *
+ * The first NULL argument terminates the list of
+ * arguments. The argv pointer may be NULL if no
+ * parameters are passed.
+ */
+
+ i = 1;
+ if (argv)
+ {
+ for (; i < CONFIG_MAX_TASK_ARGS+1 && argv[i-1]; i++)
+ {
+ tcb->argv[i] = strdup(argv[i-1]);
+ }
+ }
+
+ /* Nullify any unused argument storage */
+
+ for (; i < CONFIG_MAX_TASK_ARGS+1; i++)
+ {
+ tcb->argv[i] = NULL;
+ }
+
+ return OK;
+}
diff --git a/nuttx/sched/task_start.c b/nuttx/sched/task_start.c
new file mode 100644
index 000000000..a9cc38dfc
--- /dev/null
+++ b/nuttx/sched/task_start.c
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * sched/task_start.c
+ *
+ * Copyright (C) 2007-2010 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 <stdlib.h>
+#include <sched.h>
+#include <debug.h>
+
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: task_start
+ *
+ * Description:
+ * This function is the low level entry point into the main thread of
+ * execution of a task. It receives initial control when the task is
+ * started and calls main entry point of the newly started task.
+ *
+ * Inputs:
+ * None
+ *
+ * Return:
+ * None
+ *
+ ****************************************************************************/
+
+void task_start(void)
+{
+ FAR _TCB *tcb = (FAR _TCB*)g_readytorun.head;
+ int argc;
+
+ /* Count how many non-null arguments we are passing */
+
+ for (argc = 1; argc <= CONFIG_MAX_TASK_ARGS; argc++)
+ {
+ /* The first non-null argument terminates the list */
+
+ if (!tcb->argv[argc])
+ {
+ break;
+ }
+ }
+
+ /* Call the 'main' entry point passing argc and argv. If/when
+ * the task returns.
+ */
+
+ exit(tcb->entry.main(argc, tcb->argv));
+}
diff --git a/nuttx/sched/timer_create.c b/nuttx/sched/timer_create.c
new file mode 100644
index 000000000..edfb01080
--- /dev/null
+++ b/nuttx/sched/timer_create.c
@@ -0,0 +1,237 @@
+/********************************************************************************
+ * sched/timer_create.c
+ *
+ * Copyright (C) 2007-2009, 2011 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 <stdint.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include <wdog.h>
+#include <errno.h>
+
+#include <nuttx/kmalloc.h>
+
+#include "timer_internal.h"
+
+#ifndef CONFIG_DISABLE_POSIX_TIMERS
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: timer_allocate
+ *
+ * Description:
+ * Allocate one POSIX timer and place it into the allocated timer list.
+ *
+ ********************************************************************************/
+
+static struct posix_timer_s *timer_allocate(void)
+{
+ struct posix_timer_s *ret;
+ irqstate_t flags;
+ uint8_t pt_flags;
+
+ /* Try to get a preallocated timer from the free list */
+
+#if CONFIG_PREALLOC_TIMERS > 0
+ flags = irqsave();
+ ret = (struct posix_timer_s*)sq_remfirst((sq_queue_t*)&g_freetimers);
+ irqrestore(flags);
+
+ /* Did we get one? */
+
+ if (ret)
+ {
+ pt_flags = PT_FLAGS_PREALLOCATED;
+ }
+ else
+#endif
+ {
+ /* Allocate a new timer from the heap */
+
+ ret = (struct posix_timer_s*)kmalloc(sizeof(struct posix_timer_s));
+ pt_flags = 0;
+ }
+
+ /* If we have a timer, then put it into the allocated timer list */
+
+ if (ret)
+ {
+ /* Initialize the timer structure */
+
+ memset(ret, 0, sizeof(struct posix_timer_s));
+ ret->pt_flags = pt_flags;
+
+ /* And add it to the end of the list of allocated timers */
+
+ flags = irqsave();
+ sq_addlast((sq_entry_t*)ret, (sq_queue_t*)&g_alloctimers);
+ irqrestore(flags);
+ }
+
+ return ret;
+}
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: timer_create
+ *
+ * Description:
+ * The timer_create() function creates per-thread timer using the specified
+ * clock, clock_id, as the timing base. The timer_create() function returns, in
+ * the location referenced by timerid, a timer ID of type timer_t used to identify
+ * the timer in timer requests. This timer ID is unique until the timer is
+ * deleted. The particular clock, clock_id, is defined in <time.h>. The timer
+ * whose ID is returned will be in a disarmed state upon return from
+ * timer_create().
+ *
+ * The evp argument, if non-NULL, points to a sigevent structure. This structure
+ * is allocated by the called and defines the asynchronous notification to occur.
+ * If the evp argument is NULL, the effect is as if the evp argument pointed to
+ * a sigevent structure with the sigev_notify member having the value SIGEV_SIGNAL,
+ * the sigev_signo having a default signal number, and the sigev_value member
+ * having the value of the timer ID.
+ *
+ * Each implementation defines a set of clocks that can be used as timing bases
+ * for per-thread timers. All implementations shall support a clock_id of
+ * CLOCK_REALTIME.
+ *
+ * Parameters:
+ * clockid - Specifies the clock to use as the timing base.
+ * evp - Refers to a user allocated sigevent structure that defines the
+ * asynchronous notification. evp may be NULL (see above).
+ * timerid - The pre-thread timer created by the call to timer_create().
+ *
+ * Return Value:
+ * If the call succeeds, timer_create() will return 0 (OK) and update the
+ * location referenced by timerid to a timer_t, which can be passed to the
+ * other per-thread timer calls. If an error occurs, the function will return
+ * a value of -1 (ERROR) and set errno to indicate the error.
+ *
+ * EAGAIN - The system lacks sufficient signal queuing resources to honor the
+ * request.
+ * EAGAIN - The calling process has already created all of the timers it is
+ * allowed by this implementation.
+ * EINVAL - The specified clock ID is not defined.
+ * ENOTSUP - The implementation does not support the creation of a timer attached
+ * to the CPU-time clock that is specified by clock_id and associated with a
+ * thread different thread invoking timer_create().
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int timer_create(clockid_t clockid, FAR struct sigevent *evp, FAR timer_t *timerid)
+{
+ struct posix_timer_s *ret;
+ WDOG_ID wdog;
+
+ /* Sanity checks. Also, we support only CLOCK_REALTIME */
+
+ if (!timerid || clockid != CLOCK_REALTIME)
+ {
+ errno = EINVAL;
+ return ERROR;
+ }
+
+ /* Allocate a watchdog to provide the underling CLOCK_REALTIME timer */
+
+ wdog = wd_create();
+ if (!wdog)
+ {
+ errno = EAGAIN;
+ return ERROR;
+ }
+
+ /* Allocate a timer instance to contain the watchdog */
+
+ ret = timer_allocate();
+ if (!ret)
+ {
+ errno = EAGAIN;
+ return ERROR;
+ }
+
+ /* Initialize the timer instance */
+
+ ret->pt_crefs = 1;
+ ret->pt_owner = getpid();
+ ret->pt_delay = 0;
+ ret->pt_wdog = wdog;
+
+ if (evp)
+ {
+ ret->pt_signo = evp->sigev_signo;
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ ret->pt_value = evp->sigev_value;
+#else
+ ret->pt_value.sival_ptr = evp->sigev_value.sival_ptr;
+#endif
+ }
+ else
+ {
+ ret->pt_signo = SIGALRM;
+ ret->pt_value.sival_ptr = ret;
+ }
+
+ /* Return the timer */
+
+ *timerid = ret;
+ return OK;
+}
+
+#endif /* CONFIG_DISABLE_POSIX_TIMERS */
diff --git a/nuttx/sched/timer_delete.c b/nuttx/sched/timer_delete.c
new file mode 100644
index 000000000..c497c414e
--- /dev/null
+++ b/nuttx/sched/timer_delete.c
@@ -0,0 +1,106 @@
+/********************************************************************************
+ * timer_delete.c
+ *
+ * Copyright (C) 2007, 2008 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 <time.h>
+#include <errno.h>
+
+#include "timer_internal.h"
+
+#ifndef CONFIG_DISABLE_POSIX_TIMERS
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: timer_delete
+ *
+ * Description:
+ * The timer_delete() function deletes the specified timer, timerid, previously
+ * created by the timer_create() function. If the timer is armed when
+ * timer_delete() is called, the timer will be automatically disarmed before
+ * removal. The disposition of pending signals for the deleted timer is
+ * unspecified.
+ *
+ * Parameters:
+ * timerid - The per-thread timer, previously created by the call to
+ * timer_create(), to be deleted.
+ *
+ * Return Value:
+ * If the call succeeds, timer_create() will return 0 (OK). Otherwise, the
+ * function will return a value of -1 (ERROR) and set errno to indicate the
+ * error.
+ *
+ * EINVAL - The timer specified timerid is not valid.
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int timer_delete(timer_t timerid)
+{
+ int ret = timer_release((FAR struct posix_timer_s *)timerid);
+ if (ret < 0)
+ {
+ set_errno(-ret);
+ return ERROR;
+ }
+
+ return OK;
+}
+
+#endif /* CONFIG_DISABLE_POSIX_TIMERS */
diff --git a/nuttx/sched/timer_getoverrun.c b/nuttx/sched/timer_getoverrun.c
new file mode 100644
index 000000000..6d5a47465
--- /dev/null
+++ b/nuttx/sched/timer_getoverrun.c
@@ -0,0 +1,111 @@
+/********************************************************************************
+ * timer_getoverrun.c
+ *
+ * Copyright (C) 2007, 2008, 2011 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 <time.h>
+#include <errno.h>
+
+#include "timer_internal.h"
+
+#ifndef CONFIG_DISABLE_POSIX_TIMERS
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: timer_getoverrun
+ *
+ * Description:
+ * Only a single signal will be queued to the process for a given timer at any
+ * point in time. When a timer for which a signal is still pending expires, no
+ * signal will be queued, and a timer overrun will occur. When a timer
+ * expiration signal is delivered to or accepted by a process, if the
+ * implementation supports the Realtime Signals Extension, the
+ * timer_getoverrun() function will return the timer expiration overrun count for
+ * the specified timer. The overrun count returned contains the number of extra
+ * timer expirations that occurred between the time the signal was generated
+ * (queued) and when it was delivered or accepted, up to but not including an
+ * implementation-defined maximum of DELAYTIMER_MAX. If the number of such
+ * extra expirations is greater than or equal to DELAYTIMER_MAX, then the
+ * overrun count will be set to DELAYTIMER_MAX. The value returned by
+ * timer_getoverrun() will apply to the most recent expiration signal delivery
+ * or acceptance for the timer. If no expiration signal has been delivered
+ * for the timer, or if the Realtime Signals Extension is not supported, the
+ * return value of timer_getoverrun() is unspecified.
+ *
+ * Parameters:
+ * timerid - The pre-thread timer, previously created by the call to
+ * timer_create(), whose overrun count will be returned..
+ *
+ * Return Value:
+ * If the timer_getoverrun() function succeeds, it will return the timer
+ * expiration overrun count as explained above. timer_getoverrun() will fail if:
+ *
+ * EINVAL - The timerid argument does not correspond to an ID returned by
+ * timer_create() but not yet deleted by timer_delete().
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int timer_getoverrun(timer_t timerid)
+{
+ errno = ENOSYS;
+ return ERROR;
+}
+
+#endif /* CONFIG_DISABLE_POSIX_TIMERS */
diff --git a/nuttx/sched/timer_gettime.c b/nuttx/sched/timer_gettime.c
new file mode 100644
index 000000000..7598dbec5
--- /dev/null
+++ b/nuttx/sched/timer_gettime.c
@@ -0,0 +1,123 @@
+/********************************************************************************
+ * timer_gettime.c
+ *
+ * Copyright (C) 2007 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 <time.h>
+#include <errno.h>
+
+#include "clock_internal.h"
+#include "timer_internal.h"
+
+#ifndef CONFIG_DISABLE_POSIX_TIMERS
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: timer_gettime
+ *
+ * Description:
+ * The timer_gettime() function will store the amount of time until the
+ * specified timer, timerid, expires and the reload value of the timer into the
+ * space pointed to by the value argument. The it_value member of this structure
+ * will contain the amount of time before the timer expires, or zero if the timer
+ * is disarmed. This value is returned as the interval until timer expiration,
+ * even if the timer was armed with absolute time. The it_interval member of
+ * value will contain the reload value last set by timer_settime().
+ *
+ * Parameters:
+ * timerid - The pre-thread timer, previously created by the call to
+ * timer_create(), whose remaining time count will be returned..
+ *
+ * Return Value:
+ * If the timer_gettime() succeeds, a value of 0 (OK) will be returned.
+ * If an error occurs, the value -1 (ERROR) will be returned, and errno set to
+ * indicate the error.
+ *
+ * EINVAL - The timerid argument does not correspond to an ID returned by
+ * timer_create() but not yet deleted by timer_delete().
+ *
+ * Assumptions/Limitations:
+ * Due to the asynchronous operation of this function, the time reported
+ * by this function could be significantly more than that actual time
+ * remaining on the timer at any time.
+ *
+ ********************************************************************************/
+
+int timer_gettime(timer_t timerid, FAR struct itimerspec *value)
+{
+ FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)timerid;
+ int ticks;
+
+ if (!timer || !value)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ /* Get the number of ticks before the underlying watchdog expires */
+
+ ticks = wd_gettime(timer->pt_wdog);
+
+ /* Convert that to a struct timespec and return it */
+
+ (void)clock_ticks2time(ticks, &value->it_value);
+ (void)clock_ticks2time(timer->pt_last, &value->it_interval);
+ return OK;
+}
+
+#endif /* CONFIG_DISABLE_POSIX_TIMERS */
diff --git a/nuttx/sched/timer_initialize.c b/nuttx/sched/timer_initialize.c
new file mode 100644
index 000000000..05980bb1a
--- /dev/null
+++ b/nuttx/sched/timer_initialize.c
@@ -0,0 +1,168 @@
+/********************************************************************************
+ * timer_initialize.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ********************************************************************************/
+
+/********************************************************************************
+ * Included Files
+ ********************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <sys/types.h>
+#include <time.h>
+#include <queue.h>
+#include <errno.h>
+
+#include "timer_internal.h"
+
+#ifndef CONFIG_DISABLE_POSIX_TIMERS
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/* These are the preallocated times */
+
+#if CONFIG_PREALLOC_TIMERS > 0
+static struct posix_timer_s g_prealloctimers[CONFIG_PREALLOC_TIMERS];
+#endif
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/* This is a list of free, preallocated timer structures */
+
+#if CONFIG_PREALLOC_TIMERS > 0
+volatile sq_queue_t g_freetimers;
+#endif
+
+/* This is a list of instantiated timer structures -- active and inactive. The
+ * timers are place on this list by timer_create() and removed from the list by
+ * timer_delete() or when the owning thread exits.
+ */
+
+volatile sq_queue_t g_alloctimers;
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: timer_initialize
+ *
+ * Description:
+ * Boot up configuration of the POSIX timer facility.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+void weak_function timer_initialize(void)
+{
+#if CONFIG_PREALLOC_TIMERS > 0
+ int i;
+
+ /* Place all of the pre-allocated timers into the free timer list */
+
+ sq_init((sq_queue_t*)&g_freetimers);
+
+ for (i = 0; i < CONFIG_PREALLOC_TIMERS; i++)
+ {
+ g_prealloctimers[i].pt_flags = PT_FLAGS_PREALLOCATED;
+ sq_addlast((FAR sq_entry_t*)&g_prealloctimers[i], (FAR sq_queue_t*)&g_freetimers);
+ }
+#endif
+
+ /* Initialize the list of allocated timers */
+
+ sq_init((sq_queue_t*)&g_alloctimers);
+}
+
+/********************************************************************************
+ * Name: timer_deleteall
+ *
+ * Description:
+ * This function is called whenever a thread exits. Any timers owned by that
+ * thread are deleted as though called by timer_delete().
+ *
+ * It is provided in this file so that it can be weakly defined but also,
+ * like timer_intitialize(), be brought into the link whenever the timer
+ * resources are referenced.
+ *
+ * Parameters:
+ * pid - the task ID of the thread that exitted
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+void weak_function timer_deleteall(pid_t pid)
+{
+ FAR struct posix_timer_s *timer;
+ FAR struct posix_timer_s *next;
+ irqstate_t flags;
+
+ flags = irqsave();
+ for (timer = (FAR struct posix_timer_s*)g_alloctimers.head; timer; timer = next)
+ {
+ next = timer->flink;
+ if (timer->pt_owner == pid)
+ {
+ timer_delete((timer_t)timer);
+ }
+ }
+
+ irqrestore(flags);
+}
+
+#endif /* CONFIG_DISABLE_POSIX_TIMERS */
diff --git a/nuttx/sched/timer_internal.h b/nuttx/sched/timer_internal.h
new file mode 100644
index 000000000..71dfb59a3
--- /dev/null
+++ b/nuttx/sched/timer_internal.h
@@ -0,0 +1,102 @@
+/********************************************************************************
+ * timer_internal.h
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ********************************************************************************/
+
+#ifndef __SCHED_TIMER_INTERNAL_H
+#define __SCHED_TIMER_INTERNAL_H
+
+/********************************************************************************
+ * Included Files
+ ********************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <wdog.h>
+
+#include <nuttx/compiler.h>
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+#define PT_FLAGS_PREALLOCATED 0x01 /* Timer comes from a pool of preallocated timers */
+
+/********************************************************************************
+ * Public Types
+ ********************************************************************************/
+
+/* This structure represents one POSIX timer */
+
+struct posix_timer_s
+{
+ FAR struct posix_timer_s *flink;
+
+ uint8_t pt_flags; /* See PT_FLAGS_* definitions */
+ uint8_t pt_crefs; /* Reference count */
+ uint8_t pt_signo; /* Notification signal */
+ pid_t pt_owner; /* Creator of timer */
+ int pt_delay; /* If non-zero, used to reset repetitive timers */
+ int pt_last; /* Last value used to set watchdog */
+ WDOG_ID pt_wdog; /* The watchdog that provides the timing */
+ union sigval pt_value; /* Data passed with notification */
+};
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/* This is a list of free, preallocated timer structures */
+
+#if CONFIG_PREALLOC_TIMERS > 0
+extern volatile sq_queue_t g_freetimers;
+#endif
+
+/* This is a list of instantiated timer structures -- active and inactive. The
+ * timers are place on this list by timer_create() and removed from the list by
+ * timer_delete() or when the owning thread exits.
+ */
+
+extern volatile sq_queue_t g_alloctimers;
+
+/********************************************************************************
+ * Public Function Prototypes
+ ********************************************************************************/
+
+void weak_function timer_initialize(void);
+void weak_function timer_deleteall(pid_t pid);
+int timer_release(FAR struct posix_timer_s *timer);
+
+#endif /* __SCHED_TIMER_INTERNAL_H */
diff --git a/nuttx/sched/timer_release.c b/nuttx/sched/timer_release.c
new file mode 100644
index 000000000..ed83b5f53
--- /dev/null
+++ b/nuttx/sched/timer_release.c
@@ -0,0 +1,159 @@
+/********************************************************************************
+ * timer_release.c
+ *
+ * Copyright (C) 2008 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 <queue.h>
+#include <errno.h>
+
+#include <nuttx/kmalloc.h>
+
+#include "timer_internal.h"
+
+#ifndef CONFIG_DISABLE_POSIX_TIMERS
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: timer_free
+ *
+ * Description:
+ * Remove the timer from the allocated timer list and free it or return it to
+ * the free list (depending on whether or not the timer is one of the
+ * preallocated timers)
+ *
+ ********************************************************************************/
+
+static inline void timer_free(struct posix_timer_s *timer)
+{
+ irqstate_t flags;
+
+ /* Remove the timer from the allocated list */
+
+ flags = irqsave();
+ sq_rem((FAR sq_entry_t*)timer, (sq_queue_t*)&g_alloctimers);
+
+ /* Return it to the free list if it is one of the preallocated timers */
+
+#if CONFIG_PREALLOC_TIMERS > 0
+ if ((timer->pt_flags & PT_FLAGS_PREALLOCATED) != 0)
+ {
+ sq_addlast((FAR sq_entry_t*)timer, (FAR sq_queue_t*)&g_freetimers);
+ irqrestore(flags);
+ }
+ else
+#endif
+ {
+ /* Otherwise, return it to the heap */
+
+ irqrestore(flags);
+ sched_free(timer);
+ }
+}
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: timer_release
+ *
+ * Description:
+ * timer_release implements the heart of timer_delete. It is private to the
+ * the OS internals and differs only in that return value of 1 means that the
+ * timer was not actually deleted.
+ *
+ * Parameters:
+ * timer - The per-thread timer, previously created by the call to
+ * timer_create(), to be deleted.
+ *
+ * Return Value:
+ * If the call succeeds, timer_release() will return 0 (OK) or 1 (meaning that
+ * the timer is still valid). Otherwise, the function will return a negated errno:
+ *
+ * -EINVAL - The timer specified timerid is not valid.
+ *
+ ********************************************************************************/
+
+int timer_release(FAR struct posix_timer_s *timer)
+{
+ /* Some sanity checks */
+
+ if (!timer)
+ {
+ return -EINVAL;
+ }
+
+ /* Release one reference to timer. Don't delete the timer until the count
+ * would decrement to zero.
+ */
+
+ if (timer->pt_crefs > 1)
+ {
+ timer->pt_crefs--;
+ return 1;
+ }
+
+ /* Free the underlying watchdog instance (the timer will be canceled by the
+ * watchdog logic before it is actually deleted)
+ */
+
+ (void)wd_delete(timer->pt_wdog);
+
+ /* Release the timer structure */
+
+ timer_free(timer);
+ return OK;
+}
+
+#endif /* CONFIG_DISABLE_POSIX_TIMERS */
diff --git a/nuttx/sched/timer_settime.c b/nuttx/sched/timer_settime.c
new file mode 100644
index 000000000..1814ba898
--- /dev/null
+++ b/nuttx/sched/timer_settime.c
@@ -0,0 +1,397 @@
+/********************************************************************************
+ * sched/timer_settime.c
+ *
+ * Copyright (C) 2007-2010 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 <stdint.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+
+#include "os_internal.h"
+#include "clock_internal.h"
+#include "sig_internal.h"
+#include "timer_internal.h"
+
+#ifndef CONFIG_DISABLE_POSIX_TIMERS
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Data
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Function Prototypes
+ ********************************************************************************/
+
+static void inline timer_sigqueue(FAR struct posix_timer_s *timer);
+static void inline timer_restart(FAR struct posix_timer_s *timer, uint32_t itimer);
+static void timer_timeout(int argc, uint32_t itimer);
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: timer_sigqueue
+ *
+ * Description:
+ * This function basically reimplements sigqueue() so that the si_code can
+ * be correctly set to SI_TIMER
+ *
+ * Parameters:
+ * timer - A reference to the POSIX timer that just timed out
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * This function executes in the context of the watchod timer interrupt.
+ *
+ ********************************************************************************/
+
+static void inline timer_sigqueue(FAR struct posix_timer_s *timer)
+{
+ FAR _TCB *tcb;
+
+ /* Get the TCB of the receiving task */
+
+ tcb = sched_gettcb(timer->pt_owner);
+ if (tcb)
+ {
+ siginfo_t info;
+
+ /* Create the siginfo structure */
+
+ info.si_signo = timer->pt_signo;
+ info.si_code = SI_TIMER;
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ info.si_value = timer->pt_value;
+#else
+ info.si_value.sival_ptr = timer->pt_value.sival_ptr;
+#endif
+
+ /* Send the signal */
+
+ (void)sig_received(tcb, &info);
+ }
+}
+
+/********************************************************************************
+ * Name: timer_restart
+ *
+ * Description:
+ * If a periodic timer has been selected, then restart the watchdog.
+ *
+ * Parameters:
+ * timer - A reference to the POSIX timer that just timed out
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * This function executes in the context of the watchod timer interrupt.
+ *
+ ********************************************************************************/
+
+static void inline timer_restart(FAR struct posix_timer_s *timer, uint32_t itimer)
+{
+ /* If this is a repetitive timer, then restart the watchdog */
+
+ if (timer->pt_delay)
+ {
+ timer->pt_last = timer->pt_delay;
+ (void)wd_start(timer->pt_wdog, timer->pt_delay, (wdentry_t)timer_timeout,
+ 1, itimer);
+ }
+}
+
+/********************************************************************************
+ * Name: timer_timeout
+ *
+ * Description:
+ * This function is called if the timeout elapses before the condition is
+ * signaled.
+ *
+ * Parameters:
+ * argc - the number of arguments (should be 1)
+ * itimer - A reference to the POSIX timer that just timed out
+ * signo - The signal to use to wake up the task
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * This function executes in the context of the watchod timer interrupt.
+ *
+ ********************************************************************************/
+
+static void timer_timeout(int argc, uint32_t itimer)
+{
+#ifndef CONFIG_CAN_PASS_STRUCTS
+ /* On many small machines, pointers are encoded and cannot be simply cast from
+ * uint32_t to _TCB*. The following union works around this (see wdogparm_t).
+ */
+
+ union
+ {
+ FAR struct posix_timer_s *timer;
+ uint32_t itimer;
+ } u;
+
+ u.itimer = itimer;
+
+ /* Send the specified signal to the specified task. Increment the reference
+ * count on the timer first so that will not be deleted until after the
+ * signal handler returns.
+ */
+
+ u.timer->pt_crefs++;
+ timer_sigqueue(u.timer);
+
+ /* Release the reference. timer_release will return nonzero if the timer
+ * was not deleted.
+ */
+
+ if (timer_release(u.timer))
+ {
+ /* If this is a repetitive timer, the restart the watchdog */
+
+ timer_restart(u.timer, itimer);
+ }
+#else
+ /* (casting to uintptr_t first eliminates complaints on some architectures
+ * where the sizeof uint32_t is different from the size of a pointer).
+ */
+
+ FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)((uintptr_t)itimer);
+
+ /* Send the specified signal to the specified task. Increment the reference
+ * count on the timer first so that will not be deleted until after the
+ * signal handler returns.
+ */
+
+ timer->pt_crefs++;
+ timer_sigqueue(timer);
+
+ /* Release the reference. timer_release will return nonzero if the timer
+ * was not deleted.
+ */
+
+ if (timer_release(timer))
+ {
+ /* If this is a repetitive timer, the restart the watchdog */
+
+ timer_restart(timer, itimer);
+ }
+#endif
+}
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: timer_settime
+ *
+ * Description:
+ * The timer_settime() function sets the time until the next expiration of the
+ * timer specified by timerid from the it_value member of the value argument
+ * and arm the timer if the it_value member of value is non-zero. If the
+ * specified timer was already armed when timer_settime() is called, this call
+ * will reset the time until next expiration to the value specified. If the
+ * it_value member of value is zero, the timer will be disarmed. The effect
+ * of disarming or resetting a timer with pending expiration notifications is
+ * unspecified.
+ *
+ * If the flag TIMER_ABSTIME is not set in the argument flags, timer_settime()
+ * will behave as if the time until next expiration is set to be equal to the
+ * interval specified by the it_value member of value. That is, the timer will
+ * expire in it_value nanoseconds from when the call is made. If the flag
+ * TIMER_ABSTIME is set in the argument flags, timer_settime() will behave as
+ * if the time until next expiration is set to be equal to the difference between
+ * the absolute time specified by the it_value member of value and the current
+ * value of the clock associated with timerid. That is, the timer will expire
+ * when the clock reaches the value specified by the it_value member of value.
+ * If the specified time has already passed, the function will succeed and the
+ * expiration notification will be made.
+ *
+ * The reload value of the timer will be set to the value specified by the
+ * it_interval member of value. When a timer is armed with a non-zero
+ * it_interval, a periodic (or repetitive) timer is specified.
+ *
+ * Time values that are between two consecutive non-negative integer multiples
+ * of the resolution of the specified timer will be rounded up to the larger
+ * multiple of the resolution. Quantization error will not cause the timer to
+ * expire earlier than the rounded time value.
+ *
+ * If the argument ovalue is not NULL, the timer_settime() function will store,
+ * in the location referenced by ovalue, a value representing the previous
+ * amount of time before the timer would have expired, or zero if the timer was
+ * disarmed, together with the previous timer reload value. Timers will not
+ * expire before their scheduled time.
+ *
+ * Parameters:
+ * timerid - The pre-thread timer, previously created by the call to
+ * timer_create(), to be be set.
+ * flags - Specifie characteristics of the timer (see above)
+ * value - Specifies the timer value to set
+ * ovalue - A location in which to return the time remaining from the previous
+ * timer setting. (ignored)
+ *
+ * Return Value:
+ * If the timer_settime() succeeds, a value of 0 (OK) will be returned.
+ * If an error occurs, the value -1 (ERROR) will be returned, and errno set to
+ * indicate the error.
+ *
+ * EINVAL - The timerid argument does not correspond to an ID returned by
+ * timer_create() but not yet deleted by timer_delete().
+ * EINVAL - A value structure specified a nanosecond value less than zero or
+ * greater than or equal to 1000 million, and the it_value member of that
+ * structure did not specify zero seconds and nanoseconds.
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int timer_settime(timer_t timerid, int flags, FAR const struct itimerspec *value,
+ FAR struct itimerspec *ovalue)
+{
+ FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)timerid;
+ irqstate_t state;
+ int delay;
+ int ret = OK;
+
+ /* Some sanity checks */
+
+ if (!timer || !value)
+ {
+ errno = EINVAL;
+ return ERROR;
+ }
+
+ /* Disarm the timer (in case the timer was already armed when timer_settime()
+ * is called).
+ */
+
+ (void)wd_cancel(timer->pt_wdog);
+
+ /* If the it_value member of value is zero, the timer will not be re-armed */
+
+ if (value->it_value.tv_sec <= 0 && value->it_value.tv_nsec <= 0)
+ {
+ return OK;
+ }
+
+ /* Setup up any repititive timer */
+
+ if (value->it_interval.tv_sec > 0 || value->it_interval.tv_nsec > 0)
+ {
+ (void)clock_time2ticks(&value->it_interval, &timer->pt_delay);
+ }
+ else
+ {
+ timer->pt_delay = 0;
+ }
+
+ /* We need to disable timer interrupts through the following section so
+ * that the system timer is stable.
+ */
+
+ state = irqsave();
+
+ /* Check if abstime is selected */
+
+ if ((flags & TIMER_ABSTIME) != 0)
+ {
+#ifdef CONFIG_DISABLE_CLOCK
+ /* Absolute timing depends upon having access to clock functionality */
+
+ errno = ENOSYS;
+ return ERROR;
+#else
+ /* Calculate a delay corresponding to the absolute time in 'value'.
+ * NOTE: We have internal knowledge the clock_abstime2ticks only
+ * returns an error if clockid != CLOCK_REALTIME.
+ */
+
+ (void)clock_abstime2ticks(CLOCK_REALTIME, &value->it_value, &delay);
+#endif
+ }
+ else
+ {
+ /* Calculate a delay assuming that 'value' holds the relative time
+ * to wait. We have internal knowledge that clock_time2ticks always
+ * returns success.
+ */
+
+ (void)clock_time2ticks(&value->it_value, &delay);
+ }
+
+ /* If the time is in the past or now, then set up the next interval
+ * instead (assuming a repititive timer).
+ */
+
+ if (delay <= 0)
+ {
+ delay = timer->pt_delay;
+ }
+
+ /* Then start the watchdog */
+
+
+ if (delay > 0)
+ {
+ timer->pt_last = delay;
+ ret = wd_start(timer->pt_wdog, delay, (wdentry_t)timer_timeout,
+ 1, (uint32_t)((uintptr_t)timer));
+ }
+
+ irqrestore(state);
+ return ret;
+}
+
+#endif /* CONFIG_DISABLE_POSIX_TIMERS */
diff --git a/nuttx/sched/usleep.c b/nuttx/sched/usleep.c
new file mode 100644
index 000000000..21996d788
--- /dev/null
+++ b/nuttx/sched/usleep.c
@@ -0,0 +1,168 @@
+/****************************************************************************
+ * sched/usleep.c
+ *
+ * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include <assert.h>
+#include <errno.h>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: usleep
+ *
+ * Description:
+ * The usleep() function will cause the calling thread to be suspended
+ * from execution until either the number of real-time microseconds
+ * specified by the argument 'usec' has elapsed or a signal is delivered
+ * to the calling thread. The suspension time may be longer than requested
+ * due to the scheduling of other activity by the system.
+ *
+ * The 'usec' argument must be less than 1,000,000. If the value of
+ * 'usec' is 0, then the call has no effect.
+ *
+ * If a SIGALRM signal is generated for the calling process during
+ * execution of usleep() and if the SIGALRM signal is being ignored or
+ * blocked from delivery, it is unspecified whether usleep() returns
+ * when the SIGALRM signal is scheduled. If the signal is being blocked, it
+ * is also unspecified whether it remains pending after usleep() returns or
+ * it is discarded.
+ *
+ * If a SIGALRM signal is generated for the calling process during
+ * execution of usleep(), except as a result of a prior call to alarm(),
+ * and if the SIGALRM signal is not being ignored or blocked from delivery,
+ * it is unspecified whether that signal has any effect other than causing
+ * usleep() to return.
+ *
+ * If a signal-catching function interrupts usleep() and examines or changes
+ * either the time a SIGALRM is scheduled to be generated, the action
+ * associated with the SIGALRM signal, or whether the SIGALRM signal is
+ * blocked from delivery, the results are unspecified.
+ *
+ * If a signal-catching function interrupts usleep() and calls siglongjmp()
+ * or longjmp() to restore an environment saved prior to the usleep() call,
+ * the action associated with the SIGALRM signal and the time at which a
+ * SIGALRM signal is scheduled to be generated are unspecified. It is also
+ * unspecified whether the SIGALRM signal is blocked, unless the process'
+ * signal mask is restored as part of the environment.
+ *
+ * Implementations may place limitations on the granularity of timer values.
+ * For each interval timer, if the requested timer value requires a finer
+ * granularity than the implementation supports, the actual timer value will
+ * be rounded up to the next supported value.
+ *
+ * Interactions between usleep() and any of the following are unspecified:
+ *
+ * nanosleep(), setitimer(), timer_create(), timer_delete(), timer_getoverrun(),
+ * timer_gettime(), timer_settime(), ualarm(), sleep()
+
+ * Parameters:
+ * usec - the number of microseconds to wait.
+ *
+ * Returned Value:
+ * On successful completion, usleep() returns 0. Otherwise, it returns -1
+ * and sets errno to indicate the error.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int usleep(useconds_t usec)
+{
+ sigset_t set;
+ struct timespec ts;
+ struct siginfo value;
+ int errval;
+ int ret = 0;
+
+ if (usec)
+ {
+ /* Set up for the sleep. Using the empty set means that we are not
+ * waiting for any particualar signal. However, any unmasked signal
+ * can still awaken sigtimedwait().
+ */
+
+ (void)sigemptyset(&set);
+ ts.tv_sec = usec / 1000000;
+ ts.tv_nsec = (usec % 1000000) * 1000;
+
+ /* usleep is a simple application of sigtimedwait. */
+
+ ret = sigtimedwait(&set, &value, &ts);
+
+ /* sigtimedwait() cannot succeed. It should always return error with
+ * either (1) EAGAIN meaning that the timeout occurred, or (2) EINTR
+ * meaning that some other unblocked signal was caught.
+ */
+
+ errval = errno;
+ DEBUGASSERT(ret < 0 && (errval == EAGAIN || errval == EINTR));
+ if (errval == EAGAIN)
+ {
+ /* The timeout "error" is the normal, successful result */
+
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
diff --git a/nuttx/sched/wd_cancel.c b/nuttx/sched/wd_cancel.c
new file mode 100644
index 000000000..0bd59cf89
--- /dev/null
+++ b/nuttx/sched/wd_cancel.c
@@ -0,0 +1,165 @@
+/****************************************************************************
+ * sched/wd_cancel.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <assert.h>
+#include <wdog.h>
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "wd_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wd_cancel
+ *
+ * Description:
+ * This function cancels a currently running watchdog timer. Watchdog
+ * timers may be canceled from the interrupt level.
+ *
+ * Parameters:
+ * wdid - ID of the watchdog to cancel.
+ *
+ * Return Value:
+ * OK or ERROR
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wd_cancel (WDOG_ID wdid)
+{
+ wdog_t *curr;
+ wdog_t *prev;
+ irqstate_t saved_state;
+ int ret = ERROR;
+
+ /* Prohibit timer interactions with the timer queue until the
+ * cancellation is complete
+ */
+
+ saved_state = irqsave();
+
+ /* Make sure that the watchdog is initialed (non-NULL) and is still active */
+
+ if (wdid && wdid->active)
+ {
+ /* Search the g_wdactivelist for the target FCB. We can't use sq_rem
+ * to do this because there are additional operations that need to be
+ * done.
+ */
+
+ prev = NULL;
+ curr = (wdog_t*)g_wdactivelist.head;
+
+ while((curr) && (curr != wdid))
+ {
+ prev = curr;
+ curr = curr->next;
+ }
+
+ /* Check if the watchdog was found in the list. If not, then an OS
+ * error has occurred because the watchdog is marked active!
+ */
+
+ if (!curr)
+ {
+ PANIC(OSERR_WDOGNOTFOUND);
+ }
+ else
+ {
+ /* If there is a watchdog in the timer queue after the one that
+ * is being canceled, then it inherits the remaining ticks.
+ */
+
+ if (curr->next)
+ {
+ curr->next->lag += curr->lag;
+ }
+
+ /* Now, remove the watchdog from the timer queue */
+
+ if (prev)
+ {
+ (void)sq_remafter((FAR sq_entry_t*)prev, &g_wdactivelist);
+ }
+ else
+ {
+ (void)sq_remfirst(&g_wdactivelist);
+ }
+ wdid->next = NULL;
+
+ /* Return success */
+
+ ret = OK;
+ }
+
+ /* Mark the watchdog inactive */
+
+ wdid->active = false;
+ }
+
+ irqrestore(saved_state);
+ return ret;
+}
diff --git a/nuttx/sched/wd_create.c b/nuttx/sched/wd_create.c
new file mode 100644
index 000000000..d86171bf7
--- /dev/null
+++ b/nuttx/sched/wd_create.c
@@ -0,0 +1,109 @@
+/****************************************************************************
+ * sched/wd_create.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <wdog.h>
+#include <queue.h>
+#include <nuttx/arch.h>
+
+#include "wd_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wd_create
+ *
+ * Description:
+ * The wd_create function will create a watchdog by allocating it from the
+ * list of free watchdogs.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * Pointer to watchdog (i.e., the watchdog ID), or NULL if insufficient
+ * watchdogs are available.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+WDOG_ID wd_create (void)
+{
+ FAR wdog_t *wdog;
+ irqstate_t saved_state;
+
+ saved_state = irqsave();
+ wdog = (FAR wdog_t*)sq_remfirst(&g_wdfreelist);
+ irqrestore(saved_state);
+
+ /* Indicate that the watchdog is not actively timing */
+
+ if (wdog)
+ {
+ wdog->next = NULL;
+ wdog->active = false;
+ }
+
+ return (WDOG_ID)wdog;
+}
diff --git a/nuttx/sched/wd_delete.c b/nuttx/sched/wd_delete.c
new file mode 100644
index 000000000..16c123e13
--- /dev/null
+++ b/nuttx/sched/wd_delete.c
@@ -0,0 +1,127 @@
+/****************************************************************************
+ * sched/wd_delete.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <wdog.h>
+#include <queue.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+
+#include "wd_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wd_delete
+ *
+ * Description:
+ * The wd_delete function will deallocate a watchdog by returning it to
+ * the free pool of watchdogs. The watchdog will be removed from the timer
+ * queue if has been started.
+ *
+ * Parameters:
+ * wdId - The watchdog ID to delete. This is actually a pointer to a
+ * watchdog structure.
+ *
+ * Return Value:
+ * Returns OK or ERROR
+ *
+ * Assumptions:
+ * The caller has assured that the watchdog is no longer in use.
+ *
+ ****************************************************************************/
+
+int wd_delete(WDOG_ID wdId)
+{
+ irqstate_t saved_state;
+
+ /* Verify that a valid watchdog was provided */
+
+ if (!wdId)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ /* The following steps are atomic... the watchdog must not be active when
+ * it is being deallocated.
+ */
+
+ saved_state = irqsave();
+
+ /* Check if the watchdog has been started. */
+
+ if (wdId->active)
+ {
+ wd_cancel(wdId);
+ }
+
+ /* Put the watchdog back on the free list */
+
+ sq_addlast((FAR sq_entry_t*)wdId, &g_wdfreelist);
+ irqrestore(saved_state);
+
+ /* Return success */
+
+ return OK;
+}
diff --git a/nuttx/sched/wd_gettime.c b/nuttx/sched/wd_gettime.c
new file mode 100644
index 000000000..caa482549
--- /dev/null
+++ b/nuttx/sched/wd_gettime.c
@@ -0,0 +1,118 @@
+/********************************************************************************
+ * sched/wd_gettime.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ********************************************************************************/
+
+/********************************************************************************
+ * Included Files
+ ********************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <wdog.h>
+
+#include "os_internal.h"
+#include "wd_internal.h"
+
+/********************************************************************************
+ * Definitions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Types
+ ********************************************************************************/
+
+/********************************************************************************
+ * Global Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Variables
+ ********************************************************************************/
+
+/********************************************************************************
+ * Private Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Public Functions
+ ********************************************************************************/
+
+/********************************************************************************
+ * Name: wd_gettime
+ *
+ * Description:
+ * This function returns the time remaining before the specified watchdog
+ * expires.
+ *
+ * Parameters:
+ * wdog = watchdog ID
+ *
+ * Return Value:
+ * The time in system ticks remaining until the watchdog time expires. Zero
+ * means either that wdog is not valid or that the wdog has already expired.
+ *
+ * Assumptions:
+ *
+ ********************************************************************************/
+
+int wd_gettime(WDOG_ID wdog)
+{
+ irqstate_t flags;
+
+ /* Verify the wdog */
+
+ flags = irqsave();
+ if (wdog && wdog->active)
+ {
+ /* Traverse the watchdog list accumulating lag times until we find the wdog
+ * that we are looking for
+ */
+
+ wdog_t *curr;
+ int delay = 0;
+
+ for (curr = (wdog_t*)g_wdactivelist.head; curr; curr = curr->next)
+ {
+ delay += curr->lag;
+ if (curr == wdog)
+ {
+ irqrestore(flags);
+ return delay;
+ }
+ }
+ }
+
+ irqrestore(flags);
+ return 0;
+}
diff --git a/nuttx/sched/wd_initialize.c b/nuttx/sched/wd_initialize.c
new file mode 100644
index 000000000..db7aba502
--- /dev/null
+++ b/nuttx/sched/wd_initialize.c
@@ -0,0 +1,135 @@
+/************************************************************************
+ * sched/wd_initialize.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <queue.h>
+#include <nuttx/kmalloc.h>
+
+#include "os_internal.h"
+#include "wd_internal.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/* The g_wdfreelist data structure is a singly linked list of watchdogs
+ * available to the system for delayed function use.
+ */
+
+sq_queue_t g_wdfreelist;
+
+/* g_wdpool is a pointer to a list of pre-allocated watchdogs. The number
+ * of watchdogs in the pool is a configuration item.
+ */
+
+FAR wdog_t *g_wdpool;
+
+/* The g_wdactivelist data structure is a singly linked list ordered by
+ * watchdog expiration time. When watchdog timers expire,the functions on
+ * this linked list are removed and the function is called.
+ */
+
+sq_queue_t g_wdactivelist;
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Name: wd_initialize
+ *
+ * Description:
+ * This function initalized the watchdog data structures
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ * This function must be called early in the initialization sequence
+ * before the timer interrupt is attached and before any watchdog
+ * services are used.
+ *
+ ************************************************************************/
+
+void wd_initialize(void)
+{
+ /* Initialize the free watchdog list */
+
+ sq_init(&g_wdfreelist);
+
+ /* The g_wdfreelist must be loaded at initialization time to hold the
+ * configured number of watchdogs.
+ */
+
+ g_wdpool = (FAR wdog_t*)kmalloc(sizeof(wdog_t) * CONFIG_PREALLOC_WDOGS);
+ if (g_wdpool)
+ {
+ FAR wdog_t *wdog = g_wdpool;
+ int i;
+
+ for (i = 0; i < CONFIG_PREALLOC_WDOGS; i++)
+ {
+ sq_addlast((FAR sq_entry_t*)wdog++, &g_wdfreelist);
+ }
+ }
+
+ /* The g_wdactivelist queue must be reset at initialization time. */
+
+ sq_init(&g_wdactivelist);
+}
diff --git a/nuttx/sched/wd_internal.h b/nuttx/sched/wd_internal.h
new file mode 100644
index 000000000..e63a8bdae
--- /dev/null
+++ b/nuttx/sched/wd_internal.h
@@ -0,0 +1,119 @@
+/************************************************************************
+ * sched/d_internal.h
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+#ifndef __SCHED_WD_INTERNAL_H
+#define __SCHED_WD_INTERNAL_H
+
+/************************************************************************
+ * Included Files
+ ************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <wdog.h>
+
+#include <nuttx/compiler.h>
+
+/************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Public Type Declarations
+ ************************************************************************/
+
+/* This is the watchdog structure. The WDOG_ID is a pointer to a
+ * watchdog structure.
+ */
+
+struct wdog_s
+{
+ FAR struct wdog_s *next; /* Support for singly linked lists. */
+ wdentry_t func; /* Function to execute when delay expires */
+#ifdef CONFIG_PIC
+ FAR void *picbase; /* PIC base address */
+#endif
+ int lag; /* Timer associated with the delay */
+ bool active; /* true if the watchdog is actively timing */
+ uint8_t argc; /* The number of parameters to pass */
+ uint32_t parm[CONFIG_MAX_WDOGPARMS];
+};
+typedef struct wdog_s wdog_t;
+
+/************************************************************************
+ * Public Variables
+ ************************************************************************/
+
+/* The g_wdfreelist data structure is a singly linked list of watchdogs
+ * available to the system for delayed function use.
+ */
+
+extern sq_queue_t g_wdfreelist;
+
+/* g_wdpool is a pointer to a list of pre-allocated watchdogs. The number
+ * of watchdogs in the pool is a configuration item.
+ */
+
+extern FAR wdog_t *g_wdpool;
+
+/* The g_wdactivelist data structure is a singly linked list ordered by
+ * watchdog expiration time. When watchdog timers expire,the functions on
+ * this linked list are removed and the function is called.
+ */
+
+extern sq_queue_t g_wdactivelist;
+
+/************************************************************************
+ * Public Function Prototypes
+ ************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+EXTERN void weak_function wd_initialize(void);
+EXTERN void weak_function wd_timer(void);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SCHED_WD_INTERNAL_H */
diff --git a/nuttx/sched/wd_start.c b/nuttx/sched/wd_start.c
new file mode 100644
index 000000000..2a69d131a
--- /dev/null
+++ b/nuttx/sched/wd_start.c
@@ -0,0 +1,375 @@
+/****************************************************************************
+ * sched/wd_start.c
+ *
+ * Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <wdog.h>
+#include <unistd.h>
+#include <sched.h>
+#include <errno.h>
+
+#include <nuttx/arch.h>
+
+#include "os_internal.h"
+#include "wd_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+typedef void (*wdentry0_t)(int argc);
+#if CONFIG_MAX_WDOGPARMS > 0
+typedef void (*wdentry1_t)(int argc, uint32_t arg1);
+#endif
+#if CONFIG_MAX_WDOGPARMS > 1
+typedef void (*wdentry2_t)(int argc, uint32_t arg1, uint32_t arg2);
+#endif
+#if CONFIG_MAX_WDOGPARMS > 2
+typedef void (*wdentry3_t)(int argc, uint32_t arg1, uint32_t arg2,
+ uint32_t arg3);
+#endif
+#if CONFIG_MAX_WDOGPARMS > 3
+typedef void (*wdentry4_t)(int argc, uint32_t arg1, uint32_t arg2,
+ uint32_t arg3, uint32_t arg4);
+#endif
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wd_start
+ *
+ * Description:
+ * This function adds a watchdog to the timer queue. The specified
+ * watchdog function will be called from the interrupt level after the
+ * specified number of ticks has elapsed. Watchdog timers may be started
+ * from the interrupt level.
+ *
+ * Watchdog timers execute in the address enviroment that was in effect
+ * when wd_start() is called.
+ *
+ * Watchdog timers execute only once.
+ *
+ * To replace either the timeout delay or the function to be executed,
+ * call wd_start again with the same wdog; only the most recent wdStart()
+ * on a given watchdog ID has any effect.
+ *
+ * Parameters:
+ * wdog = watchdog ID
+ * delay = Delay count in clock ticks
+ * wdentry = function to call on timeout
+ * parm1..4 = parameters to pass to wdentry
+ *
+ * Return Value:
+ * OK or ERROR
+ *
+ * Assumptions:
+ * The watchdog routine runs in the context of the timer interrupt handler
+ * and is subject to all ISR restrictions.
+ *
+ ****************************************************************************/
+
+int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...)
+{
+ va_list ap;
+ FAR wdog_t *curr;
+ FAR wdog_t *prev;
+ FAR wdog_t *next;
+ int32_t now;
+ irqstate_t saved_state;
+ int i;
+
+ /* Verify the wdog */
+
+ if (!wdog || argc > CONFIG_MAX_WDOGPARMS || delay < 0)
+ {
+ set_errno(EINVAL);
+ return ERROR;
+ }
+
+ /* Check if the watchdog has been started. If so, stop it.
+ * NOTE: There is a race condition here... the caller may receive
+ * the watchdog between the time that wd_start is called and
+ * the critical section is established.
+ */
+
+ saved_state = irqsave();
+ if (wdog->active)
+ {
+ wd_cancel(wdog);
+ }
+
+ /* Save the data in the watchdog structure */
+
+ wdog->func = wdentry; /* Function to execute when delay expires */
+ up_getpicbase(&wdog->picbase);
+ wdog->argc = argc;
+
+ va_start(ap, argc);
+ for (i = 0; i < argc; i++)
+ {
+ wdog->parm[i] = va_arg(ap, uint32_t);
+ }
+#ifdef CONFIG_DEBUG
+ for (; i < CONFIG_MAX_WDOGPARMS; i++)
+ {
+ wdog->parm[i] = 0;
+ }
+#endif
+ va_end(ap);
+
+ /* Calculate delay+1, forcing the delay into a range that we can handle */
+
+ if (delay <= 0)
+ {
+ delay = 1;
+ }
+ else if (++delay <= 0)
+ {
+ delay--;
+ }
+
+ /* Do the easy case first -- when the watchdog timer queue is empty. */
+
+ if (g_wdactivelist.head == NULL)
+ {
+ sq_addlast((FAR sq_entry_t*)wdog,&g_wdactivelist);
+ }
+
+ /* There are other active watchdogs in the timer queue */
+
+ else
+ {
+ now = 0;
+ prev = curr = (FAR wdog_t*)g_wdactivelist.head;
+
+ /* Advance to positive time */
+
+ while ((now += curr->lag) < 0 && curr->next)
+ {
+ prev = curr;
+ curr = curr->next;
+ }
+
+ /* Advance past shorter delays */
+
+ while (now <= delay && curr->next)
+ {
+ prev = curr;
+ curr = curr->next;
+ now += curr->lag;
+ }
+
+ /* Check if the new wdog must be inserted before the curr. */
+
+ if (delay < now)
+ {
+ /* The relative delay time is smaller or equal to the current delay
+ * time, so decrement the current delay time by the new relative
+ * delay time.
+ */
+
+ delay -= (now - curr->lag);
+ curr->lag -= delay;
+
+ /* Insert the new watchdog in the list */
+
+ if (curr == (FAR wdog_t*)g_wdactivelist.head)
+ {
+ sq_addfirst((FAR sq_entry_t*)wdog, &g_wdactivelist);
+ }
+ else
+ {
+ sq_addafter((FAR sq_entry_t*)prev, (FAR sq_entry_t*)wdog,
+ &g_wdactivelist);
+ }
+ }
+
+ /* The new watchdog delay time is greater than the curr delay time,
+ * so the new wdog must be inserted after the curr. This only occurs
+ * if the wdog is to be added to the end of the list.
+ */
+
+ else
+ {
+ delay -= now;
+ if (!curr->next)
+ {
+ sq_addlast((FAR sq_entry_t*)wdog, &g_wdactivelist);
+ }
+ else
+ {
+ next = curr->next;
+ next->lag -= delay;
+ sq_addafter((FAR sq_entry_t*)curr, (FAR sq_entry_t*)wdog,
+ &g_wdactivelist);
+ }
+ }
+ }
+
+ /* Put the lag into the watchdog structure and mark it as active. */
+
+ wdog->lag = delay;
+ wdog->active = true;
+
+ irqrestore(saved_state);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: wd_timer
+ *
+ * Description:
+ * This function is called from the timer interrupt handler to determine
+ * if it is time to execute a watchdog function. If so, the watchdog
+ * function will be executed in the context of the timer interrupt handler.
+ *
+ * Parameters:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void wd_timer(void)
+{
+ FAR wdog_t *wdog;
+
+ /* Check if there are any active watchdogs to process */
+
+ if (g_wdactivelist.head)
+ {
+ /* There are. Decrement the lag counter */
+
+ --(((FAR wdog_t*)g_wdactivelist.head)->lag);
+
+ /* Check if the watchdog at the head of the list is ready to run */
+
+ if (((FAR wdog_t*)g_wdactivelist.head)->lag <= 0)
+ {
+ /* Process the watchdog at the head of the list as well as any
+ * other watchdogs that became ready to run at this time
+ */
+
+ while (g_wdactivelist.head &&
+ ((FAR wdog_t*)g_wdactivelist.head)->lag <= 0)
+ {
+ /* Remove the watchdog from the head of the list */
+
+ wdog = (FAR wdog_t*)sq_remfirst(&g_wdactivelist);
+
+ /* If there is another watchdog behind this one, update its
+ * its lag (this shouldn't be necessary).
+ */
+
+ if (g_wdactivelist.head)
+ {
+ ((FAR wdog_t*)g_wdactivelist.head)->lag += wdog->lag;
+ }
+
+ /* Indicate that the watchdog is no longer active. */
+
+ wdog->active = false;
+
+ /* Execute the watchdog function */
+
+ up_setpicbase(wdog->picbase);
+ switch (wdog->argc)
+ {
+ default:
+#ifdef CONFIG_DEBUG
+ PANIC(OSERR_INTERNAL);
+#endif
+ case 0:
+ (*((wdentry0_t)(wdog->func)))(0);
+ break;
+
+#if CONFIG_MAX_WDOGPARMS > 0
+ case 1:
+ (*((wdentry1_t)(wdog->func)))(1, wdog->parm[0]);
+ break;
+#endif
+#if CONFIG_MAX_WDOGPARMS > 1
+ case 2:
+ (*((wdentry2_t)(wdog->func)))(2,
+ wdog->parm[0], wdog->parm[1]);
+ break;
+#endif
+#if CONFIG_MAX_WDOGPARMS > 2
+ case 3:
+ (*((wdentry3_t)(wdog->func)))(3,
+ wdog->parm[0], wdog->parm[1],
+ wdog->parm[2]);
+ break;
+#endif
+#if CONFIG_MAX_WDOGPARMS > 3
+ case 4:
+ (*((wdentry4_t)(wdog->func)))(4,
+ wdog->parm[0], wdog->parm[1],
+ wdog->parm[2] ,wdog->parm[3]);
+ break;
+#endif
+ }
+ }
+ }
+ }
+}
diff --git a/nuttx/sched/work_cancel.c b/nuttx/sched/work_cancel.c
new file mode 100644
index 000000000..55df86f44
--- /dev/null
+++ b/nuttx/sched/work_cancel.c
@@ -0,0 +1,127 @@
+/****************************************************************************
+ * sched/work_cancel.c
+ *
+ * Copyright (C) 2009-2010, 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <queue.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/wqueue.h>
+
+#include "work_internal.h"
+
+#ifdef CONFIG_SCHED_WORKQUEUE
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: work_cancel
+ *
+ * Description:
+ * Cancel previously queued work. This removes work from the work queue.
+ * After work has been canceled, it may be re-queue by calling work_queue()
+ * again.
+ *
+ * Input parameters:
+ * qid - The work queue ID
+ * work - The previously queue work structure to cancel
+ *
+ * Returned Value:
+ * Zero on success, a negated errno on failure
+ *
+ ****************************************************************************/
+
+int work_cancel(int qid, FAR struct work_s *work)
+{
+ FAR struct wqueue_s *wqueue = &g_work[qid];
+ irqstate_t flags;
+
+ DEBUGASSERT(work != NULL && (unsigned)qid < NWORKERS);
+
+ /* Cancelling the work is simply a matter of removing the work structure
+ * from the work queue. This must be done with interrupts disabled because
+ * new work is typically added to the work queue from interrupt handlers.
+ */
+
+ flags = irqsave();
+ if (work->worker != NULL)
+ {
+ /* A little test of the integrity of the work queue */
+
+ DEBUGASSERT(work->dq.flink ||(FAR dq_entry_t *)work == wqueue->q.tail);
+ DEBUGASSERT(work->dq.blink ||(FAR dq_entry_t *)work == wqueue->q.head);
+
+ /* Remove the entry from the work queue and make sure that it is
+ * mark as availalbe (i.e., the worker field is nullified).
+ */
+
+ dq_rem((FAR dq_entry_t *)work, &wqueue->q);
+ work->worker = NULL;
+ }
+
+ irqrestore(flags);
+ return OK;
+}
+
+#endif /* CONFIG_SCHED_WORKQUEUE */
diff --git a/nuttx/sched/work_internal.h b/nuttx/sched/work_internal.h
new file mode 100644
index 000000000..7f6c1a937
--- /dev/null
+++ b/nuttx/sched/work_internal.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * sched/work_internal.h
+ *
+ * Copyright (C) 2009-2011 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.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_WORK_INTERNAL_H
+#define __SCHED_WORK_INTERNAL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <queue.h>
+
+#ifdef CONFIG_SCHED_WORKQUEUE
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifdef CONFIG_DISABLE_SIGNALS
+# warning "Worker thread support requires signals"
+#endif
+
+#ifdef CONFIG_SCHED_LPWORK
+# define NWORKERS 2
+#else
+# define NWORKERS 1
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/* This structure defines the state on one work queue */
+
+struct wqueue_s
+{
+ pid_t pid; /* The task ID of the worker thread */
+ struct dq_queue_s q; /* The queue of pending work */
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* The state of each work queue */
+
+extern struct wqueue_s g_work[NWORKERS];
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: work_hpthread and work_lpthread
+ *
+ * Description:
+ * These are the main worker threads that performs actions placed on the
+ * work lists. One thread also performs periodic garbage collection (that
+ * is performed by the idle thread if CONFIG_SCHED_WORKQUEUE is not defined).
+ *
+ * Input parameters:
+ * argc, argv (not used)
+ *
+ * Returned Value:
+ * Does not return
+ *
+ ****************************************************************************/
+
+int work_hpthread(int argc, char *argv[]);
+
+#ifdef CONFIG_SCHED_LPWORK
+int work_lpthread(int argc, char *argv[]);
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_SCHED_WORKQUEUE */
+#endif /* __SCHED_WORK_INTERNAL_H */
diff --git a/nuttx/sched/work_queue.c b/nuttx/sched/work_queue.c
new file mode 100644
index 000000000..075f08a4d
--- /dev/null
+++ b/nuttx/sched/work_queue.c
@@ -0,0 +1,138 @@
+/****************************************************************************
+ * sched/work_queue.c
+ *
+ * Copyright (C) 2009-2011 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 <stdint.h>
+#include <queue.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/clock.h>
+#include <nuttx/wqueue.h>
+
+#include "work_internal.h"
+
+#ifdef CONFIG_SCHED_WORKQUEUE
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: work_queue
+ *
+ * Description:
+ * Queue work to be performed at a later time. All queued work will be
+ * performed on the worker thread of of execution (not the caller's).
+ *
+ * The work structure is allocated by caller, but completely managed by
+ * the work queue logic. The caller should never modify the contents of
+ * the work queue structure; the caller should not call work_queue()
+ * again until either (1) the previous work has been performed and removed
+ * from the queue, or (2) work_cancel() has been called to cancel the work
+ * and remove it from the work queue.
+ *
+ * Input parameters:
+ * qid - The work queue ID (index)
+ * work - The work structure to queue
+ * worker - The worker callback to be invoked. The callback will invoked
+ * on the worker thread of execution.
+ * arg - The argument that will be passed to the workder callback when
+ * int is invoked.
+ * delay - Delay (in clock ticks) from the time queue until the worker
+ * is invoked. Zero means to perform the work immediately.
+ *
+ * Returned Value:
+ * Zero on success, a negated errno on failure
+ *
+ ****************************************************************************/
+
+int work_queue(int qid, FAR struct work_s *work, worker_t worker,
+ FAR void *arg, uint32_t delay)
+{
+ FAR struct wqueue_s *wqueue = &g_work[qid];
+ irqstate_t flags;
+
+ DEBUGASSERT(work != NULL && (unsigned)qid < NWORKERS);
+
+ /* First, initialize the work structure */
+
+ work->worker = worker; /* Work callback */
+ work->arg = arg; /* Callback argument */
+ work->delay = delay; /* Delay until work performed */
+
+ /* Now, time-tag that entry and put it in the work queue. This must be
+ * done with interrupts disabled. This permits this function to be called
+ * from with task logic or interrupt handlers.
+ */
+
+ flags = irqsave();
+ work->qtime = clock_systimer(); /* Time work queued */
+
+ dq_addlast((FAR dq_entry_t *)work, &wqueue->q);
+ kill(wqueue->pid, SIGWORK); /* Wake up the worker thread */
+
+ irqrestore(flags);
+ return OK;
+}
+
+#endif /* CONFIG_SCHED_WORKQUEUE */
diff --git a/nuttx/sched/work_signal.c b/nuttx/sched/work_signal.c
new file mode 100644
index 000000000..6e6838c69
--- /dev/null
+++ b/nuttx/sched/work_signal.c
@@ -0,0 +1,96 @@
+/****************************************************************************
+ * sched/work_signal.c
+ *
+ * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <signal.h>
+#include <assert.h>
+
+#include <nuttx/wqueue.h>
+
+#include "work_internal.h"
+
+#ifdef CONFIG_SCHED_WORKQUEUE
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+/****************************************************************************
+ * Name: work_signal
+ *
+ * Description:
+ * Signal the worker thread to process the work queue now. This function
+ * is used internally by the work logic but could also be used by the
+ * user to force an immediate re-assessment of pending work.
+ *
+ * Input parameters:
+ * qid - The work queue ID
+ *
+ * Returned Value:
+ * Zero on success, a negated errno on failure
+ *
+ ****************************************************************************/
+
+int work_signal(int qid)
+{
+ DEBUGASSERT((unsigned)qid < NWORKERS);
+ return kill(g_work[qid].pid, SIGWORK);
+}
+
+#endif /* CONFIG_SCHED_WORKQUEUE */
diff --git a/nuttx/sched/work_thread.c b/nuttx/sched/work_thread.c
new file mode 100644
index 000000000..abd86f771
--- /dev/null
+++ b/nuttx/sched/work_thread.c
@@ -0,0 +1,256 @@
+/****************************************************************************
+ * sched/work_thread.c
+ *
+ * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <unistd.h>
+#include <queue.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/clock.h>
+
+#include "os_internal.h"
+#include "work_internal.h"
+
+#ifdef CONFIG_SCHED_WORKQUEUE
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/* The state of each work queue */
+
+struct wqueue_s g_work[NWORKERS];
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: work_process
+ *
+ * Description:
+ * This is the logic that performs actions placed on any work list.
+ *
+ * Input parameters:
+ * wqueue - Describes the work queue to be processed
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void work_process(FAR struct wqueue_s *wqueue)
+{
+ volatile FAR struct work_s *work;
+ worker_t worker;
+ irqstate_t flags;
+ FAR void *arg;
+ uint32_t elapsed;
+ uint32_t remaining;
+ uint32_t next;
+
+ /* Then process queued work. We need to keep interrupts disabled while
+ * we process items in the work list.
+ */
+
+ next = CONFIG_SCHED_WORKPERIOD / USEC_PER_TICK;
+ flags = irqsave();
+ work = (FAR struct work_s *)wqueue->q.head;
+ while (work)
+ {
+ /* Is this work ready? It is ready if there is no delay or if
+ * the delay has elapsed. qtime is the time that the work was added
+ * to the work queue. It will always be greater than or equal to
+ * zero. Therefore a delay of zero will always execute immediately.
+ */
+
+ elapsed = clock_systimer() - work->qtime;
+ if (elapsed >= work->delay)
+ {
+ /* Remove the ready-to-execute work from the list */
+
+ (void)dq_rem((struct dq_entry_s *)work, &wqueue->q);
+
+ /* Extract the work description from the entry (in case the work
+ * instance by the re-used after it has been de-queued).
+ */
+
+ worker = work->worker;
+ arg = work->arg;
+
+ /* Mark the work as no longer being queued */
+
+ work->worker = NULL;
+
+ /* Do the work. Re-enable interrupts while the work is being
+ * performed... we don't have any idea how long that will take!
+ */
+
+ irqrestore(flags);
+ worker(arg);
+
+ /* Now, unfortunately, since we re-enabled interrupts we don't
+ * know the state of the work list and we will have to start
+ * back at the head of the list.
+ */
+
+ flags = irqsave();
+ work = (FAR struct work_s *)wqueue->q.head;
+ }
+ else
+ {
+ /* This one is not ready.. will it be ready before the next
+ * scheduled wakeup interval?
+ */
+
+ remaining = elapsed - work->delay;
+ if (remaining < next)
+ {
+ /* Yes.. Then schedule to wake up when the work is ready */
+
+ next = remaining;
+ }
+
+ /* Then try the next in the list. */
+
+ work = (FAR struct work_s *)work->dq.flink;
+ }
+ }
+
+ /* Wait awhile to check the work list. We will wait here until either
+ * the time elapses or until we are awakened by a signal.
+ */
+
+ usleep(next * USEC_PER_TICK);
+ irqrestore(flags);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+/****************************************************************************
+ * Name: work_hpthread and work_lpthread
+ *
+ * Description:
+ * These are the main worker threads that performs actions placed on the
+ * work lists. One thread also performs periodic garbage collection (that
+ * is performed by the idle thread if CONFIG_SCHED_WORKQUEUE is not defined).
+ *
+ * Input parameters:
+ * argc, argv (not used)
+ *
+ * Returned Value:
+ * Does not return
+ *
+ ****************************************************************************/
+
+int work_hpthread(int argc, char *argv[])
+{
+ /* Loop forever */
+
+ for (;;)
+ {
+ /* First, perform garbage collection. This cleans-up memory de-allocations
+ * that were queued because they could not be freed in that execution
+ * context (for example, if the memory was freed from an interrupt handler).
+ * NOTE: If the work thread is disabled, this clean-up is performed by
+ * the IDLE thread (at a very, very lower priority).
+ */
+
+#ifdef CONFIG_SCHED_LPWORK
+ sched_garbagecollection();
+#endif
+
+ /* Then process queued work. We need to keep interrupts disabled while
+ * we process items in the work list.
+ */
+
+ work_process(&g_work[HPWORK]);
+ }
+
+ return OK; /* To keep some compilers happy */
+}
+
+#ifdef CONFIG_SCHED_LPWORK
+int work_lpthread(int argc, char *argv[])
+{
+ /* Loop forever */
+
+ for (;;)
+ {
+ /* First, perform garbage collection. This cleans-up memory de-allocations
+ * that were queued because they could not be freed in that execution
+ * context (for example, if the memory was freed from an interrupt handler).
+ * NOTE: If the work thread is disabled, this clean-up is performed by
+ * the IDLE thread (at a very, very lower priority).
+ */
+
+ sched_garbagecollection();
+
+ /* Then process queued work. We need to keep interrupts disabled while
+ * we process items in the work list.
+ */
+
+ work_process(&g_work[LPWORK]);
+ }
+
+ return OK; /* To keep some compilers happy */
+}
+
+#endif /* CONFIG_SCHED_LPWORK */
+
+#endif /* CONFIG_SCHED_WORKQUEUE */