aboutsummaryrefslogtreecommitdiff
path: root/nuttx/sched
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2011-12-19 19:24:09 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2011-12-19 19:24:09 +0000
commitadd995c32e86f9de8fa8fc05172435332c25a895 (patch)
tree0191fde92a5c4dcd55a24b2aa760fa4c88713242 /nuttx/sched
downloadpx4-firmware-add995c32e86f9de8fa8fc05172435332c25a895.tar.gz
px4-firmware-add995c32e86f9de8fa8fc05172435332c25a895.tar.bz2
px4-firmware-add995c32e86f9de8fa8fc05172435332c25a895.zip
Completes coding of the PWM module
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4200 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/sched')
-rw-r--r--nuttx/sched/Makefile208
-rw-r--r--nuttx/sched/atexit.c116
-rw-r--r--nuttx/sched/clock_abstime2ticks.c128
-rw-r--r--nuttx/sched/clock_getres.c121
-rw-r--r--nuttx/sched/clock_gettime.c180
-rw-r--r--nuttx/sched/clock_gettimeofday.c111
-rw-r--r--nuttx/sched/clock_initialize.c211
-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.c131
-rw-r--r--nuttx/sched/env_dupenv.c112
-rw-r--r--nuttx/sched/env_findvar.c127
-rw-r--r--nuttx/sched/env_getenv.c136
-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.c122
-rw-r--r--nuttx/sched/env_removevar.c118
-rw-r--r--nuttx/sched/env_setenv.c208
-rw-r--r--nuttx/sched/env_share.c115
-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.c106
-rw-r--r--nuttx/sched/getpid.c84
-rw-r--r--nuttx/sched/irq_attach.c113
-rw-r--r--nuttx/sched/irq_dispatch.c105
-rw-r--r--nuttx/sched/irq_initialize.c90
-rw-r--r--nuttx/sched/irq_internal.h83
-rw-r--r--nuttx/sched/irq_unexpectedisr.c85
-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.c189
-rw-r--r--nuttx/sched/mq_descreate.c156
-rw-r--r--nuttx/sched/mq_findnamed.c104
-rw-r--r--nuttx/sched/mq_initialize.c249
-rw-r--r--nuttx/sched/mq_internal.h182
-rw-r--r--nuttx/sched/mq_msgfree.c136
-rw-r--r--nuttx/sched/mq_msgqfree.c108
-rw-r--r--nuttx/sched/mq_notify.c212
-rw-r--r--nuttx/sched/mq_open.c235
-rw-r--r--nuttx/sched/mq_rcvinternal.c313
-rw-r--r--nuttx/sched/mq_receive.c170
-rw-r--r--nuttx/sched/mq_send.c181
-rw-r--r--nuttx/sched/mq_sndinternal.c452
-rw-r--r--nuttx/sched/mq_timedreceive.c309
-rw-r--r--nuttx/sched/mq_timedsend.c320
-rw-r--r--nuttx/sched/mq_unlink.c146
-rw-r--r--nuttx/sched/mq_waitirq.c172
-rw-r--r--nuttx/sched/os_bringup.c186
-rw-r--r--nuttx/sched/os_internal.h307
-rw-r--r--nuttx/sched/os_start.c464
-rw-r--r--nuttx/sched/pg_internal.h126
-rw-r--r--nuttx/sched/pg_miss.c179
-rw-r--r--nuttx/sched/pg_worker.c675
-rw-r--r--nuttx/sched/pthread_barrierdestroy.c110
-rw-r--r--nuttx/sched/pthread_barrierinit.c121
-rw-r--r--nuttx/sched/pthread_barrierwait.c182
-rw-r--r--nuttx/sched/pthread_cancel.c147
-rw-r--r--nuttx/sched/pthread_completejoin.c231
-rw-r--r--nuttx/sched/pthread_condbroadcast.c144
-rw-r--r--nuttx/sched/pthread_conddestroy.c88
-rw-r--r--nuttx/sched/pthread_condinit.c93
-rw-r--r--nuttx/sched/pthread_condsignal.c128
-rw-r--r--nuttx/sched/pthread_condtimedwait.c308
-rw-r--r--nuttx/sched/pthread_condwait.c139
-rw-r--r--nuttx/sched/pthread_create.c434
-rw-r--r--nuttx/sched/pthread_detach.c136
-rw-r--r--nuttx/sched/pthread_exit.c133
-rw-r--r--nuttx/sched/pthread_findjoininfo.c99
-rw-r--r--nuttx/sched/pthread_getschedparam.c138
-rw-r--r--nuttx/sched/pthread_getspecific.c126
-rw-r--r--nuttx/sched/pthread_initialize.c199
-rw-r--r--nuttx/sched/pthread_internal.h136
-rw-r--r--nuttx/sched/pthread_join.c247
-rw-r--r--nuttx/sched/pthread_keycreate.c141
-rw-r--r--nuttx/sched/pthread_keydelete.c96
-rw-r--r--nuttx/sched/pthread_kill.c95
-rw-r--r--nuttx/sched/pthread_mutexdestroy.c129
-rw-r--r--nuttx/sched/pthread_mutexinit.c138
-rw-r--r--nuttx/sched/pthread_mutexlock.c183
-rw-r--r--nuttx/sched/pthread_mutextrylock.c146
-rw-r--r--nuttx/sched/pthread_mutexunlock.c164
-rw-r--r--nuttx/sched/pthread_once.c126
-rw-r--r--nuttx/sched/pthread_removejoininfo.c137
-rw-r--r--nuttx/sched/pthread_setcancelstate.c127
-rw-r--r--nuttx/sched/pthread_setschedparam.c138
-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.c120
-rw-r--r--nuttx/sched/sched_addprioritized.c175
-rw-r--r--nuttx/sched/sched_addreadytorun.c149
-rw-r--r--nuttx/sched/sched_foreach.c83
-rw-r--r--nuttx/sched/sched_free.c115
-rw-r--r--nuttx/sched/sched_garbage.c117
-rw-r--r--nuttx/sched/sched_getfiles.c76
-rw-r--r--nuttx/sched/sched_getparam.c143
-rw-r--r--nuttx/sched/sched_getscheduler.c129
-rw-r--r--nuttx/sched/sched_getsockets.c77
-rw-r--r--nuttx/sched/sched_getstreams.c76
-rw-r--r--nuttx/sched/sched_gettcb.c105
-rw-r--r--nuttx/sched/sched_lock.c110
-rw-r--r--nuttx/sched/sched_lockcount.c97
-rw-r--r--nuttx/sched/sched_mergepending.c171
-rw-r--r--nuttx/sched/sched_processtimer.c191
-rw-r--r--nuttx/sched/sched_releasefiles.c102
-rw-r--r--nuttx/sched/sched_releasetcb.c180
-rw-r--r--nuttx/sched/sched_removeblocked.c112
-rw-r--r--nuttx/sched/sched_removereadytorun.c123
-rw-r--r--nuttx/sched/sched_reprioritize.c129
-rw-r--r--nuttx/sched/sched_rrgetinterval.c155
-rw-r--r--nuttx/sched/sched_self.c83
-rw-r--r--nuttx/sched/sched_setparam.c153
-rw-r--r--nuttx/sched/sched_setpriority.c232
-rw-r--r--nuttx/sched/sched_setscheduler.c188
-rw-r--r--nuttx/sched/sched_setupidlefiles.c150
-rw-r--r--nuttx/sched/sched_setuppthreadfiles.c108
-rw-r--r--nuttx/sched/sched_setupstreams.c83
-rw-r--r--nuttx/sched/sched_setuptaskfiles.c179
-rw-r--r--nuttx/sched/sched_unlock.c128
-rw-r--r--nuttx/sched/sched_verifytcb.c86
-rw-r--r--nuttx/sched/sched_waitpid.c246
-rw-r--r--nuttx/sched/sched_yield.c101
-rw-r--r--nuttx/sched/sem_close.c139
-rw-r--r--nuttx/sched/sem_destroy.c126
-rw-r--r--nuttx/sched/sem_findnamed.c101
-rw-r--r--nuttx/sched/sem_holder.c905
-rw-r--r--nuttx/sched/sem_initialize.c101
-rw-r--r--nuttx/sched/sem_internal.h124
-rw-r--r--nuttx/sched/sem_open.c206
-rw-r--r--nuttx/sched/sem_post.c178
-rw-r--r--nuttx/sched/sem_timedwait.c286
-rw-r--r--nuttx/sched/sem_trywait.c144
-rw-r--r--nuttx/sched/sem_unlink.c138
-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.c136
-rw-r--r--nuttx/sched/sig_cleanup.c118
-rw-r--r--nuttx/sched/sig_deliver.c167
-rw-r--r--nuttx/sched/sig_findaction.c100
-rw-r--r--nuttx/sched/sig_initialize.c265
-rw-r--r--nuttx/sched/sig_internal.h191
-rw-r--r--nuttx/sched/sig_kill.c139
-rw-r--r--nuttx/sched/sig_lowest.c90
-rw-r--r--nuttx/sched/sig_mqnotempty.c128
-rw-r--r--nuttx/sched/sig_pending.c129
-rw-r--r--nuttx/sched/sig_procmask.c179
-rw-r--r--nuttx/sched/sig_queue.c161
-rw-r--r--nuttx/sched/sig_received.c403
-rw-r--r--nuttx/sched/sig_releasependingsigaction.c120
-rw-r--r--nuttx/sched/sig_releasependingsignal.c126
-rw-r--r--nuttx/sched/sig_removependingsignal.c109
-rw-r--r--nuttx/sched/sig_suspend.c177
-rw-r--r--nuttx/sched/sig_timedwait.c296
-rw-r--r--nuttx/sched/sig_unmaskpendingsignal.c138
-rw-r--r--nuttx/sched/sig_waitinfo.c89
-rw-r--r--nuttx/sched/sleep.c102
-rw-r--r--nuttx/sched/task_activate.c118
-rw-r--r--nuttx/sched/task_create.c274
-rw-r--r--nuttx/sched/task_delete.c166
-rw-r--r--nuttx/sched/task_deletecurrent.c140
-rw-r--r--nuttx/sched/task_exithook.c157
-rw-r--r--nuttx/sched/task_init.c153
-rw-r--r--nuttx/sched/task_restart.c183
-rw-r--r--nuttx/sched/task_setup.c347
-rw-r--r--nuttx/sched/task_start.c115
-rw-r--r--nuttx/sched/timer_create.c237
-rw-r--r--nuttx/sched/timer_delete.c103
-rw-r--r--nuttx/sched/timer_getoverrun.c109
-rw-r--r--nuttx/sched/timer_gettime.c121
-rw-r--r--nuttx/sched/timer_initialize.c167
-rw-r--r--nuttx/sched/timer_internal.h102
-rw-r--r--nuttx/sched/timer_release.c159
-rw-r--r--nuttx/sched/timer_settime.c395
-rw-r--r--nuttx/sched/usleep.c98
-rw-r--r--nuttx/sched/wd_cancel.c164
-rw-r--r--nuttx/sched/wd_create.c108
-rw-r--r--nuttx/sched/wd_delete.c127
-rw-r--r--nuttx/sched/wd_gettime.c118
-rw-r--r--nuttx/sched/wd_initialize.c138
-rw-r--r--nuttx/sched/wd_internal.h121
-rw-r--r--nuttx/sched/wd_start.c384
-rw-r--r--nuttx/sched/work_cancel.c116
-rw-r--r--nuttx/sched/work_internal.h112
-rw-r--r--nuttx/sched/work_queue.c131
-rw-r--r--nuttx/sched/work_thread.c215
199 files changed, 31765 insertions, 0 deletions
diff --git a/nuttx/sched/Makefile b/nuttx/sched/Makefile
new file mode 100644
index 000000000..39a526eda
--- /dev/null
+++ b/nuttx/sched/Makefile
@@ -0,0 +1,208 @@
+############################################################################
+# sched/Makefile
+#
+# Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+#
+# 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 = 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 atexit.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_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
+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..3a116f4c1
--- /dev/null
+++ b/nuttx/sched/atexit.c
@@ -0,0 +1,116 @@
+/************************************************************************
+ * sched/atexit.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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.h>
+
+#include "os_internal.h"
+
+#ifdef CONFIG_SCHED_ATEXIT
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/************************************************************************
+ * Private Type Declarations
+ ************************************************************************/
+
+/************************************************************************
+ * Global Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Variables
+ ************************************************************************/
+
+/************************************************************************
+ * Private Function Prototypes
+ ************************************************************************/
+
+/************************************************************************
+ * Private Functionss
+ ************************************************************************/
+
+/************************************************************************
+ * Public Functions
+ ************************************************************************/
+
+/************************************************************************
+ * Function: atexit
+ *
+ * Description:
+ * Registers a function to be called at program exit.
+ *
+ * Parameters:
+ * func
+ *
+ * Return Value:
+ * Zero on success. Non-zero on failure.
+ *
+ ************************************************************************/
+
+int atexit(void (*func)(void))
+{
+ _TCB *tcb = (_TCB*)g_readytorun.head;
+ int ret = ERROR;
+
+ /* The following must be atomic */
+
+ sched_lock();
+ if (func && !tcb->exitfunc)
+ {
+ tcb->exitfunc = func;
+ ret = OK;
+ }
+
+ sched_unlock();
+ return ret;
+}
+
+#endif /* CONFIG_SCHED_ATEXIT */
+
+
diff --git a/nuttx/sched/clock_abstime2ticks.c b/nuttx/sched/clock_abstime2ticks.c
new file mode 100644
index 000000000..c8be4b1b1
--- /dev/null
+++ b/nuttx/sched/clock_abstime2ticks.c
@@ -0,0 +1,128 @@
+/********************************************************************************
+ * clock_abstime2ticks.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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_getres.c b/nuttx/sched/clock_getres.c
new file mode 100644
index 000000000..467802f27
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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");
+ *get_errno_ptr() = 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..341b4bed9
--- /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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..54c44f753
--- /dev/null
+++ b/nuttx/sched/clock_gettimeofday.c
@@ -0,0 +1,111 @@
+/****************************************************************************
+ * sched/clock_gettimeofday.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..b7c5cdd9d
--- /dev/null
+++ b/nuttx/sched/clock_initialize.c
@@ -0,0 +1,211 @@
+/****************************************************************************
+ * sched/clock_initialize.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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>
+
+#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
+ **************************************************************************/
+
+/****************************************************************************
+ * Function: clock_inittime
+ *
+ * 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_inittime(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_inittime(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_inittime(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_inittime(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 */
+
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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 */
+
+ clock_inittime(&g_basetime);
+ g_system_timer = 0;
+ g_tickbias = 0;
+}
+
+/****************************************************************************
+ * Function: 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..dadf5d66a
--- /dev/null
+++ b/nuttx/sched/clock_internal.h
@@ -0,0 +1,91 @@
+/********************************************************************************
+ * clock_internal.h
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 __CLOCK_INTERNAL_H
+#define __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
+ ********************************************************************************/
+
+extern void weak_function clock_initialize(void);
+extern void weak_function clock_timer(void);
+
+extern int clock_abstime2ticks(clockid_t clockid,
+ FAR const struct timespec *abstime,
+ FAR int *ticks);
+extern int clock_time2ticks(FAR const struct timespec *reltime, FAR int *ticks);
+extern int clock_ticks2time(int ticks, FAR struct timespec *reltime);
+
+#endif /* __CLOCK_INTERNAL_H */
diff --git a/nuttx/sched/clock_settime.c b/nuttx/sched/clock_settime.c
new file mode 100644
index 000000000..aa48b4592
--- /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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..6a2a9e24e
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+
+/****************************************************************************
+ * Function: 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..fe2165d68
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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..beba5014c
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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..fa777bbf7
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..cbde5251d
--- /dev/null
+++ b/nuttx/sched/env_dup.c
@@ -0,0 +1,131 @@
+/****************************************************************************
+ * sched/env_dup.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..fd3ccd7b7
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..b789a101d
--- /dev/null
+++ b/nuttx/sched/env_findvar.c
@@ -0,0 +1,127 @@
+/****************************************************************************
+ * sched/env_findvar.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..be0a83d2e
--- /dev/null
+++ b/nuttx/sched/env_getenv.c
@@ -0,0 +1,136 @@
+/****************************************************************************
+ * env_getenv.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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:
+ *get_errno_ptr() = 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..8fad450cd
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..c96f3f708
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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..68674023a
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..d124477d5
--- /dev/null
+++ b/nuttx/sched/env_release.c
@@ -0,0 +1,122 @@
+/****************************************************************************
+ * sched/env_clearenv.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..b4890a35d
--- /dev/null
+++ b/nuttx/sched/env_removevar.c
@@ -0,0 +1,118 @@
+/****************************************************************************
+ * sched/env_removevar.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..bc1ff33b1
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..15bfcccb9
--- /dev/null
+++ b/nuttx/sched/env_share.c
@@ -0,0 +1,115 @@
+/****************************************************************************
+ * sched/env_share.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..a751661c7
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..7461a42c7
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..8daf5b2cc
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..2bf01d9b1
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..2964b5a01
--- /dev/null
+++ b/nuttx/sched/exit.c
@@ -0,0 +1,106 @@
+/****************************************************************************
+ * sched/exit.c
+ *
+ * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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.h>
+#include "os_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..158b29370
--- /dev/null
+++ b/nuttx/sched/getpid.c
@@ -0,0 +1,84 @@
+/************************************************************************
+ * sched/getpid.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..85f6b93ed
--- /dev/null
+++ b/nuttx/sched/irq_attach.c
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * sched/irq_attach.c
+ *
+ * Copyright (C) 2007-2008, 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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)
+ {
+#ifndef CONFIG_ARCH_NOINTC
+ up_disable_irq(irq);
+#endif
+ 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..4b2447cbf
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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 dispaly 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..48afa4431
--- /dev/null
+++ b/nuttx/sched/irq_initialize.c
@@ -0,0 +1,90 @@
+/****************************************************************************
+ * sched/irq_initialize.c
+ *
+ * Copyright (C) 2007-2008, 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..4d180ec12
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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 __IRQ_INTERNAL_H
+#define __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 /* __IRQ_INTERNAL_H */
+
diff --git a/nuttx/sched/irq_unexpectedisr.c b/nuttx/sched/irq_unexpectedisr.c
new file mode 100644
index 000000000..e00e534a3
--- /dev/null
+++ b/nuttx/sched/irq_unexpectedisr.c
@@ -0,0 +1,85 @@
+/****************************************************************************
+ * sched/irq_unexpectedisr.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 <debug.h>
+#include "os_internal.h"
+#include "irq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..ed923a56f
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..59a554adc
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..2e64be4bc
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..aee5306f2
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..91b3448b8
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..aba3cf26f
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..a78a0bed7
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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();
+}
+
+/************************************************************************
+ * Function: 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..4f6b0e0b5
--- /dev/null
+++ b/nuttx/sched/mq_close.c
@@ -0,0 +1,189 @@
+/************************************************************
+ * sched/mq_close.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************/
+
+/************************************************************
+ * Function: mq_desfree
+ *
+ * Description:
+ * Deallocate a message queue descriptor but returning it
+ * to the free liest
+ *
+ * Inputs:
+ * mqdes - message queue descriptor to free
+ *
+ ************************************************************/
+
+#define mq_desfree(mqdes) sq_addlast((FAR sq_entry_t*)mqdes, &g_desfree)
+
+/************************************************************
+ * Public Functions
+ ************************************************************/
+
+/************************************************************
+ * Function: 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
+ * 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..c8a0cfeae
--- /dev/null
+++ b/nuttx/sched/mq_descreate.c
@@ -0,0 +1,156 @@
+/****************************************************************************
+ * sched/mq_descreate.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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> /* va_list */
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <mqueue.h>
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+#include "os_internal.h"
+#include "sig_internal.h"
+
+#include <queue.h>
+#include <nuttx/kmalloc.h>
+#include "mq_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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:
+ *
+ *
+ ****************************************************************************/
+
+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..be3830374
--- /dev/null
+++ b/nuttx/sched/mq_findnamed.c
@@ -0,0 +1,104 @@
+/************************************************************************
+ * sched/mq_findnamed.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..2e85e148c
--- /dev/null
+++ b/nuttx/sched/mq_initialize.c
@@ -0,0 +1,249 @@
+/************************************************************************
+ * sched/mq_initialize.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: mq_msgblockalloc
+ *
+ * Description:
+ * Allocate a block of messages and place them on the free
+ * list.
+ *
+ *
+ * Inputs:
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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();
+}
+
+/************************************************************************
+ * Function: 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..c9666f683
--- /dev/null
+++ b/nuttx/sched/mq_internal.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+ * sched/mq_internal.h
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..8147dd518
--- /dev/null
+++ b/nuttx/sched/mq_msgfree.c
@@ -0,0 +1,136 @@
+/************************************************************************
+ * sched/mq_msgfree.c
+ *
+ * Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..74ba3d441
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..ce64d5a54
--- /dev/null
+++ b/nuttx/sched/mq_notify.c
@@ -0,0 +1,212 @@
+/************************************************************************
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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. One 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..de9388195
--- /dev/null
+++ b/nuttx/sched/mq_open.c
@@ -0,0 +1,235 @@
+/****************************************************************************
+ * sched/mq_open.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..744094322
--- /dev/null
+++ b/nuttx/sched/mq_rcvinternal.c
@@ -0,0 +1,313 @@
+/****************************************************************************
+ * sched/mq_rcvinternal.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 <fcntl.h> /* O_NONBLOCK */
+#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)
+ {
+ *get_errno_ptr() = EINVAL;
+ return ERROR;
+ }
+
+ if ((mqdes->oflags & O_RDOK) == 0)
+ {
+ *get_errno_ptr() = EPERM;
+ return ERROR;
+ }
+
+ if (msglen < (size_t)mqdes->msgq->maxmsgsize)
+ {
+ *get_errno_ptr() = EMSGSIZE;
+ return ERROR;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Function: 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++;
+
+ *get_errno_ptr() = 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_ptr() != OK)
+ {
+ break;
+ }
+ }
+ else
+ {
+ /* The queue was empty, and the O_NONBLOCK flag was set for the
+ * message queue description referred to by 'mqdes'.
+ */
+
+ *get_errno_ptr() = 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;
+}
+
+/****************************************************************************
+ * Function: 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..aff9e3be8
--- /dev/null
+++ b/nuttx/sched/mq_receive.c
@@ -0,0 +1,170 @@
+/************************************************************************
+ * sched/mq_receive.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..3a2284033
--- /dev/null
+++ b/nuttx/sched/mq_send.c
@@ -0,0 +1,181 @@
+/****************************************************************************
+ * sched/mq_send.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..b359f6f17
--- /dev/null
+++ b/nuttx/sched/mq_sndinternal.c
@@ -0,0 +1,452 @@
+/****************************************************************************
+ * sched/mq_send.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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;
+}
+
+/****************************************************************************
+ * Function: 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;
+}
+
+/****************************************************************************
+ * Function: 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;
+}
+
+/****************************************************************************
+ * Function: 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..856c08be5
--- /dev/null
+++ b/nuttx/sched/mq_timedreceive.c
@@ -0,0 +1,309 @@
+/****************************************************************************
+ * sched/mq_timedreceive.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..4f329d311
--- /dev/null
+++ b/nuttx/sched/mq_timedsend.c
@@ -0,0 +1,320 @@
+/****************************************************************************
+ * sched/mq_timedsend.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..0f1e63e48
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..69f09a4f1
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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/os_bringup.c b/nuttx/sched/os_bringup.c
new file mode 100644
index 000000000..eb1875a69
--- /dev/null
+++ b/nuttx/sched/os_bringup.c
@@ -0,0 +1,186 @@
+/****************************************************************************
+ * sched/os_bringup.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 "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.
+ */
+
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_USER_ENTRYPOINT)
+# define USER_ENTRYPOINT (main_t)CONFIG_USER_ENTRYPOINT
+#else
+# define USER_ENTRYPOINT user_start
+#endif
+
+/****************************************************************************
+ * 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_worker = KERNEL_THREAD("work", CONFIG_SCHED_WORKPRIORITY,
+ CONFIG_SCHED_WORKSTACKSIZE,
+ (main_t)work_thread, (const char **)NULL);
+ ASSERT(g_worker != ERROR);
+#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 USER_ENTRYPOINT() */
+
+ init_taskid = TASK_CREATE("init", SCHED_PRIORITY_DEFAULT,
+ CONFIG_USERMAIN_STACKSIZE,
+ (main_t)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..16eb176e1
--- /dev/null
+++ b/nuttx/sched/os_internal.h
@@ -0,0 +1,307 @@
+/****************************************************************************
+ * sched/os_internal.h
+ *
+ * Copyright (C) 2007-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 __OS_INTERNAL_H
+#define __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 currenly 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
+ ****************************************************************************/
+
+extern int os_bringup(void);
+extern void task_start(void);
+extern int task_schedsetup(FAR _TCB *tcb, int priority, start_t start,
+ main_t main);
+extern int task_argsetup(FAR _TCB *tcb, const char *name, const char *argv[]);
+extern void task_exithook(FAR _TCB *tcb, int status);
+extern int task_deletecurrent(void);
+#ifndef CONFIG_CUSTOM_STACK
+extern int kernel_thread(const char *name, int priority,
+ int stack_size, main_t entry, const char *argv[]);
+#else
+extern int kernel_thread(const char *name, int priority,
+ main_t entry, const char *argv[]);
+#endif
+extern bool sched_addreadytorun(FAR _TCB *rtrtcb);
+extern bool sched_removereadytorun(FAR _TCB *rtrtcb);
+extern bool sched_addprioritized(FAR _TCB *newTcb, DSEG dq_queue_t *list);
+extern bool sched_mergepending(void);
+extern void sched_addblocked(FAR _TCB *btcb, tstate_t task_state);
+extern void sched_removeblocked(FAR _TCB *btcb);
+extern int sched_setpriority(FAR _TCB *tcb, int sched_priority);
+#ifdef CONFIG_PRIORITY_INHERITANCE
+extern int sched_reprioritize(FAR _TCB *tcb, int sched_priority);
+#else
+# define sched_reprioritize(tcb,sched_priority) sched_setpriority(tcb,sched_priority)
+#endif
+extern FAR _TCB *sched_gettcb(pid_t pid);
+extern bool sched_verifytcb(FAR _TCB *tcb);
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+extern int sched_setupidlefiles(FAR _TCB *tcb);
+extern int sched_setuptaskfiles(FAR _TCB *tcb);
+extern int sched_setuppthreadfiles(FAR _TCB *tcb);
+#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
+extern int sched_setupstreams(FAR _TCB *tcb);
+extern int sched_flushfiles(FAR _TCB *tcb);
+#endif
+extern int sched_releasefiles(FAR _TCB *tcb);
+#endif
+
+extern int sched_releasetcb(FAR _TCB *tcb);
+extern void sched_garbagecollection(void);
+
+#endif /* __OS_INTERNAL_H */
diff --git a/nuttx/sched/os_start.c b/nuttx/sched/os_start.c
new file mode 100644
index 000000000..412c24ebc
--- /dev/null
+++ b/nuttx/sched/os_start.c
@@ -0,0 +1,464 @@
+/****************************************************************************
+ * sched/os_start.c
+ *
+ * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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.h>
+#include <nuttx/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 currenly 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 init task and the 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 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 init 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] = 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 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 semaphore facility. (if in link) */
+
+#ifdef CONFIG_HAVE_WEAKFUNCTIONS
+ if (sem_initialize != NULL)
+#endif
+ {
+ sem_initialize();
+ }
+
+ /* 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..6ea35eed4
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ *
+ ****************************************************************************/
+
+extern 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..7abf0e2c2
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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..c9c175b5a
--- /dev/null
+++ b/nuttx/sched/pg_worker.c
@@ -0,0 +1,675 @@
+/****************************************************************************
+ * sched/pg_worker.c
+ * Page fill worker thread implementation.
+ *
+ * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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/pthread_barrierdestroy.c b/nuttx/sched/pthread_barrierdestroy.c
new file mode 100644
index 000000000..6720b9d99
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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..1d8dd00c3
--- /dev/null
+++ b/nuttx/sched/pthread_barrierinit.c
@@ -0,0 +1,121 @@
+/********************************************************************************
+ * sched/pthread_barrieinit.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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..b8588aff0
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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_ptr();
+ 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..2ff1daf87
--- /dev/null
+++ b/nuttx/sched/pthread_cancel.c
@@ -0,0 +1,147 @@
+/**************************************************************************
+ * sched/pthread_cancel.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..fff3b46cf
--- /dev/null
+++ b/nuttx/sched/pthread_completejoin.c
@@ -0,0 +1,231 @@
+/************************************************************************
+ * sched/pthread_completejoin.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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;
+
+ sdbg("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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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;
+
+ sdbg("process_id=%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)
+ {
+
+ (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;
+}
+
+/************************************************************************
+ * Function: 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..5b69ea428
--- /dev/null
+++ b/nuttx/sched/pthread_condbroadcast.c
@@ -0,0 +1,144 @@
+/****************************************************************************
+ * sched/pthread_condbroadcast.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..dc176af77
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..f341d28fa
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..a10dda6be
--- /dev/null
+++ b/nuttx/sched/pthread_condsignal.c
@@ -0,0 +1,128 @@
+/****************************************************************************
+ * sched/pthread_condsignal.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+ {
+ 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..6c43e819c
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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_ptr() == 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..38e3ddeb9
--- /dev/null
+++ b/nuttx/sched/pthread_condwait.c
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * sched/pthread_condwait.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..d51a5956b
--- /dev/null
+++ b/nuttx/sched/pthread_create.c
@@ -0,0 +1,434 @@
+/****************************************************************************
+ * sched/pthread_create.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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;
+ }
+}
+
+/****************************************************************************
+ * Function: 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..52ea63ca5
--- /dev/null
+++ b/nuttx/sched/pthread_detach.c
@@ -0,0 +1,136 @@
+/************************************************************************
+ * sched/pthread_detach.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..c320bbb10
--- /dev/null
+++ b/nuttx/sched/pthread_exit.c
@@ -0,0 +1,133 @@
+/************************************************************************
+ * sched/pthread_exit.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 <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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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)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 becuase 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..ea8acfac3
--- /dev/null
+++ b/nuttx/sched/pthread_findjoininfo.c
@@ -0,0 +1,99 @@
+/************************************************************************
+ * pthread_findjoininfo.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..462c6c320
--- /dev/null
+++ b/nuttx/sched/pthread_getschedparam.c
@@ -0,0 +1,138 @@
+/********************************************************************************************
+ * pthread_getschedparam.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ *********************************************************************************************/
+
+/********************************************************************************************
+ * Function: 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_ptr();
+ }
+ }
+
+ 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..e0f606eaf
--- /dev/null
+++ b/nuttx/sched/pthread_getspecific.c
@@ -0,0 +1,126 @@
+/************************************************************************
+ * sched/pthread_getspecific.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..7aa4ed708
--- /dev/null
+++ b/nuttx/sched/pthread_initialize.c
@@ -0,0 +1,199 @@
+/****************************************************************************
+ * sched/pthread_initialize.c
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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);
+}
+
+/****************************************************************************
+ * Function: 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_ptr() != EINTR)
+ {
+ *get_errno_ptr() = EINVAL;
+ return ERROR;
+ }
+ }
+ return OK;
+ }
+ else
+ {
+ /* NULL semaphore pointer! */
+
+ *get_errno_ptr() = 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 */
+
+ *get_errno_ptr() = EINVAL;
+ return ERROR;
+ }
+ }
+ else
+ {
+ /* NULL semaphore pointer! */
+
+ *get_errno_ptr() = EINVAL;
+ return ERROR;
+ }
+}
+
diff --git a/nuttx/sched/pthread_internal.h b/nuttx/sched/pthread_internal.h
new file mode 100644
index 000000000..6d8961e37
--- /dev/null
+++ b/nuttx/sched/pthread_internal.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+ * sched/pthread_internal.h
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..4684b4f98
--- /dev/null
+++ b/nuttx/sched/pthread_join.c
@@ -0,0 +1,247 @@
+/****************************************************************************
+ * pthread_join.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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 a
+ * joinable thread.
+ * ESRCH No thread could be found corresponding to that
+ * specified 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..466cef84d
--- /dev/null
+++ b/nuttx/sched/pthread_keycreate.c
@@ -0,0 +1,141 @@
+/****************************************************************************
+ * sched/pthread_keycreate.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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 be
+ * returned 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..397f06267
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..171b30942
--- /dev/null
+++ b/nuttx/sched/pthread_kill.c
@@ -0,0 +1,95 @@
+/************************************************************************
+ * sched/pthread_kill.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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;
+
+ *get_errno_ptr() = EINVAL;
+ ret = kill((pid_t)thread, signo);
+ if (ret != OK)
+ {
+ ret = *get_errno_ptr();
+ }
+ return ret;
+}
+
+
diff --git a/nuttx/sched/pthread_mutexdestroy.c b/nuttx/sched/pthread_mutexdestroy.c
new file mode 100644
index 000000000..fa78fe82b
--- /dev/null
+++ b/nuttx/sched/pthread_mutexdestroy.c
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * sched/pthread_mutexdestroy.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..6004076cb
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..a56fd9d71
--- /dev/null
+++ b/nuttx/sched/pthread_mutexlock.c
@@ -0,0 +1,183 @@
+/****************************************************************************
+ * sched/pthread_mutexlock.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..24779cbf7
--- /dev/null
+++ b/nuttx/sched/pthread_mutextrylock.c
@@ -0,0 +1,146 @@
+/****************************************************************************
+ * sched/pthread_mutextrylock.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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_ptr() == 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..90ed5e537
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..dc0fcd2bd
--- /dev/null
+++ b/nuttx/sched/pthread_once.c
@@ -0,0 +1,126 @@
+/********************************************************************************
+ * sched/pthread_once.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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..3251b67fe
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..eaa754174
--- /dev/null
+++ b/nuttx/sched/pthread_setcancelstate.c
@@ -0,0 +1,127 @@
+/******************************************************************************************
+ * pthread_setcancelstate.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ******************************************************************************************/
+
+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..40e1c4918
--- /dev/null
+++ b/nuttx/sched/pthread_setschedparam.c
@@ -0,0 +1,138 @@
+/********************************************************************************************
+ * pthread_setschedparam.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Function: 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) */
+
+ *get_errno_ptr() = 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_ptr();
+ }
+ return ret;
+ }
diff --git a/nuttx/sched/pthread_setschedprio.c b/nuttx/sched/pthread_setschedprio.c
new file mode 100644
index 000000000..fc4c2d612
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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..b9f166d34
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..dac921903
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..6c7a42e20
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..9231afa49
--- /dev/null
+++ b/nuttx/sched/sched_addblocked.c
@@ -0,0 +1,120 @@
+/************************************************************************
+ * sched/sched_addblocked.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 inferreded 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..d937dcee3
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..51e219342
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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..3af74c704
--- /dev/null
+++ b/nuttx/sched/sched_foreach.c
@@ -0,0 +1,83 @@
+/************************************************************************
+ * sched/sched_foreach.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..2bdf9670e
--- /dev/null
+++ b/nuttx/sched/sched_free.c
@@ -0,0 +1,115 @@
+/************************************************************************
+ * sched/sched_free.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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();
+#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..714422bd6
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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..c8cbfe160
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..a74e4d65e
--- /dev/null
+++ b/nuttx/sched/sched_getparam.c
@@ -0,0 +1,143 @@
+/************************************************************************
+ * sched/sched_getparam.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..1515ae69c
--- /dev/null
+++ b/nuttx/sched/sched_getscheduler.c
@@ -0,0 +1,129 @@
+/************************************************************************
+ * sched/sched_getscheduler.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 process identified by pid. If
+ * pid equals zero, the policy of the calling process 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)
+ {
+ *get_errno_ptr() = 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..8a220fe4f
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..abf3d7ef2
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..39933369f
--- /dev/null
+++ b/nuttx/sched/sched_gettcb.c
@@ -0,0 +1,105 @@
+/****************************************************************************
+ * sched/sched_gettcb.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..2dd406203
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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..6ac3a9dee
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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..1448c0096
--- /dev/null
+++ b/nuttx/sched/sched_mergepending.c
@@ -0,0 +1,171 @@
+/************************************************************************
+ * sched/sched_mergepending.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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 */
+
+ 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..5c98bc45b
--- /dev/null
+++ b/nuttx/sched/sched_processtimer.c
@@ -0,0 +1,191 @@
+/************************************************************************
+ * sched/sched_processtimer.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..160b0fb42
--- /dev/null
+++ b/nuttx/sched/sched_releasefiles.c
@@ -0,0 +1,102 @@
+/****************************************************************************
+ * sched/sched_releasefiles.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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.h>
+#include <nuttx/net.h>
+#include <nuttx/lib.h>
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: sched_releasefiles
+ *
+ * Description:
+ * Release file resources attached to a TCB.
+ *
+ * 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 */
+
+ files_releaselist(tcb->filelist);
+ tcb->filelist = NULL;
+
+#if CONFIG_NFILE_STREAMS > 0
+ /* Free the stream list */
+
+ 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 */
+
+ 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..5fd509006
--- /dev/null
+++ b/nuttx/sched/sched_releasetcb.c
@@ -0,0 +1,180 @@
+/************************************************************************
+ * sched/sched_releasetcb.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..6a2194781
--- /dev/null
+++ b/nuttx/sched/sched_removeblocked.c
@@ -0,0 +1,112 @@
+/************************************************************************
+ * sched/sched_removeblocked.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 inferreded 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..46f148150
--- /dev/null
+++ b/nuttx/sched/sched_removereadytorun.c
@@ -0,0 +1,123 @@
+/****************************************************************************
+ * shced/sched_removereadytorun.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..9c40e5e3d
--- /dev/null
+++ b/nuttx/sched/sched_reprioritize.c
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * sched/sched_reprioritize.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..114f36532
--- /dev/null
+++ b/nuttx/sched/sched_rrgetinterval.c
@@ -0,0 +1,155 @@
+/************************************************************************
+ * sched/sched_rrgetinterval.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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_RR
+ * scheduling 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)
+ {
+ *get_errno_ptr() = EINVAL;
+ return ERROR;
+ }
+
+ /* Otherwise, lookup the TCB associated with this pid */
+
+ else
+ {
+ rrtcb = sched_gettcb(pid);
+ if (!rrtcb)
+ {
+ *get_errno_ptr() = ESRCH;
+ return ERROR;
+ }
+ }
+
+ if (!interval)
+ {
+ *get_errno_ptr() = 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
+ *get_errno_ptr() = ENOSYS;
+ return ERROR;
+#endif
+}
diff --git a/nuttx/sched/sched_self.c b/nuttx/sched/sched_self.c
new file mode 100644
index 000000000..99a0f1995
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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..2b0f804a6
--- /dev/null
+++ b/nuttx/sched/sched_setparam.c
@@ -0,0 +1,153 @@
+/****************************************************************************
+ * sched/sched_setparam.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..c5b7839aa
--- /dev/null
+++ b/nuttx/sched/sched_setpriority.c
@@ -0,0 +1,232 @@
+/****************************************************************************
+ * sched/sched_setpriority.c
+ *
+ * Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..2ca4849bb
--- /dev/null
+++ b/nuttx/sched/sched_setscheduler.c
@@ -0,0 +1,188 @@
+/****************************************************************************
+ * sched/sched_setscheduler.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 SCHED_FIFO;
+ }
+}
+
diff --git a/nuttx/sched/sched_setupidlefiles.c b/nuttx/sched/sched_setupidlefiles.c
new file mode 100644
index 000000000..683a00c7a
--- /dev/null
+++ b/nuttx/sched/sched_setupidlefiles.c
@@ -0,0 +1,150 @@
+/****************************************************************************
+ * sched/sched_setupidlefiles.c
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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.h>
+#include <nuttx/net.h>
+
+#include "os_internal.h"
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+ /* Allocate file descriptors for the TCB */
+
+ tcb->filelist = files_alloclist();
+ if (!tcb->filelist)
+ {
+ return -ENOMEM;
+ }
+#endif /* CONFIG_NFILE_DESCRIPTORS */
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+ /* Allocate socket descriptors for the TCB */
+
+ tcb->sockets = net_alloclist();
+ if (!tcb->sockets)
+ {
+ return -ENOMEM;
+ }
+#endif /* CONFIG_NSOCKET_DESCRIPTORS */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_DEV_CONSOLE)
+ /* Open stdin, dup to get stdout and stderr. This should always
+ * be the first file opened and, hence, should always get file
+ * descriptor 0.
+ */
+
+ 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;
+ }
+
+#if CONFIG_NFILE_STREAMS > 0
+ /* Allocate file strems for the TCB */
+
+ return sched_setupstreams(tcb);
+#else
+ return OK;
+#endif /* CONFIG_NFILE_STREAMS */
+#else
+ return OK;
+#endif /* CONFIG_NFILE_DESCRIPTORS && CONFIG_DEV_CONSOLE */
+}
+
+#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..a28a042c0
--- /dev/null
+++ b/nuttx/sched/sched_setuppthreadfiles.c
@@ -0,0 +1,108 @@
+/****************************************************************************
+ * sched_setuppthreadfiles.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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.h>
+#include <nuttx/net.h>
+#include <nuttx/lib.h>
+
+#include "os_internal.h"
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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);
+
+#if CONFIG_NFILE_STREAMS > 0
+ /* The child thread inherits the parent streams */
+
+ tcb->streams = rtcb->streams;
+ lib_addreflist(tcb->streams);
+
+#endif /* CONFIG_NFILE_STREAMS */
+#endif /* CONFIG_NFILE_DESCRIPTORS */
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+ /* The child thread inherits the parent file descriptors */
+
+ tcb->sockets = rtcb->sockets;
+ net_addreflist(tcb->sockets);
+
+#endif /* CONFIG_NSOCKET_DESCRIPTORS */
+
+ 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..a30a9259d
--- /dev/null
+++ b/nuttx/sched/sched_setupstreams.c
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * sched_setupstreams.c
+ *
+ * Copyright (C) 2007-2008, 2010-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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.h>
+#include <nuttx/net.h>
+#include <nuttx/lib.h>
+
+#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int sched_setupstreams(FAR _TCB *tcb)
+{
+ /* Allocate file strems 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 && CONFIG_NFILE_STREAMS */
diff --git a/nuttx/sched/sched_setuptaskfiles.c b/nuttx/sched/sched_setuptaskfiles.c
new file mode 100644
index 000000000..95c571b47
--- /dev/null
+++ b/nuttx/sched/sched_setuptaskfiles.c
@@ -0,0 +1,179 @@
+/****************************************************************************
+ * sched/sched_setuptaskfiles.c
+ *
+ * Copyright (C) 2007-2008, 2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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.h>
+#include <nuttx/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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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)
+{
+#if CONFIG_NFILE_DESCRIPTORS > 0
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ int i;
+#endif /* CONFIG_NFILE_DESCRIPTORS > 0 */
+ int ret = OK;
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+
+ /* Allocate file descriptors for the TCB */
+
+ tcb->filelist = files_alloclist();
+ if (!tcb->filelist)
+ {
+ return -ENOMEM;
+ }
+
+#endif /* CONFIG_NFILE_DESCRIPTORS */
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0
+
+ /* Allocate socket descriptors for the TCB */
+
+ tcb->sockets = net_alloclist();
+ if (!tcb->sockets)
+ {
+ return -ENOMEM;
+ }
+
+#endif /* CONFIG_NSOCKET_DESCRIPTORS */
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+#if !defined(CONFIG_FDCLONE_DISABLE)
+
+ /* 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)
+ {
+ for (i = 0; i < NFDS_TOCLONE; i++)
+ {
+ /* Check if this file is opened */
+
+ if (rtcb->filelist->fl_files[i].f_inode)
+ {
+ (void)files_dup(&rtcb->filelist->fl_files[i],
+ &tcb->filelist->fl_files[i]);
+ }
+ }
+ }
+#endif
+
+#if CONFIG_NFILE_STREAMS > 0
+
+ /* Allocate file streams for the TCB */
+
+ ret = sched_setupstreams(tcb);
+
+#endif /* CONFIG_NFILE_STREAMS */
+#endif /* CONFIG_NFILE_DESCRIPTORS */
+
+#if CONFIG_NSOCKET_DESCRIPTORS > 0 && !defined(CONFIG_SDCLONE_DISABLE)
+
+ /* Duplicate the socket descriptors */
+
+ if (rtcb->sockets)
+ {
+ for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; i++)
+ {
+ /* Check if this socket is allocated */
+
+ if (rtcb->sockets->sl_sockets[i].s_crefs > 0)
+ {
+ (void)net_clone(&rtcb->sockets->sl_sockets[i],
+ &tcb->sockets->sl_sockets[i]);
+ }
+ }
+ }
+#endif
+ return ret;
+}
+
+#endif /* CONFIG_NFILE_DESCRIPTORS || CONFIG_NSOCKET_DESCRIPTORS */
diff --git a/nuttx/sched/sched_unlock.c b/nuttx/sched/sched_unlock.c
new file mode 100644
index 000000000..302aea6b7
--- /dev/null
+++ b/nuttx/sched/sched_unlock.c
@@ -0,0 +1,128 @@
+/************************************************************************
+ * sched/sched_unlock.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..af7cdebe1
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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..a1af343e1
--- /dev/null
+++ b/nuttx/sched/sched_waitpid.c
@@ -0,0 +1,246 @@
+/*****************************************************************************
+ * sched/sched_waitpid.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Function: 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 = sched_gettcb(pid);
+ bool mystat;
+ int err;
+ int ret;
+
+ /* Disable pre-emption so that nothing changes in the following tests */
+
+ sched_lock();
+ 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:
+ 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..a7af4c787
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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..279e42737
--- /dev/null
+++ b/nuttx/sched/sem_close.c
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * sched/sem_close.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..95db46468
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..3d73038b5
--- /dev/null
+++ b/nuttx/sched/sem_findnamed.c
@@ -0,0 +1,101 @@
+/************************************************************************
+ * sem_findnamed.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..2dfc50ee6
--- /dev/null
+++ b/nuttx/sched/sem_holder.c
@@ -0,0 +1,905 @@
+/****************************************************************************
+ * sched/sem_holder.c
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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 (!sem->hlist.holder)
+ {
+ pholder = &sem->hlist;
+ pholder->counts = 0;
+ }
+ else
+ {
+#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->hlist.flink;
+ sem->hlist.flink = pholder;
+
+ /* Make sure the initial count is zero */
+
+ pholder->counts = 0;
+ }
+ else
+#else
+ pholder = NULL;
+#endif
+ sdbg("Insufficient pre-allocated holders\n");
+ }
+ return pholder;
+}
+
+/****************************************************************************
+ * Function: 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 */
+
+ pholder = &sem->hlist;
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ for (; pholder; pholder = pholder->flink)
+#endif
+ {
+ if (pholder->holder == htcb)
+ {
+ /* Got it! */
+
+ return pholder;
+ }
+ }
+
+ /* The holder does not appear in the list */
+
+ return NULL;
+}
+
+/****************************************************************************
+ * Function: 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;
+}
+
+/****************************************************************************
+ * Function: 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->holder = 0;
+ pholder->counts = 0;
+
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ /* If this is the holder inside the semaphore, then do nothing more */
+
+ if (pholder != &sem->hlist)
+ {
+ /* Otherwise, search the list for the matching holder */
+
+ for (prev = &sem->hlist, curr = sem->hlist.flink;
+ curr && curr != pholder;
+ prev = curr, curr = curr->flink);
+
+ if (curr)
+ {
+ /* Remove the holder from the list */
+
+ prev->flink = 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 = &sem->hlist;
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ FAR struct semholder_s *next;
+#endif
+ int ret = 0;
+
+#if CONFIG_SEM_PREALLOCHOLDERS > 0
+ for (; pholder && ret == 0; pholder = next)
+#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->holder)
+ {
+ /* 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->holder;
+ FAR _TCB *rtcb = (FAR _TCB*)arg;
+
+ /* Make sure that the 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 has already been boosted, then add the
+ * boost priority to the list of restoration priorities. When the
+ * higher priority thread gets its count, then we need to revert
+ * to this saved priority, not to the base priority.
+ */
+
+ if (htcb->sched_priority > htcb->base_priority)
+ {
+ /* Save the current, boosted priority */
+
+ 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 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);
+ }
+ 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)
+{
+// REMOVE ME
+#if 0 // Need to revisit this, but these assumptions seem to be untrue -- OR there is a bug???
+ FAR _TCB *htcb = (FAR _TCB *)pholder->holder;
+
+ /* 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->holder, pholder->counts);
+#else
+ dbg(" %08x: %08x %04x\n", pholder, pholder->holder, 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->holder;
+#if CONFIG_SEM_NNESTPRIO > 0
+ FAR _TCB *stcb = (FAR _TCB *)arg;
+ int rpriority;
+ int i;
+ int j;
+#endif
+
+ /* Make sure that the 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 this thread boosted? If so, then drop its priority
+ * back to 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 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 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 thread has been boosted to the same priority as the task
+ * that just received the count. We will simply reprioritized
+ * 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 thread has been boosted to a higher priority than the task. The
+ * pending priority should be in he list (unless it was lost because of
+ * of list overflow).
+ *
+ * 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
+ * all the way back to the threads "base" priority.
+ */
+
+ sched_reprioritize(htcb, htcb->base_priority);
+#endif
+ }
+ return 0;
+}
+
+/****************************************************************************
+ * Name: sem_restoreholderprioA & B
+ ****************************************************************************/
+
+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->holder != rtcb)
+ {
+ return sem_restoreholderprio(pholder, sem, arg);
+ }
+ return 0;
+}
+
+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->holder == rtcb)
+ {
+ (void)sem_restoreholderprio(pholder, sem, arg);
+ return 1;
+ }
+ return 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+}
+
+/****************************************************************************
+ * Function: 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 is a semaphore is destroyed while there are any holders
+ * (except perhaps the thread releas 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->hlist.holder || sem->hlist.flink)
+ {
+ sdbg("Semaphore destroyed with holders\n");
+ (void)sem_foreachholder(sem, sem_recoverholders, NULL);
+ }
+#else
+ if (sem->hlist.holder)
+ {
+ sdbg("Semaphore destroyed with holder\n");
+ }
+ sem->hlist.holder = NULL;
+#endif
+}
+
+/****************************************************************************
+ * Function: 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->holder = rtcb;
+ pholder->counts++;
+ }
+}
+
+/****************************************************************************
+ * Function: 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);
+}
+
+/****************************************************************************
+ * Function: 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--;
+ }
+}
+
+/****************************************************************************
+ * Function: sem_restorebaseprio
+ *
+ * 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:
+ * 0 (OK) or -1 (ERROR) if unsuccessful
+ *
+ * Assumptions:
+ * The scheduler is locked.
+ *
+ ****************************************************************************/
+
+void sem_restorebaseprio(FAR _TCB *stcb, FAR sem_t *sem)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ FAR struct semholder_s *pholder;
+
+ /* Check our assumptions */
+
+ DEBUGASSERT((sem->semcount > 0 && stcb == NULL) ||
+ (sem->semcount <= 0 && stcb != NULL));
+
+ /* Perfom the following actions only if a new thread was given a count. */
+
+ if (stcb)
+ {
+ /* The currently executed thread should be the low 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 execuing 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);
+ }
+ }
+}
+
+/****************************************************************************
+ * Function: 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
+
+/****************************************************************************
+ * Function: 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
+
+/****************************************************************************
+ * Function: 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..a355571fd
--- /dev/null
+++ b/nuttx/sched/sem_initialize.c
@@ -0,0 +1,101 @@
+/****************************************************************************
+ * schec/sem_initialize.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..b67e506bf
--- /dev/null
+++ b/nuttx/sched/sem_internal.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+ * sched/sem_internal.h
+ *
+ * Copyright (C) 2007, 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+
+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);
+
+#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..cd9ca6129
--- /dev/null
+++ b/nuttx/sched/sem_open.c
@@ -0,0 +1,206 @@
+/****************************************************************************
+ * sched/sem_open.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..b29cdfb15
--- /dev/null
+++ b/nuttx/sched/sem_post.c
@@ -0,0 +1,178 @@
+/****************************************************************************
+ * sched/sem_post.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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++;
+
+ /* If the result of of semaphore unlock is non-positive, then
+ * there must be some task waiting for the semaphore.
+ */
+
+#ifdef CONFIG_PRIORITY_INHERITANCE
+ /* Don't let it run until we complete the priority restoration
+ * steps.
+ */
+
+ sched_lock();
+#endif
+ 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..5a1b943a5
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..d50dc106d
--- /dev/null
+++ b/nuttx/sched/sem_trywait.c
@@ -0,0 +1,144 @@
+/****************************************************************************
+ * sched/sem_trywait.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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. */
+
+ *get_errno_ptr() = 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.
+ */
+
+ *get_errno_ptr() = 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..ec0864180
--- /dev/null
+++ b/nuttx/sched/sem_unlink.c
@@ -0,0 +1,138 @@
+/****************************************************************************
+ * sched/sem_unlink.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..e36de438d
--- /dev/null
+++ b/nuttx/sched/sem_wait.c
@@ -0,0 +1,216 @@
+/****************************************************************************
+ * sched/sem_wait.c
+ *
+ * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..409cf780a
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..cc4ea263b
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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;
+}
+
+/****************************************************************************
+ * Function: 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..3294a0ab8
--- /dev/null
+++ b/nuttx/sched/sig_allocatependingsigaction.c
@@ -0,0 +1,136 @@
+/************************************************************************
+ * sched/sig_allocatependingsigaction.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..7fb0d1a9c
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..2244ca2fe
--- /dev/null
+++ b/nuttx/sched/sig_deliver.c
@@ -0,0 +1,167 @@
+/****************************************************************************
+ * sched/sig_deliver.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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)
+{
+ pid_t rpid;
+ 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);
+
+ /* The current tasks process.ID. We'll need this later to see if
+ * the signal handler caused a context switch.
+ */
+
+ rpid = getpid();
+
+ /* 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..6c9d7386f
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..4c225350a
--- /dev/null
+++ b/nuttx/sched/sig_initialize.c
@@ -0,0 +1,265 @@
+/************************************************************************
+ * sched/sig_initialize.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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;
+}
+
+/************************************************************************
+ * Function: 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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);
+}
+
+/************************************************************************
+ * Function: 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..877400b1b
--- /dev/null
+++ b/nuttx/sched/sig_internal.h
@@ -0,0 +1,191 @@
+/****************************************************************************
+ * sched/sig_internal.h
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 __SIG_INTERNAL_H
+#define __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 functin 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 */
+
+extern void weak_function sig_initialize(void);
+extern void sig_allocateactionblock(void);
+
+/* sig_action.c */
+
+extern void sig_releaseaction(FAR sigactq_t *sigact);
+
+/* sig_pending.c */
+
+extern sigset_t sig_pendingset(FAR _TCB *stcb);
+
+/* In files of the same name */
+
+extern FAR sigq_t *sig_allocatependingsigaction(void);
+extern void sig_cleanup(FAR _TCB *stcb);
+extern void sig_deliver(FAR _TCB *stcb);
+extern FAR sigactq_t *sig_findaction(FAR _TCB *stcb, int signo);
+extern int sig_lowest(sigset_t *set);
+#ifdef CONFIG_CAN_PASS_STRUCTS
+extern int sig_mqnotempty(int tid, int signo, union sigval value);
+#else
+extern int sig_mqnotempty(int tid, int signo,
+ void *sival_ptr);
+#endif
+extern int sig_received(FAR _TCB *stcb, siginfo_t *info);
+extern void sig_releasependingsigaction(FAR sigq_t *sigq);
+extern void sig_releasependingsignal(FAR sigpendq_t *sigpend);
+extern FAR sigpendq_t *sig_removependingsignal(FAR _TCB *stcb, int signo);
+extern void sig_unmaskpendingsignal(void);
+
+#endif /* __SIG_INTERNAL_H */
diff --git a/nuttx/sched/sig_kill.c b/nuttx/sched/sig_kill.c
new file mode 100644
index 000000000..5e9125088
--- /dev/null
+++ b/nuttx/sched/sig_kill.c
@@ -0,0 +1,139 @@
+/************************************************************************
+ * sched/sig_kill.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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.
+ *
+ *
+ * Return 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..cb009a706
--- /dev/null
+++ b/nuttx/sched/sig_lowest.c
@@ -0,0 +1,90 @@
+/************************************************************************
+ * sched/sig_lowest.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: sig_lowest
+ *
+ * Description:
+ *
+ ************************************************************************/
+
+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..a9f05e28b
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..1c6021050
--- /dev/null
+++ b/nuttx/sched/sig_pending.c
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * sched/sig_pending.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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;
+}
+
+/****************************************************************************
+ * Function: 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..00ef53904
--- /dev/null
+++ b/nuttx/sched/sig_procmask.c
@@ -0,0 +1,179 @@
+/****************************************************************************
+ * sched/sig_procmask.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..3bb35c564
--- /dev/null
+++ b/nuttx/sched/sig_queue.c
@@ -0,0 +1,161 @@
+/****************************************************************************
+ * sched/sig_queue.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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))
+ {
+ *get_errno_ptr() = 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)
+ {
+ *get_errno_ptr() = 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..26727dfbc
--- /dev/null
+++ b/nuttx/sched/sig_received.c
@@ -0,0 +1,403 @@
+/************************************************************************
+ * sched/sig_received.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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;
+}
+
+/************************************************************************
+ * Function: 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;
+}
+
+/************************************************************************
+ * Function: 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;
+}
+
+/************************************************************************
+ * Function: 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..f486bf708
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..4059b9bbe
--- /dev/null
+++ b/nuttx/sched/sig_releasependingsignal.c
@@ -0,0 +1,126 @@
+/************************************************************************
+ * sched/sig_releasependingsignal.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..37c829dfe
--- /dev/null
+++ b/nuttx/sched/sig_removependingsignal.c
@@ -0,0 +1,109 @@
+/************************************************************************
+ * sched/sig_removependingsignal.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..4b6190266
--- /dev/null
+++ b/nuttx/sched/sig_suspend.c
@@ -0,0 +1,177 @@
+/****************************************************************************
+ * sched/sig_suspend.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..2d9afaab1
--- /dev/null
+++ b/nuttx/sched/sig_timedwait.c
@@ -0,0 +1,296 @@
+/****************************************************************************
+ * sched/sig_timedwait.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 <nuttx/arch.h>
+#include "os_internal.h"
+#include "sig_internal.h"
+#include "clock_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functionss
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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 = ERROR;
+ u.wtcb->sigunbinfo.si_code = SI_TIMER;
+ u.wtcb->sigunbinfo.si_value.sival_int = 0;
+ up_unblock_task(u.wtcb);
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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.
+ *
+ * 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. Return the signal
+ * info to the caller if so requested
+ */
+
+ if (info)
+ {
+ memcpy(info, &rtcb->sigunbinfo, sizeof(struct siginfo));
+
+ /* The return value is the number of the signal that awakened us */
+
+ ret = info->si_signo;
+ }
+ else
+ {
+ /* We don't know which signal awakened us. This is probably a bug. */
+
+ ret = 0;
+ }
+ 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..27b405b5b
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..50f06a136
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..bf586acd9
--- /dev/null
+++ b/nuttx/sched/sleep.c
@@ -0,0 +1,102 @@
+/****************************************************************************
+ * sched/sleep.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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>
+
+/****************************************************************************
+ * Preprocessor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: sleep
+ *
+ * Description:
+ * As typically declared in unistd.h. sleep() is a simple application of
+ * sigtimedwait.
+ *
+ * Parameters:
+ * seconds
+ *
+ * Returned Value:
+ * Zero if the requested time has elapsed, or the number of seconds left
+ * to sleep.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+unsigned int sleep(unsigned int seconds)
+{
+ sigset_t set;
+ struct timespec ts;
+ struct siginfo value;
+
+ if (seconds)
+ {
+ (void)sigemptyset(&set);
+ ts.tv_sec = seconds;
+ ts.tv_nsec = 0;
+ (void)sigtimedwait(&set, &value, &ts);
+ }
+
+ return 0;
+}
diff --git a/nuttx/sched/task_activate.c b/nuttx/sched/task_activate.c
new file mode 100644
index 000000000..8e4b8b080
--- /dev/null
+++ b/nuttx/sched/task_activate.c
@@ -0,0 +1,118 @@
+/****************************************************************************
+ * sched/task_activate.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..23478c810
--- /dev/null
+++ b/nuttx/sched/task_create.c
@@ -0,0 +1,274 @@
+/****************************************************************************
+ * sched/task_create.c
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..51b3e30da
--- /dev/null
+++ b/nuttx/sched/task_delete.c
@@ -0,0 +1,166 @@
+/****************************************************************************
+ * sched/task_delete.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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().
+ *
+ * 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);
+ }
+
+ /* 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();
+
+ /* Perform common task termination logic (flushing streams, calling
+ * functions registered by at_exit/on_exit, etc.). I suppose EXIT_SUCCESS
+ * is an appropriate return value???
+ */
+
+ task_exithook(dtcb, EXIT_SUCCESS);
+
+ /* 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..0945282c4
--- /dev/null
+++ b/nuttx/sched/task_deletecurrent.c
@@ -0,0 +1,140 @@
+/****************************************************************************
+ * sched/task_deletecurrent.c
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..9567f48a9
--- /dev/null
+++ b/nuttx/sched/task_exithook.c
@@ -0,0 +1,157 @@
+/****************************************************************************
+ * sched/task_exithook.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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.h>
+
+#include "os_internal.h"
+#include "sig_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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)
+{
+ /* Inform the instrumentation layer that the task has stopped */
+
+ sched_note_stop(tcb);
+
+ /* Flush all streams (File descriptors will be closed when
+ * the TCB is deallocated).
+ */
+
+#if CONFIG_NFILE_STREAMS > 0
+ (void)lib_flushall(tcb->streams);
+#endif
+
+ /* Deallocate anything left in the TCB's queues */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ sig_cleanup(tcb); /* Deallocate Signal lists */
+#endif
+
+ /* Wakeup any tasks waiting for this task to exit */
+
+#ifdef CONFIG_SCHED_WAITPID /* Experimental */
+ 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);
+ }
+#endif
+
+ /* If an exit function was registered, call it now. NOTE: In the case
+ * of task_delete(), the exit function will *not* be called on the thread
+ * execution of the task being deleted!
+ */
+
+#ifdef CONFIG_SCHED_ATEXIT
+ if (tcb->exitfunc)
+ {
+ (*tcb->exitfunc)();
+ }
+#endif
+}
diff --git a/nuttx/sched/task_init.c b/nuttx/sched/task_init.c
new file mode 100644
index 000000000..98b12fb5c
--- /dev/null
+++ b/nuttx/sched/task_init.c
@@ -0,0 +1,153 @@
+/****************************************************************************
+ * sched/task_init.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..1cd575a4e
--- /dev/null
+++ b/nuttx/sched/task_restart.c
@@ -0,0 +1,183 @@
+/****************************************************************************
+ * sched/task_restart.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 task priority */
+
+ tcb->sched_priority = tcb->init_priority;
+#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..9fdbf3d25
--- /dev/null
+++ b/nuttx/sched/task_setup.c
@@ -0,0 +1,347 @@
+/****************************************************************************
+ * sched/task_setup.c
+ *
+ * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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;
+}
+
+/****************************************************************************
+ * Function: 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..5d1e74180
--- /dev/null
+++ b/nuttx/sched/task_start.c
@@ -0,0 +1,115 @@
+/****************************************************************************
+ * sched/task_start.c
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..b1ad142c7
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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..e89dd15a1
--- /dev/null
+++ b/nuttx/sched/timer_delete.c
@@ -0,0 +1,103 @@
+/********************************************************************************
+ * timer_delete.c
+ *
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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)
+ {
+ *get_errno_ptr() = -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..6f8c87672
--- /dev/null
+++ b/nuttx/sched/timer_getoverrun.c
@@ -0,0 +1,109 @@
+/********************************************************************************
+ * timer_getoverrun.c
+ *
+ * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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..49c65ddf8
--- /dev/null
+++ b/nuttx/sched/timer_gettime.c
@@ -0,0 +1,121 @@
+/********************************************************************************
+ * timer_gettime.c
+ *
+ * Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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)
+ {
+ *get_errno_ptr() = 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..10856d800
--- /dev/null
+++ b/nuttx/sched/timer_initialize.c
@@ -0,0 +1,167 @@
+/********************************************************************************
+ * timer_initialize.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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);
+}
+
+/********************************************************************************
+ * Function: 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..1b6daffec
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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 __TIMER_INTERNAL_H
+#define __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
+ ********************************************************************************/
+
+extern void weak_function timer_initialize(void);
+extern void weak_function timer_deleteall(pid_t pid);
+extern int timer_release(FAR struct posix_timer_s *timer);
+
+#endif /* __TIMER_INTERNAL_H */
diff --git a/nuttx/sched/timer_release.c b/nuttx/sched/timer_release.c
new file mode 100644
index 000000000..83f86954b
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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..035852315
--- /dev/null
+++ b/nuttx/sched/timer_settime.c
@@ -0,0 +1,395 @@
+/********************************************************************************
+ * sched/timer_settime.c
+ *
+ * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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);
+ }
+}
+
+/********************************************************************************
+ * Function: 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);
+ }
+}
+
+/********************************************************************************
+ * Function: 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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..2751628eb
--- /dev/null
+++ b/nuttx/sched/usleep.c
@@ -0,0 +1,98 @@
+/****************************************************************************
+ * sched/usleep.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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>
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: usleep
+ *
+ * Description:
+ * BSD version as typically declared in unistd.h. usleep() is a simple
+ * application of sigtimedwait.
+ *
+ * Parameters:
+ * seconds
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+void usleep(useconds_t usec)
+{
+ sigset_t set;
+ struct timespec ts;
+ struct siginfo value;
+
+ if (usec)
+ {
+ (void)sigemptyset(&set);
+ ts.tv_sec = usec / 1000000;
+ ts.tv_nsec = (usec % 1000000) * 1000;
+ (void)sigtimedwait(&set, &value, &ts);
+ }
+}
diff --git a/nuttx/sched/wd_cancel.c b/nuttx/sched/wd_cancel.c
new file mode 100644
index 000000000..ea686cf92
--- /dev/null
+++ b/nuttx/sched/wd_cancel.c
@@ -0,0 +1,164 @@
+/****************************************************************************
+ * sched/wd_cancel.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..a383de6a5
--- /dev/null
+++ b/nuttx/sched/wd_create.c
@@ -0,0 +1,108 @@
+/****************************************************************************
+ * sched/wd_create.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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..3f39bf723
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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)
+ {
+ *get_errno_ptr() = 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..0d5a3a470
--- /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 <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ********************************************************************************/
+
+/********************************************************************************
+ * Function: 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..8553582e0
--- /dev/null
+++ b/nuttx/sched/wd_initialize.c
@@ -0,0 +1,138 @@
+/************************************************************************
+ * sched/wd_initialize.c
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ************************************************************************/
+
+/************************************************************************
+ * Function: 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..4df2a0e65
--- /dev/null
+++ b/nuttx/sched/wd_internal.h
@@ -0,0 +1,121 @@
+/************************************************************************
+ * sched/d_internal.h
+ *
+ * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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..1f37dbf99
--- /dev/null
+++ b/nuttx/sched/wd_start.c
@@ -0,0 +1,384 @@
+/****************************************************************************
+ * sched/wd_start.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: 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)
+ {
+ *get_errno_ptr() = 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;
+}
+
+/****************************************************************************
+ * Function: 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)
+{
+ pid_t pid;
+ 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;
+
+ /* Get the current task's process ID. We'll need this later to
+ * see if the watchdog function caused a context switch.
+ */
+
+ pid = getpid();
+
+ /* 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..f110eb4cc
--- /dev/null
+++ b/nuttx/sched/work_cancel.c
@@ -0,0 +1,116 @@
+/****************************************************************************
+ * sched/work_cancel.c
+ *
+ * Copyright (C) 2009-2010 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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:
+ * work - The previously queue work structure to cancel
+ *
+ * Returned Value:
+ * Zero on success, a negated errno on failure
+ *
+ ****************************************************************************/
+
+int work_cancel(struct work_s *work)
+{
+ irqstate_t flags;
+
+ DEBUGASSERT(work != NULL);
+
+ /* 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)
+ {
+ DEBUGASSERT(work->dq.flink || (FAR dq_entry_t *)work == g_work.head);
+ DEBUGASSERT(work->dq.blink || (FAR dq_entry_t *)work == g_work.tail);
+ dq_rem((FAR dq_entry_t *)work, &g_work);
+
+ 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..56f5e5d56
--- /dev/null
+++ b/nuttx/sched/work_internal.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+ * sched/work_internal.h
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 ************************************************************/
+
+#ifndef CONFIG_SCHED_WORKPRIORITY
+# define CONFIG_SCHED_WORKPRIORITY 50
+#endif
+
+#ifndef CONFIG_SCHED_WORKPERIOD
+# define CONFIG_SCHED_WORKPERIOD (50*1000) /* 50 milliseconds */
+#endif
+
+#ifndef CONFIG_SCHED_WORKSTACKSIZE
+# define CONFIG_SCHED_WORKSTACKSIZE CONFIG_IDLETHREAD_STACKSIZE
+#endif
+
+#ifdef CONFIG_DISABLE_SIGNALS
+# warning "Worker thread support requires signals"
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* The queue of pending work */
+
+extern struct dq_queue_s g_work;
+
+/* The task ID of the worker thread */
+
+extern pid_t g_worker;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: work_thread
+ *
+ * Description:
+ * This is the main worker thread that performs actions placed on the work
+ * queue. It 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
+ *
+ ****************************************************************************/
+
+extern int work_thread(int argc, char *argv[]);
+
+#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..4b0380643
--- /dev/null
+++ b/nuttx/sched/work_queue.c
@@ -0,0 +1,131 @@
+/****************************************************************************
+ * sched/work_queue.c
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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:
+ * 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(struct work_s *work, worker_t worker, FAR void *arg, uint32_t delay)
+{
+ irqstate_t flags;
+
+ DEBUGASSERT(work != NULL);
+
+ /* 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, &g_work);
+ work_signal(); /* Wake up the worker thread */
+ irqrestore(flags);
+ return OK;
+}
+#endif /* CONFIG_SCHED_WORKQUEUE */
diff --git a/nuttx/sched/work_thread.c b/nuttx/sched/work_thread.c
new file mode 100644
index 000000000..a0e0d78e9
--- /dev/null
+++ b/nuttx/sched/work_thread.c
@@ -0,0 +1,215 @@
+/****************************************************************************
+ * sched/work_thread.c
+ *
+ * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 queue of pending work */
+
+struct dq_queue_s g_work;
+
+/* The task ID of the worker thread */
+
+#ifdef CONFIG_SCHED_WORKQUEUE
+pid_t g_worker;
+#endif
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+/****************************************************************************
+ * Name: work_thread
+ *
+ * Description:
+ * This is the main worker thread that performs actions placed on the work
+ * list. It 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_thread(int argc, char *argv[])
+{
+ volatile FAR struct work_s *work;
+ worker_t worker;
+ FAR void *arg;
+ uint32_t elapsed;
+ uint32_t remaining;
+ uint32_t next;
+ int usec;
+ irqstate_t flags;
+
+ /* Loop forever */
+
+ usec = CONFIG_SCHED_WORKPERIOD;
+ flags = irqsave();
+ for (;;)
+ {
+ /* 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(usec);
+ irqrestore(flags);
+
+ /* 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.
+ */
+
+ next = CONFIG_SCHED_WORKPERIOD / USEC_PER_TICK;
+ flags = irqsave();
+ work = (FAR struct work_s *)g_work.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, &g_work);
+
+ /* 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 *)g_work.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;
+ }
+ }
+
+ /* Now calculate the microsecond delay we should wait */
+
+ usec = next * USEC_PER_TICK;
+ }
+
+ return OK; /* To keep some compilers happy */
+}
+#endif /* CONFIG_SCHED_WORKQUEUE */