diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-02-17 23:21:28 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-02-17 23:21:28 +0000 |
commit | e3940eb2080711edac189cca3f642ee89dc215f2 (patch) | |
tree | 1c390958fae49e34dce698b175487e6d4681e540 /nuttx/sched | |
parent | 2223612deb2cc6322992f8595b6d6f86fcb53ae1 (diff) | |
download | px4-nuttx-e3940eb2080711edac189cca3f642ee89dc215f2.tar.gz px4-nuttx-e3940eb2080711edac189cca3f642ee89dc215f2.tar.bz2 px4-nuttx-e3940eb2080711edac189cca3f642ee89dc215f2.zip |
NuttX RTOS
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/sched')
157 files changed, 22193 insertions, 0 deletions
diff --git a/nuttx/sched/Makefile b/nuttx/sched/Makefile new file mode 100644 index 000000000..ebc27785d --- /dev/null +++ b/nuttx/sched/Makefile @@ -0,0 +1,130 @@ +############################################################ +# Makefile +# +# 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 Gregory Nutt nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (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 + +MKDEP = $(TOPDIR)/tools/mkdeps.sh + +ASRCS = +AOBJS = $(ASRCS:.S=.o) + +MISC_SRCS = os_start.c get_errno_ptr.c \ + sched_setupstreams.c sched_getfiles.c sched_getstreams.c \ + sched_setupidlefiles.c sched_setuptaskfiles.c sched_setuppthreadfiles.c \ + sched_releasefiles.c +TSK_SRCS = task_create.c task_delete.c task_restart.c \ + exit.c abort.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_releasetcb.c +SCHED_SRCS = sched_setparam.c sched_getparam.c \ + sched_setscheduler.c sched_getscheduler.c \ + sched_yield.c sched_rrgetinterval.c \ + sched_getprioritymax.c sched_getprioritymin.c \ + sched_lock.c sched_unlock.c sched_lockcount.c +WDOG_SRCS = wd_initialize.c wd_create.c wd_start.c wd_cancel.c wd_delete.c +TIME_SRCS = sched_processtimer.c clock_initialize.c mktime.c gmtime_r.c \ + clock_settime.c clock_gettime.c clock_getres.c sleep.c usleep.c +SIGNAL_SRCS = sig_initialize.c \ + sig_action.c sig_procmask.c sig_pending.c sig_suspend.c \ + sig_queue.c sig_waitinfo.c sig_timedwait.c \ + sig_emptyset.c sig_fillset.c sig_addset.c sig_delset.c \ + sig_ismember.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_receive.c \ + mq_notify.c mq_setattr.c mq_getattr.c \ + mq_initialize.c mq_descreate.c mq_findnamed.c \ + mq_msgfree.c mq_msgqfree.c +PTHREAD_SRCS = pthread_attrinit.c pthread_attrdestroy.c \ + pthread_attrsetschedpolicy.c pthread_attrgetschedpolicy.c \ + pthread_attrsetinheritsched.c pthread_attrgetinheritsched.c \ + pthread_attrsetstacksize.c pthread_attrgetstacksize.c \ + pthread_attrsetschedparam.c pthread_attrgetschedparam.c \ + pthread_create.c pthread_exit.c pthread_join.c pthread_detach.c \ + pthread_yield.c pthread_self.c \ + pthread_getschedparam.c pthread_setschedparam.c \ + pthread_mutexattrinit.c pthread_mutexattrdestroy.c \ + pthread_mutexattrgetpshared.c pthread_mutexattrsetpshared.c \ + pthread_mutexinit.c pthread_mutexdestroy.c \ + pthread_mutexlock.c pthread_mutextrylock.c pthread_mutexunlock.c \ + pthread_condinit.c pthread_conddestroy.c \ + pthread_condattrinit.c pthread_condattrdestroy.c \ + pthread_condwait.c pthread_condtimedwait.c \ + pthread_condsignal.c pthread_condbroadcast.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 +SEM_SRCS = sem_initialize.c sem_init.c sem_destroy.c\ + sem_open.c sem_close.c sem_unlink.c \ + sem_wait.c sem_trywait.c sem_post.c sem_getvalue.c \ + sem_waitirq.c sem_findnamed.c +IRQ_SRCS = irq_initialize.c irq_attach.c irq_dispatch.c irq_unexpectedisr.c +CSRCS = $(MISC_SRCS) $(TSK_SRCS) $(SCHED_SRCS) $(WDOG_SRCS) $(TIME_SRCS) \ + $(SIGNAL_SRCS) $(MQUEUE_SRCS) $(PTHREAD_SRCS) $(SEM_SRCS) $(IRQ_SRCS) +COBJS = $(CSRCS:.c=.o) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +BIN = libsched.a + +all: $(BIN) + +$(AOBJS): %.o: %.S + $(CC) -c $(CFLAGS) -D__ASSEMBLY__ $< -o $@ + +$(COBJS): %.o: %.c + $(CC) -c $(CFLAGS) $< -o $@ + +$(BIN): $(OBJS) + $(AR) rcs $@ $(OBJS) + +.depend: Makefile $(SRCS) + $(MKDEP) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep + touch $@ + +depend: .depend + +clean: + rm -f $(BIN) *.o *~ + +distclean: clean + rm -f Make.dep .depend + +-include Make.dep diff --git a/nuttx/sched/abort.c b/nuttx/sched/abort.c new file mode 100644 index 000000000..7c077a967 --- /dev/null +++ b/nuttx/sched/abort.c @@ -0,0 +1,81 @@ +/************************************************************ + * abort.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <stdlib.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/************************************************************ + * Private Functionss + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: abort + * + * Description: + * The abort() function causes abnormal program termination. + * All open streams are closed and flushed. + ************************************************************/ + +void abort(void) +{ + exit(EXIT_FAILURE); +} diff --git a/nuttx/sched/atexit.c b/nuttx/sched/atexit.c new file mode 100644 index 000000000..9feb4ce9a --- /dev/null +++ b/nuttx/sched/atexit.c @@ -0,0 +1,103 @@ +/************************************************************ + * atexit.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <stdlib.h> +#include <assert.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 Functionss + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: atexit + * + * Description: + * Registers a function to be called at program exit. + * + * Parameters: + * func + * + * Return Value: + * zero on success. + * + ************************************************************/ + +int atexit(void (*func)(void)) +{ + _TCB *tcb = (_TCB*)g_readytorun.head; + int ret = ERROR; + + if ((func) && (!tcb->exitfunc)) + { + tcb->exitfunc = func; + ret = OK; + } + return ret; +} + diff --git a/nuttx/sched/clock_getres.c b/nuttx/sched/clock_getres.c new file mode 100644 index 000000000..5cf07f249 --- /dev/null +++ b/nuttx/sched/clock_getres.c @@ -0,0 +1,119 @@ +/************************************************************ + * clock_getres.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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 time_res; + int ret = OK; + + dbg("%s: clock_id=%d\n", __FUNCTION__, clock_id); + + /* Only CLOCK_REALTIME is supported */ + + if (clock_id != CLOCK_REALTIME) + { + dbg("%s: Returning ERROR\n", __FUNCTION__); + *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; + + dbg("%s: Returning res=(%d,%d) time_res=%d\n", + __FUNCTION__, + (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..ac9270975 --- /dev/null +++ b/nuttx/sched/clock_gettime.c @@ -0,0 +1,148 @@ +/************************************************************ + * clock_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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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_gettime + * + * Description: + * Clock Functions based on POSIX APIs + * + ************************************************************/ + +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + uint32 msecs; + uint32 secs; + uint32 nsecs; + int ret = OK; + + dbg("%s: clock_id=%d\n", __FUNCTION__, clock_id); + + /* Only CLOCK_REALTIME is supported */ + + if (clock_id != CLOCK_REALTIME) + { + dbg("%s: Returning ERROR\n", __FUNCTION__); + + *get_errno_ptr() = EINVAL; + ret = ERROR; + } + else + { + /* Get the elapsed time since power up (in milliseconds) biased + * as appropriate. + */ + + msecs = MSEC_PER_TICK * (g_system_timer - g_tickbias); + + dbg("%s: msecs = %d g_tickbias=%d\n", __FUNCTION__, + (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; + + dbg("%s: secs = %d + %d nsecs = %d + %d\n", __FUNCTION__, + (int)msecs, (int)g_basetime.tv_sec, + (int)nsecs, (int)g_basetime.tv_nsec); + + /* Add the base time to this. */ + + secs += (uint32)g_basetime.tv_sec; + nsecs += (uint32)g_basetime.tv_nsec; + + /* Handle carry to seconds. */ + + if (nsecs > NSEC_PER_SEC) + { + uint32 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; + + dbg("%s: Returning tp=(%d,%d)\n", __FUNCTION__, + (int)tp->tv_sec, (int)tp->tv_nsec); + } + + return ret; +} diff --git a/nuttx/sched/clock_initialize.c b/nuttx/sched/clock_initialize.c new file mode 100644 index 000000000..7b63a6521 --- /dev/null +++ b/nuttx/sched/clock_initialize.c @@ -0,0 +1,128 @@ +/************************************************************ + * clock_initialize.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <time.h> +#include <errno.h> +#include <debug.h> +#include "clock_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/********************************************************** + * Public Constant Data + **********************************************************/ + +/************************************************************ + * Public Variables + ************************************************************/ + +volatile uint32 g_system_timer = 0; +struct timespec g_basetime = {0,0}; +uint32 g_tickbias = 0; + +/********************************************************** + * Private Variables + **********************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: clock_initialize + * + * Description: + * Perform one-time initialization of the timing facilities. + * + ************************************************************/ + +void clock_initialize(void) +{ + time_t jdn; + + /* Initialize the real time close */ + + g_system_timer = 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. */ + + g_basetime.tv_sec = jdn * (24*60*60); + g_basetime.tv_nsec = 0; + + /* These is no time bias from this time. */ + + 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) +{ + g_system_timer++; +} diff --git a/nuttx/sched/clock_internal.h b/nuttx/sched/clock_internal.h new file mode 100644 index 000000000..18806d952 --- /dev/null +++ b/nuttx/sched/clock_internal.h @@ -0,0 +1,101 @@ +/************************************************************ + * clock_internal.h + * + * 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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (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 <sys/types.h> +#include <nuttx/compiler.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/* Timing constants */ + +#define NSEC_PER_SEC 1000000000 +#define USEC_PER_SEC 1000000 +#define MSEC_PER_SEC 1000 +#define NSEC_PER_MSEC 1000000 +#define USEC_PER_MSEC 1000 +#define NSEC_PER_USEC 1000 + +#define MSEC_PER_TICK 10 +#define USEC_PER_TICK (MSEC_PER_TICK * USEC_PER_MSEC) +#define NSEC_PER_TICK (MSEC_PER_TICK * NSEC_PER_MSEC) +#define TICK_PER_SEC (MSEC_PER_SEC / MSEC_PER_TICK) + +#define MSEC2TICK(msec) (((msec)+(MSEC_PER_TICK/2))/MSEC_PER_TICK) +#define USEC2TICK(usec) (((usec)+(USEC_PER_TICK/2))/USEC_PER_TICK) + +#define JD_OF_EPOCH 2440588 /* Julian Date of noon, J1970 */ + +#ifdef CONFIG_JULIAN_TIME +# define GREG_DUTC -141427 /* Default is October 15, 1582 */ +# define GREG_YEAR 1582 +# define GREG_MONTH 10 +# define GREG_DAY 15 +#endif /* CONFIG_JULIAN_TIME */ + +/************************************************************ + * Public Type Definitions + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +extern volatile uint32 g_system_timer; +extern struct timespec g_basetime; +extern uint32 g_tickbias; + +/************************************************************ + * Public Inline Functions + ************************************************************/ + +/************************************************************ + * Public Function Prototypes + ************************************************************/ + +extern void weak_function clock_initialize(void); +extern void weak_function clock_timer(void); + +extern time_t clock_calendar2utc(int year, int month, int day); + +#endif /* __CLOCK_INTERNAL_H */ diff --git a/nuttx/sched/clock_settime.c b/nuttx/sched/clock_settime.c new file mode 100644 index 000000000..c57fb2808 --- /dev/null +++ b/nuttx/sched/clock_settime.c @@ -0,0 +1,119 @@ +/************************************************************ + * clock_settime.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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_settime + * + * Description: + * Clock Functions based on POSIX APIs + * + ************************************************************/ + +int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + int ret = OK; + + dbg("%s: clock_id=%d\n", __FUNCTION__, clock_id); + + /* Only CLOCK_REALTIME is supported */ + + if (clock_id != CLOCK_REALTIME || !tp) + { + dbg("%s: Returning ERROR\n", __FUNCTION__); + *get_errno_ptr() = EINVAL; + ret = ERROR; + } + else + { + /* Save the new base time. */ + + g_basetime = *tp; + + /* Get the elapsed time since power up (in milliseconds) biased + * as appropriate. + */ + + g_tickbias = g_system_timer; + + dbg("%s: basetime=(%d,%d) tickbias=%d\n", + __FUNCTION__, + (int)g_basetime.tv_sec, (int)g_basetime.tv_nsec, + (int)g_tickbias); + } + + return ret; +} diff --git a/nuttx/sched/exit.c b/nuttx/sched/exit.c new file mode 100644 index 000000000..e71ed68e8 --- /dev/null +++ b/nuttx/sched/exit.c @@ -0,0 +1,112 @@ +/************************************************************ + * exit.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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 Functionss + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: exit + * + * Description: + * The exit() function causes normal process termination + * and the value of status & 0377 is 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. Files created + * by tmpfile() are removed. + * + ************************************************************/ + +void exit(int status) +{ + _TCB *tcb = (_TCB*)g_readytorun.head; + + /* Flush all streams (File descriptors will be closed when + * the TCB is deallocated. + */ + +#if CONFIG_NFILE_STREAMS > 0 + lib_flushall(tcb->streams); +#endif + + /* If an exit function was registered, call it now. */ + + if (tcb->exitfunc) { + + (*tcb->exitfunc)(); + + } /* end if */ + + _exit(status & 0377); +} diff --git a/nuttx/sched/get_errno_ptr.c b/nuttx/sched/get_errno_ptr.c new file mode 100644 index 000000000..c9f0d52c8 --- /dev/null +++ b/nuttx/sched/get_errno_ptr.c @@ -0,0 +1,70 @@ +/************************************************************ + * get_errno_ptr.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <errno.h> +#include "os_internal.h" + +/************************************************************ + * Global 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: + * + ************************************************************/ + +int *get_errno_ptr(void) +{ + _TCB *ptcb = (_TCB*)g_readytorun.head; + return &ptcb->errno; +} + + diff --git a/nuttx/sched/getpid.c b/nuttx/sched/getpid.c new file mode 100644 index 000000000..a68ce896a --- /dev/null +++ b/nuttx/sched/getpid.c @@ -0,0 +1,84 @@ +/************************************************************ + * getpid.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 ((_TCB*)g_readytorun.head)->pid; +} diff --git a/nuttx/sched/gmtime_r.c b/nuttx/sched/gmtime_r.c new file mode 100644 index 000000000..8661d73b7 --- /dev/null +++ b/nuttx/sched/gmtime_r.c @@ -0,0 +1,215 @@ +/************************************************************ + * gmtime_r.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <time.h> +#include <errno.h> +#include <debug.h> +#include "clock_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/* Calendar/UTC conversion routines */ + +static void clock_utc2calendar(time_t utc, int *year, int *month, int *day); +static void clock_utc2gregorian (time_t jdn, int *year, int *month, int *day); + +#ifdef CONFIG_JULIAN_TIME +static void clock_utc2julian(time_t jdn, int *year, int *month, int *day); +#endif /* CONFIG_JULIAN_TIME */ + +/********************************************************** + * Public Constant Data + **********************************************************/ + +/************************************************************ + * Public Variables + ************************************************************/ + +/********************************************************** + * Private Variables + **********************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Function: clock_calendar2utc, clock_gregorian2utc, + * and clock_julian2utc + * + * Description: + * Calendar to UTC conversion routines. These conversions + * are based on algorithms from p. 604 of Seidelman, P. K. + * 1992. Explanatory Supplement to the Astronomical + * Almanac. University Science Books, Mill Valley. + * + ************************************************************/ + +static void clock_utc2calendar(time_t utc, int *year, int *month, int *day) +{ +#ifdef CONFIG_JULIAN_TIME + + if (utc >= GREG_DUTC) + { + clock_utc2gregorian(utc + JD_OF_EPOCH, year, month, day); + } + else + { + clock_utc2julian (utc + JD_OF_EPOCH, year, month, day); + } + +#else /* CONFIG_JULIAN_TIME */ + + clock_utc2gregorian(utc + JD_OF_EPOCH, year, month, day); + +#endif /* CONFIG_JULIAN_TIME */ +} + +static void clock_utc2gregorian(time_t jd, int *year, int *month, int *day) +{ + long l, n, i, j, d, m, y; + + l = jd + 68569; + n = (4*l) / 146097; + l = l - (146097*n + 3)/4; + i = (4000*(l+1))/1461001; + l = l - (1461*i)/4 + 31; + j = (80*l)/2447; + d = l - (2447*j)/80; + l = j/11; + m = j + 2 - 12*l; + y = 100*(n-49) + i + l; + + *year = y; + *month = m; + *day = d; +} + + +#ifdef CONFIG_JULIAN_TIME +static void clock_utc2julian(time_t jd, int *year, int *month, int *day) +{ + long j, k, l, n, d, i, m, y; + + j = jd + 1402; + k = (j-1)/1461; + l = j - 1461*k; + n = (l-1)/365 - l/1461; + i = l - 365*n + 30; + j = (80*i)/2447; + d = i - (2447*j)/80; + i = j/11; + m = j + 2 - 12*i; + y = 4*k + n + i - 4716; + + *year = y; + *month = m; + *day = d; +} +#endif /* CONFIG_JULIAN_TIME */ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: gmtime_r + * + * Description: + * Time conversion (based on the POSIX API) + * + ************************************************************/ + +struct tm *gmtime_r(const time_t *clock, struct tm *result) +{ + time_t time; + time_t jdn; + int year, month, day; + int hour, min, sec; + + /* Get the seconds since the EPOCH */ + + time = *clock; + dbg("%s: clock=%d\n", __FUNCTION__, (int)time); + + /* Convert to days, hours, minutes, and seconds since the EPOCH */ + + jdn = time / (24*60*60); + time -= (24*60*60) * jdn; + + hour = time / (60*60); + time -= (60*60) * hour; + + min = time / 60; + time -= 60 * min; + + sec = time; + + dbg("%s: hour=%d min=%d sec=%d\n", __FUNCTION__, + (int)hour, (int)min, (int)sec); + + /* Convert the days since the EPOCH to calendar day */ + + clock_utc2calendar(jdn, &year, &month, &day); + + dbg("%s: jdn=%d year=%d month=%d day=%d\n", __FUNCTION__, + (int)jdn, (int)year, (int)month, (int)day); + + /* Then return the struct tm contents */ + + result->tm_year = (int)year - 1900; + result->tm_mon = (int)month - 1; + result->tm_mday = (int)day; + result->tm_hour = (int)hour; + result->tm_min = (int)min; + result->tm_sec = (int)sec; + + return result; +} diff --git a/nuttx/sched/irq_attach.c b/nuttx/sched/irq_attach.c new file mode 100644 index 000000000..2c669071d --- /dev/null +++ b/nuttx/sched/irq_attach.c @@ -0,0 +1,107 @@ +/************************************************************ + * irq_attach.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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) +{ + int ret = ERROR; + + if ((unsigned)irq < NR_IRQS) + { + int 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) + { + up_disable_irq(irq); + isr = irq_unexpected_isr; + } + + /* Save the new ISR in the table. */ + + g_irqvector[irq] = isr; + irqrestore(state); + ret = OK; + } + + return ret; +} + + diff --git a/nuttx/sched/irq_dispatch.c b/nuttx/sched/irq_dispatch.c new file mode 100644 index 000000000..f783b2f54 --- /dev/null +++ b/nuttx/sched/irq_dispatch.c @@ -0,0 +1,98 @@ +/************************************************************ + * irq_dispatch.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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, struct xcptcontext *xcp) +{ + xcpt_t vector; + + /* Perform some sanity checks */ + + if ((unsigned)irq >= NR_IRQS || g_irqvector[irq] == NULL) + { + vector = irq_unexpected_isr; + } + else + { + vector = g_irqvector[irq]; + } + + /* Then dispatch to the interrupt handler */ + + vector(irq, xcp); +} + diff --git a/nuttx/sched/irq_initialize.c b/nuttx/sched/irq_initialize.c new file mode 100644 index 000000000..b213a5b09 --- /dev/null +++ b/nuttx/sched/irq_initialize.c @@ -0,0 +1,90 @@ +/************************************************************ + * irq_initialize.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <nuttx/arch.h> +#include <nuttx/irq.h> +#include "irq_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +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..a11120f55 --- /dev/null +++ b/nuttx/sched/irq_internal.h @@ -0,0 +1,82 @@ +/************************************************************ + * irq_internal.h + * + * 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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (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 <sys/types.h> +#include <nuttx/arch.h> +#include <nuttx/irq.h> +#include <nuttx/compiler.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Public Type Declarations + ************************************************************/ + +extern 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, struct xcptcontext *xcp); + +#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..c235c53a8 --- /dev/null +++ b/nuttx/sched/irq_unexpectedisr.c @@ -0,0 +1,83 @@ +/************************************************************ + * irq_unexpectedisr.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <nuttx/irq.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, struct xcptcontext *xcp) +{ + (void)irqsave(); + PANIC(OSERR_UNEXPECTEDISR); + return 0; +} diff --git a/nuttx/sched/mktime.c b/nuttx/sched/mktime.c new file mode 100644 index 000000000..9c8496463 --- /dev/null +++ b/nuttx/sched/mktime.c @@ -0,0 +1,211 @@ +/************************************************************ + * mktime.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <time.h> +#include <debug.h> +#include "clock_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/********************************************************** + * Public Constant Data + **********************************************************/ + +/************************************************************ + * Public Variables + ************************************************************/ + +/********************************************************** + * Private Variables + **********************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Function: clock_gregorian2utc, clock_julian2utc + * + * Description: + * UTC conversion routines. These conversions are based + * on algorithms from p. 604 of Seidelman, P. K. 1992. + * Explanatory Supplement to the Astronomical Almanac. + * University Science Books, Mill Valley. + * + ************************************************************/ + +static inline time_t clock_gregorian2utc(int year, int month, int day) +{ + int temp; + + /* temp = (month - 14)/12; */ + + temp = (month <= 2 ? -1:0); + + return (1461*(year + 4800 + temp))/4 + + (367*(month - 2 - 12*temp))/12 + - (3*((year + 4900 + temp)/100))/4 + day - 32075; +} + +#ifdef CONFIG_JULIAN_TIME +static inline time_t clock_julian2utc(int year, int month, int day) +{ + return 367*year + - (7*(year + 5001 + (month-9)/7))/4 + + (275*month)/9 + + day + 1729777; +} +#endif + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: mktime + * + * Description: + * Time conversion (based on the POSIX API) + * + ************************************************************/ + +time_t mktime(struct tm *tp) +{ + time_t ret; + time_t jdn; + + /* Get the EPOCH-relative julian date from the calendar year, + * month, and date + */ + + jdn = clock_calendar2utc(tp->tm_year+1900, tp->tm_mon+1, tp->tm_mday); + dbg("%s: jdn=%d tm_year=%d tm_mon=%d tm_mday=%d\n", + __FUNCTION__, (int)jdn, tp->tm_year, tp->tm_mon, tp->tm_mday); + + /* Return the seconds into the julian day. */ + + ret = ((jdn*24 + tp->tm_hour)*60 + tp->tm_min)*60 + tp->tm_sec; + dbg("%s:\tret=%d tm_hour=%d tm_min=%d tm_sec=%d\n", + __FUNCTION__, (int)ret, tp->tm_hour, tp->tm_min, tp->tm_sec); + + return ret; +} + +/************************************************************ + * Function: clock_calendar2utc + * + * Description: + * Calendar/UTC conversion based on algorithms from p. 604 + * of Seidelman, P. K. 1992. Explanatory Supplement to + * the Astronomical Almanac. University Science Books, + * Mill Valley. + * + ************************************************************/ + +time_t clock_calendar2utc(int year, int month, int day) +{ + int dyear; +#ifdef CONFIG_JULIAN_TIME + int isgreg; +#endif /* CONFIG_JULIAN_TIME */ + + /* Correct year & month ranges. Shift month into range 1-12 */ + + dyear = (month-1) / 12; + month -= 12 * dyear; + year += dyear; + + if (month < 1) + { + month += 12; + year -= 1; + } + +#ifdef CONFIG_JULIAN_TIME + /* Determine which calendar to use */ + + if (year > GREG_YEAR) + { + isgreg = TRUE; + } + else if (year < GREG_YEAR) + { + isgreg = FALSE; + } + else if (month > GREG_MONTH) + { + isgreg = TRUE; + } + else if (month < GREG_MONTH) + { + isgreg = FALSE; + } + else + { + isgreg = (day >= GREG_DAY); + } + + /* Calculate and return date */ + + if (isgreg) + { + return clock_gregorian2utc(year, month, day) - JD_OF_EPOCH; + } + else + { + return clock_julian2utc (year, month, day) - JD_OF_EPOCH; + } + +#else /* CONFIG_JULIAN_TIME */ + + return clock_gregorian2utc(year, month, day) - JD_OF_EPOCH; + +#endif /* CONFIG_JULIAN_TIME */ +} diff --git a/nuttx/sched/mq_close.c b/nuttx/sched/mq_close.c new file mode 100644 index 000000000..b1625de73 --- /dev/null +++ b/nuttx/sched/mq_close.c @@ -0,0 +1,189 @@ +/************************************************************ + * mq_close.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#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 + * + * Inputs: + * mqdes - message queue descriptor to free + * + ************************************************************/ + +static inline void mq_desfree(mqd_t mqdes) +{ + /* Just put it back on the free list */ + + sq_addlast((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) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + msgq_t *msgq; + uint32 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((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. + */ + + if (msgq->ntmqdes == mqdes) + { + msgq->ntpid = INVALID_PROCESS_ID; + msgq->ntsigno = 0; + msgq->ntvalue.sival_int = 0; + msgq->ntmqdes = NULL; + } + + /* 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((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..5f68268d3 --- /dev/null +++ b/nuttx/sched/mq_descreate.c @@ -0,0 +1,156 @@ +/************************************************************ + * mq_descreate.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#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 <nuttx/os_external.h> +#include "os_internal.h" +#include "sig_internal.h" + +#include <sys/types.h> /* uint32, etc. */ +#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 inline 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(_TCB* mtcb, 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((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..f01e24d1f --- /dev/null +++ b/nuttx/sched/mq_findnamed.c @@ -0,0 +1,103 @@ +/************************************************************ + * mq_findnamed.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#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). + * + ************************************************************/ + +msgq_t *mq_findnamed(const char *mq_name) +{ + msgq_t *msgq; + + /* Search the list of named message queues */ + + for (msgq = (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_getattr.c b/nuttx/sched/mq_getattr.c new file mode 100644 index 000000000..52292410e --- /dev/null +++ b/nuttx/sched/mq_getattr.c @@ -0,0 +1,114 @@ +/************************************************************ + * mq_getattr.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#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/kmalloc.h> +#include <nuttx/arch.h> +#include <nuttx/os_external.h> +#include "os_internal.h" +#include "sig_internal.h" +#include "mq_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: mq_getattr + * + * Description: + * This functions gets status information and attributes + * associated with the specified message queue. + * + * Parameters: + * mqdes - Message queue descriptor + * mq_stat - Buffer in which to return attributes + * + * Return Value: + * 0 (OK) if attributes provided, -1 (ERROR) otherwise. + * + * Assumptions: + * + ************************************************************/ + +int mq_getattr(mqd_t mqdes, struct mq_attr *mq_stat) +{ + int ret = ERROR; + + if (mqdes && mq_stat) + { + /* Return the attributes */ + + mq_stat->mq_maxmsg = mqdes->msgq->maxmsgs; + mq_stat->mq_msgsize = mqdes->msgq->maxmsgsize; + mq_stat->mq_flags = mqdes->oflags; + mq_stat->mq_curmsgs = mqdes->msgq->nmsgs; + + ret = OK; + } + + return ret; +} diff --git a/nuttx/sched/mq_initialize.c b/nuttx/sched/mq_initialize.c new file mode 100644 index 000000000..deff6a254 --- /dev/null +++ b/nuttx/sched/mq_initialize.c @@ -0,0 +1,246 @@ +/************************************************************ + * mq_initialize.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#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 nmsgs, + ubyte 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((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(&mqdesblock->queue, &g_desalloc); + + /* Then add each message queue descriptor to the free list */ + + for (i = 0; i < NUM_MSG_DESCRIPTORS; i++) + { + sq_addlast((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..5768bbd70 --- /dev/null +++ b/nuttx/sched/mq_internal.h @@ -0,0 +1,200 @@ +/************************************************************ + * mq_internal.h + * + * 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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (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 __MQ_INTERNAL_H +#define __MQ_INTERNAL_H + +/************************************************************ + * Included Files + ************************************************************/ + +#include <sys/types.h> +#include <mqueue.h> +#include <sched.h> +#include <nuttx/compiler.h> + +/************************************************************ + * Compilations Switches + ************************************************************/ + +/************************************************************ + * Definitions + ************************************************************/ + +#define MQ_MAX_BYTES CONFIG_MQ_MAXMSGSIZE +#define MQ_MAX_HWORDS ((MQ_MAX_BYTES + sizeof(uint16) - 1) / sizeof(uint16)) +#define MQ_MAX_MSGS 16 +#define MQ_PRIO_MAX 255 + +/* 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. */ +/* NOTE: This structure is allocated from the same pool as MQ_type. + * Therefore, (1) it must have a fixed "mail" size, and (2) must + * exactly match MQ_type in size. + */ + +struct mqmsg +{ + /* The position of the following two field must exactly match + * MQ_type. + */ + + struct mqmsg *next; /* Forward link to next message */ + ubyte type; /* (Used to manage allocations) */ + + ubyte priority; /* priority of message */ + ubyte msglen; /* Message data length */ + ubyte pad; /* Not used */ + uint16 mail[MQ_MAX_HWORDS]; /* Message data */ +}; +typedef struct mqmsg mqmsg_t; + +/* This structure defines a message queue */ + +struct msgq_s +{ + struct msgq_s *flink; /* Forward link to next message queue */ + sq_queue_t msglist; /* Prioritized message list */ + sint16 maxmsgs; /* Maximum number of messages in the queue */ + sint16 nmsgs; /* Number of message in the queue */ + sint16 nconnect; /* Number of connections to message queue */ + sint16 nwaitnotfull; /* Number tasks waiting for not full */ + sint16 nwaitnotempty; /* Number tasks waiting for not empty */ + ubyte maxmsgsize; /* Max size of message in message queue */ + boolean unlinked; /* TRUE if the msg queue has been unlinked */ + struct mq_des *ntmqdes; /* Notification: Owning mqdes (NULL if none) */ + pid_t ntpid; /* Notification: Receiving Task's PID */ + int ntsigno; /* Notification: Signal number */ + union sigval ntvalue; /* Notification: Signal value */ + char name[1]; /* Start of the queue name */ +}; +typedef struct msgq_s msgq_t; + +#define SIZEOF_MQ_HEADER ((int)(((msgq_t*)NULL)->name)) + +/* This describes the message queue descriptor that is held in the + * task's TCB + */ + +struct mq_des +{ + struct mq_des *flink; /* Forward link to next message descriptor */ + msgq_t *msgq; /* Pointer to associated message queue */ + int oflags; /* Flags set when message queue was opened */ +}; + +/* This is the handle used to reference a message queue */ + +typedef struct mq_des *mqd_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_initialized.c *******************/ + +EXTERN void weak_function mq_initialize(void); +EXTERN void mq_desblockalloc(void); + +EXTERN mqd_t mq_descreate(_TCB* mtcb, msgq_t* msgq, int oflags); +EXTERN msgq_t *mq_findnamed(const char *mq_name); +EXTERN void mq_msgfree(mqmsg_t *mqmsg); +EXTERN void mq_msgqfree(msgq_t *msgq); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __MQ_INTERNAL_H */ + diff --git a/nuttx/sched/mq_msgfree.c b/nuttx/sched/mq_msgfree.c new file mode 100644 index 000000000..9c5f12af5 --- /dev/null +++ b/nuttx/sched/mq_msgfree.c @@ -0,0 +1,135 @@ +/************************************************************ + * 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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#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(mqmsg_t * mqmsg) +{ + uint32 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((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((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..59a27603e --- /dev/null +++ b/nuttx/sched/mq_msgqfree.c @@ -0,0 +1,107 @@ +/************************************************************ + * mq_msgqfree.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#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(msgq_t *msgq) +{ + mqmsg_t *curr; + mqmsg_t *next; + + /* Deallocate any stranded messages in the message queue. */ + + curr = (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..aaed2e45b --- /dev/null +++ b/nuttx/sched/mq_notify.c @@ -0,0 +1,170 @@ +/************************************************************ + * mq_notify.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#include <mqueue.h> +#include <sched.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: + * None + * + * 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 ret = ERROR; + + if (mqdes) + { + sched_lock(); + + /* Get a pointer to the message queue */ + + 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? Make + * sure a good signal number has been provided + */ + + if (notification && GOOD_SIGNO(notification->sigev_signo)) + { + /* Yes... Assign it to the current task. */ + + msgq->ntvalue = notification->sigev_value; + msgq->ntsigno = notification->sigev_signo; + msgq->ntpid = rtcb->pid; + msgq->ntmqdes = mqdes; + ret = OK; + } + } + + /* Yes... a notification is attached. Does this task own it? + * Is it trying to remove it? + */ + + else if ((msgq->ntpid == rtcb->pid) && (!notification)) + { + /* Yes... Detach the notification */ + + msgq->ntpid = INVALID_PROCESS_ID; + msgq->ntsigno = 0; + msgq->ntvalue.sival_int = 0; + msgq->ntmqdes = NULL; + ret = OK; + } + sched_unlock(); + } + + return ret; +} diff --git a/nuttx/sched/mq_open.c b/nuttx/sched/mq_open.c new file mode 100644 index 000000000..97b2af121 --- /dev/null +++ b/nuttx/sched/mq_open.c @@ -0,0 +1,226 @@ +/************************************************************ + * mq_open.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#include <stdarg.h> /* va_list */ +#include <mqueue.h> +#include <string.h> +#include <sched.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, ...) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + 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. + */ + + if (!(oflags & O_CREAT) || !(oflags & O_EXCL)) + { + /* 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 = (msgq_t*)kzmalloc(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 = (sint16)attr->mq_maxmsg; + if (attr->mq_msgsize <= MQ_MAX_BYTES) + { + msgq->maxmsgsize = (sint16)attr->mq_msgsize; + } + else + { + msgq->maxmsgsize = MQ_MAX_BYTES; + } + } + else + { + msgq->maxmsgs = MQ_MAX_MSGS; + msgq->maxmsgsize = MQ_MAX_BYTES; + } + + msgq->nconnect = 1; + msgq->ntpid = INVALID_PROCESS_ID; + strcpy(msgq->name, mq_name); + + /* Add the new message queue to the list of + * message queues + */ + + sq_addlast((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_receive.c b/nuttx/sched/mq_receive.c new file mode 100644 index 000000000..3dbe662c2 --- /dev/null +++ b/nuttx/sched/mq_receive.c @@ -0,0 +1,236 @@ +/************************************************************ + * mq_receive.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#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/kmalloc.h> +#include <nuttx/arch.h> +#include <nuttx/os_external.h> +#include "os_internal.h" +#include "sig_internal.h" +#include "mq_internal.h" + +/************************************************************ + * 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 + * select 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: + * Length of the selected message in bytes, otherwise -1 + * (ERROR). + * + * Assumptions: + * + ************************************************************/ + +int mq_receive(mqd_t mqdes, void *msg, size_t msglen, int *prio) +{ + _TCB *rtcb; + _TCB *btcb; + msgq_t *msgq; + mqmsg_t *curr; + uint32 saved_state; + ubyte rcvmsglen; + int ret = ERROR; + + /* Verify the input parameters */ + + sched_lock(); + if (msg && mqdes && (mqdes->oflags & O_RDOK) != 0 && + msglen >= (size_t)mqdes->msgq->maxmsgsize) + { + /* Get a pointer to the message queue */ + + msgq = mqdes->msgq; + + /* Several operations must be performed below: We must determine if + * a message is pending and, if not, wait for the message. Since + * messages can be sent from the interrupt level, there is a race + * condition that can only be eliminated by disabling interrupts! + */ + + saved_state = irqsave(); + + /* Get the message from the head of the queue */ + + while ((curr = (mqmsg_t*)sq_remfirst(&msgq->msglist)) == NULL) + { + /* Should we block until there the above condition has been + * satisfied? + */ + + if (!(mqdes->oflags & O_NONBLOCK)) + { + /* Block and try again */ + + rtcb = (_TCB*)g_readytorun.head; + rtcb->msgwaitq = msgq; + msgq->nwaitnotempty++; + up_block_task(rtcb, TSTATE_WAIT_MQNOTEMPTY); + } + else + { + break; + } + } + + /* If we got message, then decrement the number of messages in + * the queue while we are still in the critical section + */ + + if (curr) + { + msgq->nmsgs--; + } + irqrestore(saved_state); + + /* Check (again) if we got a message from the message queue*/ + + if (curr) + { + /* Get the length of the message (also the return value) */ + + ret = rcvmsglen = curr->msglen; + + /* Copy the message into the caller's buffer */ + + memcpy((void*)curr->mail, msg, rcvmsglen); + + /* Copy the message priority as well (if a buffer is provided) */ + + if (prio) + { + *prio = curr->priority; + } + + /* We are done with the message. Deallocate it now. */ + + mq_msgfree(curr); + + /* Check if any tasks are waiting for the MQ not full event. */ + + 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 = (_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); + } + } + } + + sched_unlock(); + return ret; +} diff --git a/nuttx/sched/mq_send.c b/nuttx/sched/mq_send.c new file mode 100644 index 000000000..b5dda8278 --- /dev/null +++ b/nuttx/sched/mq_send.c @@ -0,0 +1,398 @@ +/************************************************************ + * mq_send.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <nuttx/kmalloc.h> +#include <sys/types.h> /* uint32, etc. */ +#include <mqueue.h> +#include <string.h> +#include <sched.h> +#include <debug.h> +#include <nuttx/arch.h> +#include "os_internal.h" +#include "sig_internal.h" +#include "mq_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * 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 + * + ************************************************************/ + +mqmsg_t *mq_msgalloc(void) +{ + mqmsg_t *mqmsg; + uint32 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 = (mqmsg_t*)sq_remfirst(&g_msgfree); + if (!mqmsg) + { + /* Try the free list reserved for interrupt handlers */ + + mqmsg = (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 = (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 = (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 + { + dbg("%s: Out of messages\n", __FUNCTION__); + PANIC((uint32)OSERR_OUTOFMESSAGES); + } + } + } + + return(mqmsg); + +} + +/************************************************************ + * 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() will in 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: + * None + * + * Assumptions/restrictions: + * + ************************************************************/ + +int mq_send(mqd_t mqdes, const void *msg, size_t msglen, int prio) +{ + _TCB *rtcb; + _TCB *btcb; + msgq_t *msgq; + mqmsg_t *curr; + mqmsg_t *next; + mqmsg_t *prev; + uint32 saved_state; + int ret = ERROR; + + /* Verify the input parameters */ + + sched_lock(); + if (msg && mqdes && (mqdes->oflags & O_WROK) != 0 && + msglen > 0 && msglen <= (size_t)mqdes->msgq->maxmsgsize && + prio >= 0 && prio <= MQ_PRIO_MAX) + { + /* Get a pointer to the message queue */ + + msgq = mqdes->msgq; + + /* If we are sending a message from an interrupt handler, then + * try to get message structure unconditionally. + */ + + saved_state = irqsave(); + if (up_interrupt_context()) + { + curr = mq_msgalloc(); + } + + /* Otherwise, arbitrarily limit the number of messages in the + * queue to the value determined when the message queue was opened. + * This makes us more POSIX-like as well as prohibits one slow + * responding task from consuming all available memory. + */ + + else 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. */ + + curr = NULL; + } + + /* Yes... We will not return control until the message queue is + * available. + */ + + 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 = (_TCB*)g_readytorun.head; + rtcb->msgwaitq = msgq; + (msgq->nwaitnotfull)++; + up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL); + } + + /* It should be okay to get add a message to the receiving + * message queue now. + */ + + curr = mq_msgalloc(); + } + } + + /* We are not in an interrupt handler and the receiving message queue + * is not full + */ + + else + { + /* Just allocate a message */ + + curr = mq_msgalloc(); + } + irqrestore(saved_state); + + /* Check if we were able to get a message structure */ + + if (curr) + { + /* Construct the current message header info */ + + curr->priority = (ubyte)prio; + curr->msglen = (ubyte)msglen; + + /* Copy the message data into the message */ + + memcpy((void*)msg, (const void*)curr->mail, 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 = (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((sq_entry_t*)prev, (sq_entry_t*)curr, + &msgq->msglist); + } + else + { + sq_addfirst((sq_entry_t*)curr, &msgq->msglist); + } + + /* Increment the count of message in the queue */ + + msgq->nmsgs++; + irqrestore(saved_state); + + /* Check if we need to notify any tasks that are attached to the + * message queue + */ + + if (msgq->ntmqdes) + { + /* Remove the message notification data from the message queue. */ + + union sigval value = msgq->ntvalue; + 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? */ + + sig_mqnotempty(pid, signo, value); + } + + /* 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 = (_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); + ret = OK; + } + } + + sched_unlock(); + return(ret); +} + diff --git a/nuttx/sched/mq_setattr.c b/nuttx/sched/mq_setattr.c new file mode 100644 index 000000000..6976886de --- /dev/null +++ b/nuttx/sched/mq_setattr.c @@ -0,0 +1,115 @@ +/************************************************************ + * mq_setattr.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#include <mqueue.h> +#include "mq_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: mq_setattr + * + * Description: + * This function sets the attributes associated with the + * specified message queue "mqdes." Only the "O_NONBLOCK" + * bit of the "mq_flags" can be changed. + * + * If "oldstat" is non-null, mq_setattr() will store the + * previous message queue attributes at that location (just + * as would have been returned by mq_getattr()). + * + * Parameters: + * mqdes - Message queue descriptor + * mq_stat - New attributes + * oldstate - Old attributes + * + * Return Value: + * 0 (OK) if attributes are set successfully, otherwise + * -1 (ERROR). + * + * Assumptions: + * + ************************************************************/ + +int mq_setattr(mqd_t mqdes, const struct mq_attr *mq_stat, + struct mq_attr *oldstat) +{ + int ret = ERROR; + + if (mqdes && mq_stat) + { + /* Return the attributes if so requested */ + + if (oldstat) + { + (void)mq_getattr(mqdes, oldstat); + } + + /* Set the new value of the O_NONBLOCK flag. */ + + mqdes->oflags = ((mq_stat->mq_flags & O_NONBLOCK) | + (mqdes->oflags & (~O_NONBLOCK))); + ret = OK; + } + + return ret; +} diff --git a/nuttx/sched/mq_unlink.c b/nuttx/sched/mq_unlink.c new file mode 100644 index 000000000..dc1f95140 --- /dev/null +++ b/nuttx/sched/mq_unlink.c @@ -0,0 +1,142 @@ +/************************************************************ + * mq_unlink.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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> /* uint32, etc. */ +#include <mqueue.h> +#include <sched.h> +#include "os_internal.h" +#include "mq_internal.h" + +/************************************************************ + * 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) +{ + msgq_t *msgq; + uint32 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((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/os_internal.h b/nuttx/sched/os_internal.h new file mode 100644 index 000000000..0be0bb5ac --- /dev/null +++ b/nuttx/sched/os_internal.h @@ -0,0 +1,267 @@ +/************************************************************ + * os_internal.h + * + * 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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (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 <queue.h> +#include <sched.h> +#include <nuttx/kmalloc.h> +#include <nuttx/os_external.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/* OS CRASH CODES */ + +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_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 following + * definition. 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_ALLOWED 64 +#define MAX_TASKS_MASK 0x3f +#define PIDHASH(pid) ((pid) & MAX_TASKS_MASK) + +/* Stubs used when there are no file descriptors */ + +#if CONFIG_NFILE_DESCRIPTORS <= 0 +# define sched_setupidlefiles(t) (OK) +# define sched_setuptaskfiles(t) (OK) +# define sched_setuppthreadfiles(t) (OK) +# define sched_releasefiles(t) (OK) +#endif + +/* A more efficient ways to access the errno */ + +#define SET_ERRNO(e) \ + { _TCB *rtcb = _TCB*)g_readytorun.head; rtcb->errno = (e); } + +#define _SET_TCB_ERRNO(t,e) \ + { (t)->errno = (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 +{ + _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 +{ + dq_queue_t *list; /* Pointer to the task list */ + boolean 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 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 dq_queue_t g_pendingtasks; + +/* This is the list of all tasks that are blocked waiting for a semaphore */ + +extern dq_queue_t g_waitingforsemaphore; + +/* This is the list of all tasks that are blocked waiting for a signal */ + +extern dq_queue_t g_waitingforsignal; + +/* This is the list of all tasks that are blocked waiting for a message + * queue to become non-empty. + */ + +extern dq_queue_t g_waitingformqnotempty; + +/* This is the list of all tasks that are blocked waiting for a message + * queue to become non-full. + */ + +extern dq_queue_t g_waitingformqnotfull; + +/* 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 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 sq_queue_t g_delayeddeallocations; + +/* This is the value of the last process ID assigned to a task */ + +extern 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 MAX_TASKS_ALLOWED. + */ + +extern pidhash_t g_pidhash[MAX_TASKS_ALLOWED]; + +/* 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 Inline Functions + ************************************************************/ + +/************************************************************ + * Public Function Prototypes + ************************************************************/ + +extern STATUS _task_init(_TCB *tcb, char *name, int priority, + start_t start, main_t main, + boolean pthread, + char *arg1, char *arg2, + char *arg3, char *arg4); + +extern boolean sched_addreadytorun(_TCB *rtrtcb); +extern boolean sched_removereadytorun(_TCB *rtrtcb); +extern boolean sched_addprioritized(_TCB *newTcb, + dq_queue_t *list); +extern boolean sched_mergepending(void); +extern void sched_addblocked(_TCB *btcb, tstate_t task_state); +extern void sched_removeblocked(_TCB *btcb); +extern _TCB *sched_gettcb(pid_t pid); + +#if CONFIG_NFILE_DESCRIPTORS > 0 +extern int sched_setupidlefiles(_TCB *tcb); +extern int sched_setuptaskfiles(_TCB *tcb); +extern int sched_setuppthreadfiles(_TCB *tcb); +#if CONFIG_NFILE_STREAMS > 0 +extern int sched_setupstreams(_TCB *tcb); +extern int sched_flushfiles(_TCB *tcb); +#endif +extern int sched_releasefiles(_TCB *tcb); +#endif + +extern int sched_releasetcb(_TCB *tcb); + +#endif /* __OS_INTERNAL_H */ diff --git a/nuttx/sched/os_start.c b/nuttx/sched/os_start.c new file mode 100644 index 000000000..b4bae75c5 --- /dev/null +++ b/nuttx/sched/os_start.c @@ -0,0 +1,382 @@ +/************************************************************ + * os_start.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <debug.h> +#include <string.h> + +#include <nuttx/arch.h> +#include <nuttx/fs.h> +#include <nuttx/lib.h> +#include <nuttx/os_external.h> +#include "os_internal.h" +#include "sig_internal.h" +#include "wd_internal.h" +#include "sem_internal.h" +#include "mq_internal.h" +#include "pthread_internal.h" +#include "clock_internal.h" +#include "irq_internal.h" + +/************************************************************ + * 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. + */ + +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. + */ + +dq_queue_t g_pendingtasks; + +/* This is the list of all tasks that are blocked waiting for a semaphore */ + +dq_queue_t g_waitingforsemaphore; + +/* This is the list of all tasks that are blocked waiting for a signal */ + +dq_queue_t g_waitingforsignal; + +/* This is the list of all tasks that are blocked waiting for a message + * queue to become non-empty. + */ + +dq_queue_t g_waitingformqnotempty; + +/* This is the list of all tasks that are blocked waiting for a message + * queue to become non-full. + */ + +dq_queue_t g_waitingformqnotfull; + +/* This the list of all tasks that have been initialized, but not yet + * activated. NOTE: This is the only list that is not prioritized. + */ + +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. + */ + +sq_queue_t g_delayeddeallocations; + +/* This is the value of the last process ID assigned to a task */ + +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 MAX_TASKS_ALLOWED. + */ + +pidhash_t g_pidhash[MAX_TASKS_ALLOWED]; + +/* 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 */ + { &g_waitingforsignal, FALSE }, /* TSTATE_WAIT_SIG */ + { &g_waitingformqnotempty, TRUE }, /* TSTATE_WAIT_MQNOTEMPTY */ + { &g_waitingformqnotfull, TRUE } /* TSTATE_WAIT_MQNOTFULL */ +}; + +/************************************************************ + * 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 _TCB g_idletcb; + +/************************************************************ + * 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 init_taskid; + int i; + + lldbg("os_start:\n"); + + /* Initialize all task lists */ + + dq_init(&g_readytorun); + dq_init(&g_pendingtasks); + dq_init(&g_waitingforsemaphore); + dq_init(&g_waitingforsignal); + dq_init(&g_waitingformqnotfull); + dq_init(&g_waitingformqnotempty); + dq_init(&g_inactivetasks); + sq_init(&g_delayeddeallocations); + + /* Initialize the logic that determine unique process IDs. */ + + g_lastpid = 0; + for (i = 0; i < MAX_TASKS_ALLOWED; 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, "Idle Task", CONFIG_TASK_NAME_SIZE-1); + g_idletcb.argv[0] = g_idletcb.name; +#else + g_idletcb.argv[0] = "Idle Task"; +#endif /* CONFIG_TASK_NAME_SIZE */ + + /* Then add the idle task's TCB to the head of the ready to run list */ + + dq_addfirst((dq_entry_t*)&g_idletcb, &g_readytorun); + + /* Initialize the processor-specific portion of the TCB */ + + up_initial_state(&g_idletcb); + + /* Initialize the memory manager */ + +#ifndef CONFIG_HEAP_BASE + { + void *heap_start; + size_t heap_size; + up_allocate_heap(&heap_start, &heap_size); + mm_initialize(heap_start, heap_size); + } +#else + mm_initialize((void*)CONFIG_HEAP_BASE, CONFIG_HEAP_SIZE); +#endif + + /* Initialize the interrupt handling subsystem (if included) */ + + if (irq_initialize != NULL) + { + irq_initialize(); + } + + /* Provide an access point to initialize any user-specific logic very + * early in the initialization sequence. Note that user_ininitialize() + * is called only if it is provided in the link. + */ + + if (user_initialize != NULL) + { + user_initialize(); + } + + /* Initialize the POSIX timer facility (if included in the link) */ + + if (clock_initialize != NULL) + { + clock_initialize(); + } + + /* Initialize the watchdog facility (if included in the link) */ + + if (wd_initialize != NULL) + { + wd_initialize(); + } + + /* Initialize the signal facility (if in link) */ + + if (sig_initialize != NULL) + { + sig_initialize(); + } + + /* Initialize the semaphore facility. (if in link) */ + + if (sem_initialize != NULL) + { + sem_initialize(); + } + + /* Initialize the named message queue facility (if in link) */ + + if (mq_initialize != NULL) + { + mq_initialize(); + } + + /* Initialize the thread-specific data facility (if in link) */ + + if (pthread_initialize != NULL) + { + pthread_initialize(); + } + + /* Initialize the file system (needed to support device drivers) */ + + if (fs_initialize != NULL) + { + fs_initialize(); + } + + /* 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. + */ + + if (lib_initialize != NULL) + { + lib_initialize(); + } + + /* Create stdout, stderr, stdin */ + + (void)sched_setupidlefiles(&g_idletcb); + + /* Once the operating system has been initialized, the system must be + * started by spawning the user init thread of execution. + */ + + dbg("os_start: Starting init thread\n"); + init_taskid = task_create("init", SCHED_PRIORITY_DEFAULT, + CONFIG_PROC_STACK_SIZE, + (main_t)user_start, 0, 0, 0, 0); + ASSERT(init_taskid != ERROR); + + /* When control is return to this point, the system is idle. */ + + dbg("os_start: Beginning Idle Loop\n"); + for (;;) + { + /* Check if there is anything in the delayed deallocation list. */ + + while (g_delayeddeallocations.head) + { + /* Remove the first delayed deallocation. */ + + uint32 savedState = irqsave(); + void *address = (void*)sq_remfirst(&g_delayeddeallocations); + irqrestore(savedState); + + /* Then deallocate it */ + + if (address) sched_free(address); + } + + /* Perform idle state operations */ + + up_idle(); + } +} diff --git a/nuttx/sched/pthread_attrdestroy.c b/nuttx/sched/pthread_attrdestroy.c new file mode 100644 index 000000000..9bb86268c --- /dev/null +++ b/nuttx/sched/pthread_attrdestroy.c @@ -0,0 +1,108 @@ +/************************************************************ + * pthread_attrdestroy.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_attr_destroy + * + * Description: + * An attributes object can be deleted when it is no longer + * needed. + * + * Parameters: + * attr + * + * Return Value: + * 0 meaning success + * + * Assumptions: + * + ************************************************************/ + +int pthread_attr_destroy(pthread_attr_t *attr) +{ + int ret; + + dbg("%s: attr=0x%p\n", __FUNCTION__, attr); + + if (!attr) + { + ret = EINVAL; + } + else + { + memset(attr, 0, sizeof(pthread_attr_t)); + ret = OK; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + diff --git a/nuttx/sched/pthread_attrgetinheritsched.c b/nuttx/sched/pthread_attrgetinheritsched.c new file mode 100644 index 000000000..d0d3143e7 --- /dev/null +++ b/nuttx/sched/pthread_attrgetinheritsched.c @@ -0,0 +1,112 @@ +/************************************************************ + * pthread_attrgetinheritsched.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_attr_getinheritsched + * + * Description: + * Report whether the scheduling info in the pthread + * attributes will be used or if the thread will + * inherit the properties of the parent. + * + * Parameters: + * attr + * inheritsched + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_attr_getinheritsched(const pthread_attr_t *attr, + int *inheritsched) +{ + int ret; + + dbg("%s: attr=0x%p inheritsched=0x%p\n", + __FUNCTION__, attr, inheritsched); + + if (!attr || !inheritsched) + { + ret = EINVAL; + } + else + { + *inheritsched = (int)attr->inheritsched; + ret = OK; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + diff --git a/nuttx/sched/pthread_attrgetschedparam.c b/nuttx/sched/pthread_attrgetschedparam.c new file mode 100644 index 000000000..2285895e7 --- /dev/null +++ b/nuttx/sched/pthread_attrgetschedparam.c @@ -0,0 +1,109 @@ +/************************************************************ + * pthread_attrgetschedparam.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_attr_getschedparam + * + * Description: + * + * Parameters: + * attr + * param + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_attr_getschedparam(pthread_attr_t *attr, + struct sched_param *param) +{ + int ret; + + dbg("%s: attr=0x%p param=0x%p\n", __FUNCTION__, attr, param); + + if (!attr || !param) + { + ret = EINVAL; + } + else + { + param->sched_priority = attr->priority; + ret = OK; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + + diff --git a/nuttx/sched/pthread_attrgetschedpolicy.c b/nuttx/sched/pthread_attrgetschedpolicy.c new file mode 100644 index 000000000..801226c98 --- /dev/null +++ b/nuttx/sched/pthread_attrgetschedpolicy.c @@ -0,0 +1,106 @@ +/************************************************************ + * pthread_attrgetschedpolicy.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_attr_getschedpolicy + * + * Description: + * Obtain the scheduling algorithm attribute. + * + * Parameters: + * attr + * policy + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy) +{ + int ret; + + dbg("%s: attr=0x%p policy=0x%p\n", __FUNCTION__, attr, policy); + + if (!attr || !policy) + { + ret = EINVAL; + } + else + { + *policy = attr->policy; + ret = OK; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_attrgetstacksize.c b/nuttx/sched/pthread_attrgetstacksize.c new file mode 100644 index 000000000..d36ae172e --- /dev/null +++ b/nuttx/sched/pthread_attrgetstacksize.c @@ -0,0 +1,107 @@ +/************************************************************ + * pthread_attrgetstacksize.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_attr_getstacksize + * + * Description: + * + * Parameters: + * attr + * stacksize + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_attr_getstacksize(pthread_attr_t *attr, long *stacksize) +{ + int ret; + + dbg("%s: attr=0x%p stacksize=0x%p\n", __FUNCTION__, attr, stacksize); + + if (!stacksize) + { + ret = EINVAL; + } + else + { + *stacksize = attr->stacksize; + ret = OK; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + diff --git a/nuttx/sched/pthread_attrinit.c b/nuttx/sched/pthread_attrinit.c new file mode 100644 index 000000000..51d2ea525 --- /dev/null +++ b/nuttx/sched/pthread_attrinit.c @@ -0,0 +1,111 @@ +/************************************************************ + * pthread_attrinit.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_attr_init + * + * Description: + * Initializes a thread attributes object (attr) with + * default values for all of the individual attributes + * used by a given implementation. + * + * Parameters: + * attr + * + * Return Value: + * 0 on success, otherwise an error number + * + * Assumptions: + * + ************************************************************/ + +int pthread_attr_init(pthread_attr_t *attr) +{ + int ret = OK; + + dbg("%s: attr=0x%p\n", __FUNCTION__, attr); + if (!attr) + { + ret = ENOMEM; + } + else + { + /* Set the child thread priority to be the default + * priority. Set the child stack size to some arbitrary + * default value. + */ + + memcpy(attr, &g_default_pthread_attr, sizeof(pthread_attr_t)); + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + diff --git a/nuttx/sched/pthread_attrsetinheritsched.c b/nuttx/sched/pthread_attrsetinheritsched.c new file mode 100644 index 000000000..e83d13d73 --- /dev/null +++ b/nuttx/sched/pthread_attrsetinheritsched.c @@ -0,0 +1,112 @@ +/************************************************************ + * pthread_attrsetinheritsched.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_attr_setinheritsched + * + * Description: + * Indicate whether the scheduling info in the pthread + * attributes will be used or if the thread will + * inherit the properties of the parent. + * + * Parameters: + * attr + * policy + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_attr_setinheritsched(pthread_attr_t *attr, + int inheritsched) +{ + int ret; + + dbg("%s: inheritsched=%d\n", __FUNCTION__, inheritsched); + + if (!attr || + (inheritsched != PTHREAD_INHERIT_SCHED && + inheritsched != PTHREAD_EXPLICIT_SCHED)) + { + ret = EINVAL; + } + else + { + attr->inheritsched = (ubyte)inheritsched; + ret = OK; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + diff --git a/nuttx/sched/pthread_attrsetschedparam.c b/nuttx/sched/pthread_attrsetschedparam.c new file mode 100644 index 000000000..4a0d98348 --- /dev/null +++ b/nuttx/sched/pthread_attrsetschedparam.c @@ -0,0 +1,107 @@ +/************************************************************ + * pthread_attrsetschedparam.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_attr_setschedparam + * + * Description: + * + * Parameters: + * attr + * param + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_attr_setschedparam(pthread_attr_t *attr, + const struct sched_param *param) +{ + int ret; + + dbg("%s: attr=0x%p param=0x%p\n", __FUNCTION__, attr, param); + + if (!attr || !param) + { + ret = EINVAL; + } + else + { + attr->priority = (short)param->sched_priority; + ret = OK; + } + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + diff --git a/nuttx/sched/pthread_attrsetschedpolicy.c b/nuttx/sched/pthread_attrsetschedpolicy.c new file mode 100644 index 000000000..d750cf6fd --- /dev/null +++ b/nuttx/sched/pthread_attrsetschedpolicy.c @@ -0,0 +1,110 @@ +/************************************************************ + * pthread_attrsetschedpolicy.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_attr_setschedpolicy + * + * Description: + * Set the scheduling algorithm attribute. + * + * Parameters: + * attr + * policy + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) +{ + int ret; + + dbg("%s: attr=0x%p policy=%d\n", __FUNCTION__, attr, policy); + +#if CONFIG_RR_INTERVAL > 0 + if (!attr || (policy != SCHED_FIFO && policy != SCHED_RR)) +#else + if (!attr || policy != SCHED_FIFO ) +#endif + { + ret = EINVAL; + } + else + { + attr->policy = policy; + ret = OK; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_attrsetstacksize.c b/nuttx/sched/pthread_attrsetstacksize.c new file mode 100644 index 000000000..b33b75e63 --- /dev/null +++ b/nuttx/sched/pthread_attrsetstacksize.c @@ -0,0 +1,107 @@ +/************************************************************ + * pthread_attrsetstacksize.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_attr_setstacksize + * + * Description: + * + * Parameters: + * attr + * stacksize + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_attr_setstacksize(pthread_attr_t *attr, long stacksize) +{ + int ret; + + dbg("%s: attr=0x%p stacksize=%ld\n", + __FUNCTION__, attr, stacksize); + + if (!attr || stacksize < PTHREAD_STACK_MIN) + { + ret = EINVAL; + } + else + { + attr->stacksize = stacksize; + ret = OK; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + diff --git a/nuttx/sched/pthread_cancel.c b/nuttx/sched/pthread_cancel.c new file mode 100644 index 000000000..d34c29ae3 --- /dev/null +++ b/nuttx/sched/pthread_cancel.c @@ -0,0 +1,143 @@ +/************************************************************************** + * pthread_cancel.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +/************************************************************************** + * Included Files + **************************************************************************/ + +#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) + { + /* pid == 0 is the IDLE task. Callers cannot cancel the + * IDLE task. + */ + + return ESRCH; + } + + tcb = sched_gettcb(thread.pid); + 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(thread.pid, PTHREAD_CANCELED); + + /* Then let pthread_delete do the real work */ + + task_delete(thread.pid); + return OK; +} + + diff --git a/nuttx/sched/pthread_completejoin.c b/nuttx/sched/pthread_completejoin.c new file mode 100644 index 000000000..a5e7651e0 --- /dev/null +++ b/nuttx/sched/pthread_completejoin.c @@ -0,0 +1,211 @@ +/************************************************************ + * pthread_completejoin.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <errno.h> +#include <debug.h> +#include "os_internal.h" +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_destroyjoininfo + * + * Description: + * Destroy a join_t structure. This must + * be done by the child thread at child thread destruction + * time. + * + ************************************************************/ + +static void pthread_destroyjoininfo(join_t *pjoin) +{ + int ntasks_waiting; + int status; + + dbg("%s: pjoin=0x%p\n", __FUNCTION__, 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); + (void)sem_destroy(&pjoin->data_sem); + } + + /* All of the joined threads have had received the exit value. + * Now we can destroy this thread's exit semaphore + */ + + (void)sem_destroy(&pjoin->exit_sem); +} + +/************************************************************ + * 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, void *exit_value) +{ + join_t *pjoin; + boolean detached = FALSE; + + dbg("%s: process_id=%d exit_value=%p\n", __FUNCTION__, 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 + { + /* Has the thread been marked as detached? */ + + pjoin->terminated = TRUE; + detached = pjoin->detached; + if (detached) + { + dbg("%s: Detaching\n", __FUNCTION__); + + /* If so, then remove the thread's structure from the private + * data set. After this point, no other thread can perform a join + * operation. + */ + + (void)pthread_removejoininfo(pid); + (void)pthread_givesemaphore(&g_join_semaphore); + + /* Destroy this thread data structure. */ + + pthread_destroyjoininfo(pjoin); + + /* Deallocate the join entry if it was detached. */ + + sched_free((void*)pjoin); + } + + /* No, then we can assume that some other thread is waiting for the join info */ + + else + { + /* Save the return exit value in the thread structure. */ + + pjoin->exit_value = exit_value; + + /* Destroy this thread data structure. */ + + pthread_destroyjoininfo(pjoin); + + /* pthread_join may now access the thread entry structure. */ + + (void)pthread_givesemaphore(&g_join_semaphore); + } + } + + return OK; +} diff --git a/nuttx/sched/pthread_condattrdestroy.c b/nuttx/sched/pthread_condattrdestroy.c new file mode 100644 index 000000000..a12c3f57c --- /dev/null +++ b/nuttx/sched/pthread_condattrdestroy.c @@ -0,0 +1,82 @@ +/************************************************************ + * pthread_condattrdestroy.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Global Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_condattr_destroy + * + * Description: + * Operations on condition variable attributes + * + * Parameters: + * None + * + * Return Value: + * None + * + * Assumptions: + * + ************************************************************/ + +int pthread_condattr_destroy(pthread_condattr_t *attr) +{ + int ret = OK; + + dbg("%s: attr=0x%p\n", __FUNCTION__, attr); + + if (!attr) + { + ret = EINVAL; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + + diff --git a/nuttx/sched/pthread_condattrinit.c b/nuttx/sched/pthread_condattrinit.c new file mode 100644 index 000000000..739b703ff --- /dev/null +++ b/nuttx/sched/pthread_condattrinit.c @@ -0,0 +1,85 @@ +/************************************************************ + * pthread_condattrinit.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <debug.h> +#include <errno.h> +#include "pthread_internal.h" + +/************************************************************ + * Global Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_condattr_init + * + * Description: + * Operations on condition variable attributes + * + * Parameters: + * None + * + * Return Value: + * None + * + * Assumptions: + * + ************************************************************/ + +int pthread_condattr_init(pthread_condattr_t *attr) +{ + int ret = OK; + + dbg("%s: attr=0x%p\n", __FUNCTION__, attr); + + if (!attr) + { + ret = EINVAL; + } + else + { + *attr = 0; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + diff --git a/nuttx/sched/pthread_condbroadcast.c b/nuttx/sched/pthread_condbroadcast.c new file mode 100644 index 000000000..322a4d288 --- /dev/null +++ b/nuttx/sched/pthread_condbroadcast.c @@ -0,0 +1,142 @@ +/************************************************************ + * pthread_condbroadcast.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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_cond_broadcast + * + * Description: + * A thread broadcast on a condition variable. + * + * Parameters: + * None + * + * Return Value: + * None + * + * Assumptions: + * + ************************************************************/ + +int pthread_cond_broadcast(pthread_cond_t *cond) +{ + int ret = OK; + int sval; + + dbg("%s: cond=0x%p\n", __FUNCTION__, 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(); + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + diff --git a/nuttx/sched/pthread_conddestroy.c b/nuttx/sched/pthread_conddestroy.c new file mode 100644 index 000000000..527200857 --- /dev/null +++ b/nuttx/sched/pthread_conddestroy.c @@ -0,0 +1,87 @@ +/************************************************************ + * pthread_conddestroy.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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(pthread_cond_t *cond) +{ + int ret = OK; + + dbg("%s: cond=0x%p\n", __FUNCTION__, cond); + + if (!cond) + { + ret = EINVAL; + } + + /* Destroy the semaphore contained in the structure */ + + else if (sem_destroy((sem_t*)&cond->sem) != OK) + { + ret = EINVAL; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + diff --git a/nuttx/sched/pthread_condinit.c b/nuttx/sched/pthread_condinit.c new file mode 100644 index 000000000..9dac4692f --- /dev/null +++ b/nuttx/sched/pthread_condinit.c @@ -0,0 +1,91 @@ +/************************************************************ + * pthread_condinit.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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(pthread_cond_t *cond, pthread_condattr_t *attr) +{ + int ret = OK; + + dbg("%s: cond=0x%p attr=0x%p\n", __FUNCTION__, 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; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + + diff --git a/nuttx/sched/pthread_condsignal.c b/nuttx/sched/pthread_condsignal.c new file mode 100644 index 000000000..f9ee3781d --- /dev/null +++ b/nuttx/sched/pthread_condsignal.c @@ -0,0 +1,126 @@ +/************************************************************ + * pthread_condsignal.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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(pthread_cond_t *cond) +{ + int ret = OK; + int sval; + + dbg("%s: cond=0x%p\n", __FUNCTION__, 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 + { + dbg("%s: sval=%d\n", __FUNCTION__, sval); + if (sval < 0) + { + dbg("%s: Signalling...\n", __FUNCTION__); + ret = pthread_givesemaphore((sem_t*)&cond->sem); + } + } + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + diff --git a/nuttx/sched/pthread_condtimedwait.c b/nuttx/sched/pthread_condtimedwait.c new file mode 100644 index 000000000..f65122699 --- /dev/null +++ b/nuttx/sched/pthread_condtimedwait.c @@ -0,0 +1,306 @@ +/************************************************************ + * pthread_condtimedwait.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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 + ************************************************************/ + +#define ECHO_COND_WAIT_SIGNO 3 + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +static void pthread_condtimedout(int pid, int signo, int arg3, int arg4) +{ + union sigval value; + + /* Send the specified signal to the specified task. */ + + value.sival_ptr = 0; + (void)sigqueue(pid, signo, value); +} + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_cond_timedwait + * + * Description: + * A thread can perform a timed wait on a condition variable. + * + * Parameters: + * None + * + * Return Value: + * None + * + * Assumptions: + * Timing is of resolution 1 msec, with +/-1 millisecond + * accuracy. + * + ************************************************************/ + +int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + struct timespec currtime; + struct timespec reltime; + WDOG_ID wdog; + sint32 relusec; + sint32 ticks; + int mypid = (int)getpid(); + int ret = OK; + int int_state; + int status; + + dbg("%s: cond=0x%p mutex=0x%p abstime=0x%p\n", + __FUNCTION__, 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 + { + dbg("%s: Give up mutex...\n", __FUNCTION__); + + /* 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. + * NOTE: Here we use internal knowledge that CLOCK_REALTIME is + * defined to be zero! + */ + + ret = clock_gettime(0, &currtime); + if (ret) + { + /* Restore interrupts (pre-emption will be enabled when + * we fall through the if/then/else + */ + + irqrestore(int_state); + } + else + { + /* The relative time to wait is the absolute time minus the + * 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.*/ + + relusec = + reltime.tv_sec * USEC_PER_SEC + + reltime.tv_nsec / NSEC_PER_USEC; + + /* Convert microseconds to clock ticks */ + + ticks = relusec / USEC_PER_TICK; + + /* 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, + mypid, ECHO_COND_WAIT_SIGNO, 0, 0); + + /* 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); + irqrestore(int_state); + + /* 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) + { + dbg("%s: Timedout!\n", __FUNCTION__); + ret = ETIMEDOUT; + } + else + { + ret = EINVAL; + } + } + } + + /* Reacquire the mutex (retaining the ret). */ + + dbg("%s: Re-locking...\n", __FUNCTION__); + 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); + } + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + diff --git a/nuttx/sched/pthread_condwait.c b/nuttx/sched/pthread_condwait.c new file mode 100644 index 000000000..555d3d06f --- /dev/null +++ b/nuttx/sched/pthread_condwait.c @@ -0,0 +1,137 @@ +/************************************************************ + * pthread_condwait.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + int ret; + + dbg("%s: cond=0x%p mutex=0x%p\n", __FUNCTION__, 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 */ + + dbg("%s: Give up mutex / take cond\n", __FUNCTION__); + + 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 */ + + dbg("%s: Reacquire mutex...\n", __FUNCTION__); + ret |= pthread_takesemaphore((sem_t*)&mutex->sem); + if (!ret) + { + mutex->pid = getpid();; + } + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + diff --git a/nuttx/sched/pthread_create.c b/nuttx/sched/pthread_create.c new file mode 100644 index 000000000..c8ec604d1 --- /dev/null +++ b/nuttx/sched/pthread_create.c @@ -0,0 +1,342 @@ +/************************************************************ + * pthread_create.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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.h> +#include <sched.h> +#include <debug.h> +#include <errno.h> +#include <queue.h> +#include <nuttx/kmalloc.h> +#include <nuttx/arch.h> +#include "os_internal.h" +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/* Default pthread attributes */ + +pthread_attr_t g_default_pthread_attr = +{ + .stacksize = PTHREAD_STACK_DEFAULT, + .priority = PTHREAD_DEFAULT_PRIORITY, + .policy = SCHED_RR, + .inheritsched = PTHREAD_EXPLICIT_SCHED, +}; + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_addjoininfo + * + * Description: + * Add a join_t to the local data set. + * + * Parameters: + * pjoin + * + * Return Value: + * None or pointer to the found entry. + * + * Assumptions: + * The caller has provided protection from re-entrancy. + * + ************************************************************/ + +static void pthread_addjoininfo(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) +{ + _TCB *ptcb = (_TCB*)g_readytorun.head; + join_t *pjoin = (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 + * startRoutine + * arg + ************************************************************/ + +int pthread_create(pthread_t *thread, pthread_attr_t *attr, + pthread_startroutine_t startRoutine, + pthread_addr_t arg) +{ + _TCB *ptcb; + join_t *pjoin; + STATUS 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 = (_TCB*)kzmalloc(sizeof(_TCB)); + if (!ptcb) + { + *get_errno_ptr() = ENOMEM; + return ERROR; + } + + /* Associate file descriptors with the new task */ + + if (sched_setuppthreadfiles(ptcb) != OK) + { + sched_releasetcb(ptcb); + return ERROR; + } + + /* Allocate a detachable structure to support pthread_join logic */ + + pjoin = (join_t*)kzmalloc(sizeof(join_t)); + if (!pjoin) + { + sched_releasetcb(ptcb); + return ERROR; + } + + /* Allocate the stack for the TCB */ + + status = up_create_stack(ptcb, attr->stacksize); + if (status != OK) + { + sched_releasetcb(ptcb); + sched_free(pjoin); + return ERROR; + } + + /* 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 of this thread. */ + + struct sched_param param; + status = sched_getparam(0, ¶m); + if (status == OK) + { + priority = param.sched_priority; + } + + /* 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 + } + + /* Initialize the task */ + + status = _task_init(ptcb, NULL, priority, pthread_start, (main_t)startRoutine, + TRUE, (char*)arg, NULL, NULL, NULL); + if (status != OK) + { + + sched_releasetcb(ptcb); + sched_free(pjoin); + return ERROR; + } + + /* 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; + } +#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.pid = 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->pid = pid; + if (!pjoin->started) status = ERROR; + + sched_unlock(); + (void)sem_destroy(&pjoin->data_sem); + } + else + { + sched_unlock(); + dq_rem((dq_entry_t*)ptcb, &g_inactivetasks); + (void)sem_destroy(&pjoin->data_sem); + (void)sem_destroy(&pjoin->exit_sem); + sched_releasetcb(ptcb); + sched_free(pjoin); + return ERROR; + } + return OK; +} diff --git a/nuttx/sched/pthread_detach.c b/nuttx/sched/pthread_detach.c new file mode 100644 index 000000000..967ed237f --- /dev/null +++ b/nuttx/sched/pthread_detach.c @@ -0,0 +1,134 @@ +/************************************************************ + * pthread_detach.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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_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) +{ + join_t *pjoin; + int ret; + + dbg("%s: Thread=%d\n", __FUNCTION__, thread.pid); + + /* Find the entry associated with this pthread. */ + + (void)pthread_takesemaphore(&g_join_semaphore); + pjoin = pthread_findjoininfo(thread.pid); + if (!pjoin) + { + dbg("%s: Could not find thread entry\n", __FUNCTION__); + ret = EINVAL; + } + else + { + /* Has the thread already terminated? */ + + if (pjoin->terminated) + { + /* YES.. just remove the thread entry. */ + + (void)pthread_removejoininfo(thread.pid); + sched_free(pjoin); + pjoin = NULL; + } + 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); + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_exit.c b/nuttx/sched/pthread_exit.c new file mode 100644 index 000000000..5330ee3f0 --- /dev/null +++ b/nuttx/sched/pthread_exit.c @@ -0,0 +1,119 @@ +/************************************************************ + * pthread_exit.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <stdlib.h> +#include <unistd.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(void *exit_value) +{ + int error_code = (int)exit_value; + int status; + + dbg("%s: exit_value=%p\n", __FUNCTION__, exit_value); + + /* 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() funcitons. + */ + + _exit(error_code); +} diff --git a/nuttx/sched/pthread_findjoininfo.c b/nuttx/sched/pthread_findjoininfo.c new file mode 100644 index 000000000..48871cf80 --- /dev/null +++ b/nuttx/sched/pthread_findjoininfo.c @@ -0,0 +1,98 @@ +/************************************************************ + * pthread_findjoininfo.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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: 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. + * + ************************************************************/ + +join_t *pthread_findjoininfo(int pid) +{ + join_t *pjoin; + + /* Find the entry with the matching pid */ + + for (pjoin = g_pthread_head; + (pjoin && pjoin->thread.pid != 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..0a30fba8f --- /dev/null +++ b/nuttx/sched/pthread_getschedparam.c @@ -0,0 +1,123 @@ +/************************************************************ + * pthread_getschedparam.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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: + * Obtain the thread scheduling parameters. + * + * Parameters: + * thread + * policy + * param + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_getschedparam(pthread_t thread, int *policy, + struct sched_param *param) +{ + int ret; + + dbg("%s: thread ID=%d policy=0x%p param=0x%p\n", + __FUNCTION__, thread.pid, policy, param); + + if (!policy || !param) + { + ret = EINVAL; + } + else + { + /* Get the schedparams of the thread. */ + + ret = sched_getparam(thread.pid, param); + if (ret != OK) + { + ret = EINVAL; + } + + /* Return the policy. */ + + *policy = sched_getscheduler(thread.pid); + if (*policy == ERROR) + { + ret = *get_errno_ptr(); + } + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + diff --git a/nuttx/sched/pthread_getspecific.c b/nuttx/sched/pthread_getspecific.c new file mode 100644 index 000000000..886557f38 --- /dev/null +++ b/nuttx/sched/pthread_getspecific.c @@ -0,0 +1,119 @@ +/************************************************************ + * pthread_getspecific.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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. + * + ************************************************************/ + +void *pthread_getspecific(pthread_key_t key) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + 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; +} diff --git a/nuttx/sched/pthread_initialize.c b/nuttx/sched/pthread_initialize.c new file mode 100644 index 000000000..e1b24f432 --- /dev/null +++ b/nuttx/sched/pthread_initialize.c @@ -0,0 +1,193 @@ +/************************************************************ + * pthread_initialize.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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. + */ + +join_t *g_pthread_head = NULL; +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. + */ + +ubyte 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: + * None + * + * 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..d0b1cdeb9 --- /dev/null +++ b/nuttx/sched/pthread_internal.h @@ -0,0 +1,129 @@ +/************************************************************ + * pthread_internal.h + * + * 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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (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 __PTHREAD_INTERNAL_H +#define __PTHREAD_INTERNAL_H + +/************************************************************ + * Included Files + ************************************************************/ + +#include <sys/types.h> +#include <pthread.h> +#include <nuttx/compiler.h> + +/************************************************************ + * 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 +{ + struct join_s *next; /* Implements link list */ + boolean started; /* TRUE: pthread started. */ + boolean detached; /* TRUE: pthread_detached'ed */ + boolean 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 join_t *g_pthread_head; +extern 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 ubyte g_pthread_num_keys; + +/* Default pthread attributes */ + +extern pthread_attr_t g_default_pthread_attr; + +/************************************************************ + * 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, void *exit_value); +EXTERN join_t *pthread_findjoininfo(int pid); +EXTERN int pthread_givesemaphore(sem_t *sem); +EXTERN join_t *pthread_removejoininfo(int pid); +EXTERN int pthread_takesemaphore(sem_t *sem); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __PTHREAD_INTERNAL_H */ + diff --git a/nuttx/sched/pthread_join.c b/nuttx/sched/pthread_join.c new file mode 100644 index 000000000..4e956777c --- /dev/null +++ b/nuttx/sched/pthread_join.c @@ -0,0 +1,213 @@ +/************************************************************ + * pthread_join.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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, pthread_addr_t *pexit_value) +{ + join_t *pjoin; + int ret; + + dbg("%s: thread=%d\n", __FUNCTION__, thread.pid); + + /* First make sure that this is not an attempt to join to + * ourself. + */ + + if (thread.pid == 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(thread.pid); + if (!pjoin) + { + /* Determine what kind of error to return */ + + _TCB *tcb = sched_gettcb(thread.pid); + + dbg("%s: Could not find thread data\n", __FUNCTION__); + + /* 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 /* if ((tcb->flags & EDEADLK) == 0) */ + { + ret = EINVAL; + } + + (void)pthread_givesemaphore(&g_join_semaphore); + } + else if (pjoin->terminated) + { + dbg("%s: Thread has terminated\n", __FUNCTION__); + + /* Get the thread exit value from the terminated thread. */ + + if (pexit_value) + { + dbg("%s: exit_value=0x%p\n", __FUNCTION__, pjoin->exit_value); + *pexit_value = pjoin->exit_value; + } + + /* Then remove and deallocate the thread entry. */ + + (void)pthread_removejoininfo(thread.pid); + (void)pthread_givesemaphore(&g_join_semaphore); + sched_free(pjoin); + ret = OK; + } + else + { + dbg("%s: Thread is still running\n", __FUNCTION__); + + /* Relinquish the data set semaphore, making certain that + * no task has the opportunity to run between the time + * we relinquish the data set semaphore and the time that + * we wait on the join semaphore. + */ + + sched_lock(); + (void)pthread_givesemaphore(&g_join_semaphore); + + /* Take the thread's join semaphore */ + + (void)pthread_takesemaphore(&pjoin->exit_sem); + + /* Get the thread exit value */ + + if (pexit_value) + { + *pexit_value = pjoin->exit_value; + dbg("%s: exit_value=0x%p\n", __FUNCTION__, pjoin->exit_value); + } + + /* Post the thread's join semaphore so that exitting thread + * will know that we have received the data. + */ + + (void)pthread_givesemaphore(&pjoin->data_sem); + + /* Pre-emption is okay now. */ + + sched_unlock(); + + ret = OK; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_keycreate.c b/nuttx/sched/pthread_keycreate.c new file mode 100644 index 000000000..bda51e53a --- /dev/null +++ b/nuttx/sched/pthread_keycreate.c @@ -0,0 +1,135 @@ +/************************************************************ + * pthread_keycreate.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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 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(pthread_key_t *key, void (*destructor)(void*)) +{ + 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; +} diff --git a/nuttx/sched/pthread_keydelete.c b/nuttx/sched/pthread_keydelete.c new file mode 100644 index 000000000..486de00d8 --- /dev/null +++ b/nuttx/sched/pthread_keydelete.c @@ -0,0 +1,93 @@ +/************************************************************ + * pthread_keydelete.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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_mutexattrdestroy.c b/nuttx/sched/pthread_mutexattrdestroy.c new file mode 100644 index 000000000..8e3abdb47 --- /dev/null +++ b/nuttx/sched/pthread_mutexattrdestroy.c @@ -0,0 +1,104 @@ +/************************************************************ + * pthread_mutexattrdestroy.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <errno.h> +#include <debug.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_mutexattr_destroy + * + * Description: + * Destroy mutex attributes. + * + * Parameters: + * attr + * pshared + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) +{ + int ret = OK; + + dbg("%s: attr=0x%p\n", __FUNCTION__, attr); + + if (!attr) + { + ret = EINVAL; + } + else + { + attr->pshared = 0; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_mutexattrgetpshared.c b/nuttx/sched/pthread_mutexattrgetpshared.c new file mode 100644 index 000000000..1d54b9012 --- /dev/null +++ b/nuttx/sched/pthread_mutexattrgetpshared.c @@ -0,0 +1,104 @@ +/************************************************************ + * pthread_mutexattrgetpshared.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <errno.h> +#include <debug.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_mutexattr_getpshared + * + * Description: + * Get pshared mutex attribute. + * + * Parameters: + * attr + * pshared + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared) +{ + int ret = OK; + + dbg("%s: attr=0x%p pshared=0x%p\n", __FUNCTION__, attr, pshared); + + if (!attr || !pshared) + { + ret = EINVAL; + } + else + { + *pshared = attr->pshared; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_mutexattrinit.c b/nuttx/sched/pthread_mutexattrinit.c new file mode 100644 index 000000000..920ccf0ee --- /dev/null +++ b/nuttx/sched/pthread_mutexattrinit.c @@ -0,0 +1,103 @@ +/************************************************************ + * pthread_mutexattrinit.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <errno.h> +#include <debug.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_mutexattr_init + * + * Description: + * Create mutex attributes. + * + * Parameters: + * attr + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_mutexattr_init(pthread_mutexattr_t *attr) +{ + int ret = OK; + + dbg("%s: attr=0x%p\n", __FUNCTION__, attr); + + if (!attr) + { + ret = EINVAL; + } + else + { + attr->pshared = 0; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_mutexattrsetpshared.c b/nuttx/sched/pthread_mutexattrsetpshared.c new file mode 100644 index 000000000..a9ddd0c3c --- /dev/null +++ b/nuttx/sched/pthread_mutexattrsetpshared.c @@ -0,0 +1,104 @@ +/************************************************************ + * pthread_mutexattrsetpshared.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <errno.h> +#include <debug.h> +#include "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_mutexattr_setpshared + * + * Description: + * Set pshared mutex attribute. + * + * Parameters: + * attr + * pshared + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) +{ + int ret = OK; + + dbg("%s: attr=0x%p pshared=%d\n", __FUNCTION__, attr, pshared); + + if (!attr || (pshared != 0 && pshared != 1)) + { + ret = EINVAL; + } + else + { + attr->pshared = pshared; + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_mutexdestroy.c b/nuttx/sched/pthread_mutexdestroy.c new file mode 100644 index 000000000..bf82d4f43 --- /dev/null +++ b/nuttx/sched/pthread_mutexdestroy.c @@ -0,0 +1,128 @@ +/************************************************************ + * pthread_mutexdestroy.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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(pthread_mutex_t *mutex) +{ + int ret = OK; + int status; + + dbg("%s: mutex=0x%p\n", __FUNCTION__, 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(); + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_mutexinit.c b/nuttx/sched/pthread_mutexinit.c new file mode 100644 index 000000000..faa06f227 --- /dev/null +++ b/nuttx/sched/pthread_mutexinit.c @@ -0,0 +1,122 @@ +/************************************************************ + * pthread_mutexinit.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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(pthread_mutex_t *mutex, pthread_mutexattr_t *attr) +{ + int ret = OK; + int pshared = 0; + int status; + + dbg("%s: mutex=0x%p attr=0x%p\n", __FUNCTION__, mutex, attr); + + if (!mutex) + { + ret = EINVAL; + } + else + { + /* Were attributes specified? If so, use them */ + + if (attr) + { + pshared = attr->pshared; + } + + /* 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; + } + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_mutexlock.c b/nuttx/sched/pthread_mutexlock.c new file mode 100644 index 000000000..43e7c8356 --- /dev/null +++ b/nuttx/sched/pthread_mutexlock.c @@ -0,0 +1,138 @@ +/************************************************************ + * pthread_mutexlock.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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: + * Lock a mutex. + * + * Parameters: + * None + * + * Return Value: + * None + * + * Assumptions: + * + ************************************************************/ + +int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + int mypid = (int)getpid(); + int ret = OK; + + dbg("%s: mutex=0x%p\n", __FUNCTION__, 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) + { + dbg("%s: Returning EDEADLK\n", __FUNCTION__); + 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; + } + } + sched_unlock(); + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + + + diff --git a/nuttx/sched/pthread_mutextrylock.c b/nuttx/sched/pthread_mutextrylock.c new file mode 100644 index 000000000..010c85f80 --- /dev/null +++ b/nuttx/sched/pthread_mutextrylock.c @@ -0,0 +1,137 @@ +/************************************************************ + * pthread_mutextrylock.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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: + * Attempt to lock a mutex + * + * Parameters: + * None + * + * Return Value: + * None + * + * Assumptions: + * + ************************************************************/ + +int pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + int ret = OK; + + dbg("%s: mutex=0x%p\n", __FUNCTION__, 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(); + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + + diff --git a/nuttx/sched/pthread_mutexunlock.c b/nuttx/sched/pthread_mutexunlock.c new file mode 100644 index 000000000..133dc1a94 --- /dev/null +++ b/nuttx/sched/pthread_mutexunlock.c @@ -0,0 +1,127 @@ +/************************************************************ + * pthread_mutexunlock.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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: + * Unlock a mutex. + * + * Parameters: + * None + * + * Return Value: + * None + * + * Assumptions: + * + ************************************************************/ + +int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + int ret = OK; + + dbg("%s: mutex=0x%p\n", __FUNCTION__, 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()) + { + dbg("%s: Holder=%d Returning EPERM\n", __FUNCTION__, mutex->pid); + ret = EPERM; + } + else + { + /* Nulllify the pid and post the semaphore */ + + mutex->pid = 0; + ret = pthread_givesemaphore((sem_t*)&mutex->sem); + } + sched_unlock(); + } + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} + + diff --git a/nuttx/sched/pthread_removejoininfo.c b/nuttx/sched/pthread_removejoininfo.c new file mode 100644 index 000000000..ecdc6d99e --- /dev/null +++ b/nuttx/sched/pthread_removejoininfo.c @@ -0,0 +1,136 @@ +/************************************************************ + * pthread_removejoininfo.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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. + * + ************************************************************/ + +join_t *pthread_removejoininfo(int pid) +{ + join_t *prev; + join_t *join; + + /* Find the entry with the matching pid */ + + for (prev = NULL, join = g_pthread_head; + (join && join->thread.pid != 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_self.c b/nuttx/sched/pthread_self.c new file mode 100644 index 000000000..55ceddbdd --- /dev/null +++ b/nuttx/sched/pthread_self.c @@ -0,0 +1,91 @@ +/************************************************************ + * pthread_self.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 "pthread_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: pthread_self + * + * Description: + * A thread may obtain a copy of its own thread handle. + * + * Parameters: + * None + * + * Return Value: + * A copy of this threads handle + * + * Assumptions: + * + ************************************************************/ + +pthread_t pthread_self(void) +{ + pthread_t thread; + thread.pid = (int)getpid(); + return thread; +} + diff --git a/nuttx/sched/pthread_setcancelstate.c b/nuttx/sched/pthread_setcancelstate.c new file mode 100644 index 000000000..4a23b1068 --- /dev/null +++ b/nuttx/sched/pthread_setcancelstate.c @@ -0,0 +1,127 @@ +/************************************************************************** + * pthread_setcancelstate.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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, 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..5d0f913c2 --- /dev/null +++ b/nuttx/sched/pthread_setschedparam.c @@ -0,0 +1,103 @@ +/************************************************************ + * pthread_setschedparam.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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: + * Set thread scheduling parameters. + * + * Parameters: + * thread + * policy + * param + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + * Assumptions: + * + ************************************************************/ + +int pthread_setschedparam(pthread_t thread, int policy, + const struct sched_param *param) +{ + int ret; + + dbg("%s: thread ID=%d policy=%d param=0x%p\n", + __FUNCTION__, thread.pid, policy, param); + + /* Let sched_setscheduler do all of the work */ + + ret = sched_setscheduler(thread.pid, policy, param); + + dbg("%s: Returning %d\n", __FUNCTION__, ret); + return ret; +} diff --git a/nuttx/sched/pthread_setspecific.c b/nuttx/sched/pthread_setspecific.c new file mode 100644 index 000000000..c08a18190 --- /dev/null +++ b/nuttx/sched/pthread_setspecific.c @@ -0,0 +1,131 @@ +/************************************************************ + * pthread_setspecific.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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, void *value) +{ + _TCB *rtcb = (_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; +} diff --git a/nuttx/sched/pthread_yield.c b/nuttx/sched/pthread_yield.c new file mode 100644 index 000000000..06d68e5a1 --- /dev/null +++ b/nuttx/sched/pthread_yield.c @@ -0,0 +1,87 @@ +/************************************************************ + * pthread_yield.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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..195937832 --- /dev/null +++ b/nuttx/sched/sched_addblocked.c @@ -0,0 +1,117 @@ +/************************************************************ + * sched_addblocked.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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(_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, g_tasklisttable[task_state].list); + } + else + { + /* Add the task to a non-prioritized list */ + + dq_addlast((dq_entry_t*)btcb, 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..54e792048 --- /dev/null +++ b/nuttx/sched/sched_addprioritized.c @@ -0,0 +1,170 @@ +/************************************************************ + * sched_addprioritized.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <queue.h> +#include <assert.h> +#include "os_internal.h" + +/************************************************************ + * 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. + ************************************************************/ + +boolean sched_addprioritized(_TCB *tcb, dq_queue_t *list) +{ + _TCB *next; + _TCB *prev; + ubyte sched_priority = tcb->sched_priority; + boolean 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 = (_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 = (_TCB*)list->tail; + if (!prev) + { + /* Special case: The list is empty */ + + tcb->flink = NULL; + tcb->blink = NULL; + list->head = (dq_entry_t*)tcb; + list->tail = (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 = (dq_entry_t*)tcb; + } + } + else + { + /* The tcb goes just before next */ + + prev = (_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 = (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..c52da3670 --- /dev/null +++ b/nuttx/sched/sched_addreadytorun.c @@ -0,0 +1,144 @@ +/************************************************************ + * sched_addreadytorun.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <queue.h> +#include <assert.h> +#include "os_internal.h" + +/************************************************************ + * 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. + ************************************************************/ + +boolean sched_addreadytorun(_TCB *btcb) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + boolean ret; + + /* Check if pre-emption is disabled for the current running task and + * if the rtrTask would cause the current running task to be preempted. + */ + + if (rtcb->lockcount && rtcb->sched_priority < btcb->sched_priority) + { + /* Yes. Preemption would occur! Add the btcb to the g_pendingtasks + * task list for now. + */ + + sched_addprioritized(btcb, &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, &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_free.c b/nuttx/sched/sched_free.c new file mode 100644 index 000000000..205da0a46 --- /dev/null +++ b/nuttx/sched/sched_free.c @@ -0,0 +1,103 @@ +/************************************************************ + * sched_free.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <nuttx/kmalloc.h> +#include <queue.h> +#include <assert.h> +#include <nuttx/arch.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(void *address) +{ + /* Check if this is an attempt to deallocate memory from + * an exception handler. + */ + + if (up_interrupt_context()) + { + /* Yes.. Delay the deallocation until a more appropriate time. */ + + uint32 savedState = irqsave(); + sq_addlast((sq_entry_t*)address, &g_delayeddeallocations); + irqrestore(savedState); + } + else + { + /* No.. just deallocate the memory now. */ + + kfree(address); + } +} diff --git a/nuttx/sched/sched_getfiles.c b/nuttx/sched/sched_getfiles.c new file mode 100644 index 000000000..d6986a5bc --- /dev/null +++ b/nuttx/sched/sched_getfiles.c @@ -0,0 +1,77 @@ +/************************************************************ + * sched_getfiles.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <nuttx/config.h> + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#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: + * + ************************************************************/ + +struct filelist *sched_getfiles(void) +{ + _TCB *rtcb = (_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..85d8c55c7 --- /dev/null +++ b/nuttx/sched/sched_getparam.c @@ -0,0 +1,142 @@ +/************************************************************ + * sched_getparam.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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) +{ + _TCB *rtcb; + _TCB *tcb; + int ret = OK; + + if (!param) + { + return ERROR; + } + + /* Check if the task to restart is the calling task */ + + rtcb = (_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_getprioritymax.c b/nuttx/sched/sched_getprioritymax.c new file mode 100644 index 000000000..f137b72c6 --- /dev/null +++ b/nuttx/sched/sched_getprioritymax.c @@ -0,0 +1,102 @@ +/************************************************************ + * sched_getprioritymax.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 <nuttx/arch.h> +#include <nuttx/os_external.h> +#include "os_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Name: ched_get_priority_max + * + * Description: + * This function returns the value of the highest possible + * task priority for a specified scheduling policy. + * + * Inputs: + * policy - Scheduling policy requested. + * + * Return Value: + * The maximum priority value or -1 (ERROR) + * (errno is not set) + * + * Assumptions: + * + ************************************************************/ + +int sched_get_priority_max(int policy) +{ + if (policy != SCHED_FIFO) + { + return ERROR; + } + else + { + return SCHED_PRIORITY_MAX; + } +} diff --git a/nuttx/sched/sched_getprioritymin.c b/nuttx/sched/sched_getprioritymin.c new file mode 100644 index 000000000..154432c66 --- /dev/null +++ b/nuttx/sched/sched_getprioritymin.c @@ -0,0 +1,102 @@ +/************************************************************ + * sched_getprioritymin.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 <nuttx/arch.h> +#include <nuttx/os_external.h> +#include "os_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Name: sched_get_priority_min + * + * Description: + * This function returns the value of the lowest possible + * task priority for a specified scheduling policy. + * + * Inputs: + * policy - Scheduling policy requested. + * + * Return Value: + * The minimum priority value or -1 (ERROR) + * (errno is not set) + * + * Assumptions: + * + ************************************************************/ + +int sched_get_priority_min(int policy) +{ + if (policy != SCHED_FIFO) + { + return ERROR; + } + else + { + return SCHED_PRIORITY_MIN; + } +} diff --git a/nuttx/sched/sched_getscheduler.c b/nuttx/sched/sched_getscheduler.c new file mode 100644 index 000000000..9406d9774 --- /dev/null +++ b/nuttx/sched/sched_getscheduler.c @@ -0,0 +1,130 @@ +/************************************************************ + * sched_getscheduler.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 <nuttx/os_external.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 = 0) + { + 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_getstreams.c b/nuttx/sched/sched_getstreams.c new file mode 100644 index 000000000..fef913bc4 --- /dev/null +++ b/nuttx/sched/sched_getstreams.c @@ -0,0 +1,77 @@ +/************************************************************ + * sched_getstreams.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <nuttx/config.h> + +#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 + +#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: + * + ************************************************************/ + +struct streamlist *sched_getstreams(void) +{ + _TCB *rtcb = (_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..7073b796a --- /dev/null +++ b/nuttx/sched/sched_gettcb.c @@ -0,0 +1,104 @@ +/************************************************************ + * sched_gettcb.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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). + * + ************************************************************/ + +_TCB *sched_gettcb(pid_t pid) +{ + _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..344d3d75b --- /dev/null +++ b/nuttx/sched/sched_lock.c @@ -0,0 +1,109 @@ +/************************************************************ + * sched_lock.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 <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 + * + ************************************************************/ + +STATUS 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..8db9b116b --- /dev/null +++ b/nuttx/sched/sched_lockcount.c @@ -0,0 +1,93 @@ +/************************************************************ + * sched_lockcount.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 "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, preemption is enabled; if non-zero, this value + * indicates the number of times that osTask() has been + * called on this thread of execution. + * + * Inputs: + * None + * + * Return Value: + * lockcount + * + ************************************************************/ + +sint32 sched_lockcount(void) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + return (sint32)rtcb->lockcount; +} diff --git a/nuttx/sched/sched_mergepending.c b/nuttx/sched/sched_mergepending.c new file mode 100644 index 000000000..db03bccc3 --- /dev/null +++ b/nuttx/sched/sched_mergepending.c @@ -0,0 +1,168 @@ +/************************************************************ + * sched_mergepending.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <queue.h> +#include <assert.h> +#include "os_internal.h" + +/************************************************************ + * 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. + * + ************************************************************/ + +boolean sched_mergepending(void) +{ + _TCB *pndtcb; + _TCB *pndnext; + _TCB *rtrtcb; + _TCB *rtrprev; + boolean ret = FALSE; + + /* Initialize the inner search loop */ + + rtrtcb = (_TCB*)g_readytorun.head; + + /* Process every TCB in the g_pendingtasks list */ + + for (pndtcb = (_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 = (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..2ab4c4bfa --- /dev/null +++ b/nuttx/sched/sched_processtimer.c @@ -0,0 +1,181 @@ +/************************************************************ + * sched_processtimer.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <nuttx/config.h> +#include <sys/types.h> + +#if CONFIG_RR_INTERVAL > 0 +# include <sched.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 inline 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) + { + /* 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) + { + struct sched_param param; + + /* Reset the timeslice */ + + rtcb->timeslice = CONFIG_RR_INTERVAL; + + /* 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. + */ + + param.sched_priority = rtcb->sched_priority; + (void)sched_setparam(0, ¶m); + } + } + 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) */ + + if (clock_timer != NULL) + { + clock_timer(); + } + + /* Process watchdogs (if in the link) */ + + if (wd_timer != NULL) + { + 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..979aca22d --- /dev/null +++ b/nuttx/sched/sched_releasefiles.c @@ -0,0 +1,90 @@ +/************************************************************ + * sched_releasefiles.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <nuttx/config.h> + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#include <sched.h> +#include <nuttx/fs.h> +#include <nuttx/lib.h> + +/************************************************************ + * 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) + { + /* 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 */ + } + return OK; +} +#endif /* CONFIG_NFILE_DESCRIPTORS */ diff --git a/nuttx/sched/sched_releasetcb.c b/nuttx/sched/sched_releasetcb.c new file mode 100644 index 000000000..ffbfc6c58 --- /dev/null +++ b/nuttx/sched/sched_releasetcb.c @@ -0,0 +1,142 @@ +/************************************************************ + * sched_releasetcb.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <sched.h> +#include <errno.h> +#include <nuttx/arch.h> +#include "os_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: + * + ************************************************************/ + +int sched_releasetcb(_TCB *tcb) +{ + int ret = OK; + int i; + + if (tcb) + { + /* 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 */ + + if (tcb->stack_alloc_ptr) + { + up_release_stack(tcb); + } + + /* Release command line arguments that were allocated + * for task start/re-start. + */ + + if ((tcb->flags & TCB_FLAG_PTHREAD) == 0) + { + for (i = 1; i < NUM_TASK_ARGS+1 && tcb->argv[i]; i++) + { + sched_free(tcb->argv[i]); + } + } + + /* Release any allocated file structures */ + + ret = sched_releasefiles(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..f3ed363ae --- /dev/null +++ b/nuttx/sched/sched_removeblocked.c @@ -0,0 +1,113 @@ +/************************************************************ + * sched_removeblocked.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <sys/types.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(_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((dq_entry_t*)btcb, 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..24057f3b7 --- /dev/null +++ b/nuttx/sched/sched_removereadytorun.c @@ -0,0 +1,117 @@ +/************************************************************ + * sched_removereadytorun.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <queue.h> +#include <assert.h> +#include "os_internal.h" + +/************************************************************ + * 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. + ************************************************************/ + +boolean sched_removereadytorun(_TCB *rtcb) +{ + boolean 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) + { + 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((dq_entry_t*)rtcb, &g_readytorun); + + rtcb->task_state = TSTATE_TASK_INVALID; + return ret; +} diff --git a/nuttx/sched/sched_rrgetinterval.c b/nuttx/sched/sched_rrgetinterval.c new file mode 100644 index 000000000..8dfe99ff3 --- /dev/null +++ b/nuttx/sched/sched_rrgetinterval.c @@ -0,0 +1,156 @@ +/************************************************************ + * sched_rrgetinterval.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 <nuttx/os_external.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 + _TCB *rrtcb; + + /* If pid is zero, the timeslice for the calling process is + * written into 'interval.' + */ + + if (!pid) + { + rrtcb = (_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_errnor_ptr() = ENOSYS; + return ERROR; +#endif +} diff --git a/nuttx/sched/sched_setparam.c b/nuttx/sched/sched_setparam.c new file mode 100644 index 000000000..482b62ddb --- /dev/null +++ b/nuttx/sched/sched_setparam.c @@ -0,0 +1,266 @@ +/************************************************************ + * sched_setparam.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 <nuttx/os_external.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 the + * 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: + * OK if successful, otherwise ERROR. This function can + * fail for the following reasons: + * + * (1) parm is NULL or parm->sched_priority is out of + * range. + * (2) pid does not correspond to any task. + * + * (errno is not set). + * + * Assumptions: + * + ************************************************************/ + +int sched_setparam(pid_t pid, const struct sched_param *param) +{ + _TCB *rtcb; + _TCB *tcb; + tstate_t task_state; + uint32 saved_state; + int sched_priority = param->sched_priority; + int ret = 0; + + /* Verify that the requested priority is in the valid range */ + + if (!param || + param->sched_priority < SCHED_PRIORITY_MIN || + param->sched_priority > SCHED_PRIORITY_MAX) + { + 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 = (_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 */ + + sched_unlock(); + 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, (ubyte)sched_priority); + } + + /* Otherwise, we can just change priority since it has no effect */ + + else + { + /* Change the task priority */ + + tcb->sched_priority = (ubyte)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, (ubyte)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 = (ubyte)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((dq_entry_t*)tcb, g_tasklisttable[task_state].list); + + /* Change the task priority */ + + tcb->sched_priority = (ubyte)sched_priority; + + /* Put it back into the prioritized list at the correct + * position + */ + + sched_addprioritized(tcb, 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 = (ubyte)sched_priority; + } + break; + } + + irqrestore(saved_state); + sched_unlock(); + return ret; +} diff --git a/nuttx/sched/sched_setscheduler.c b/nuttx/sched/sched_setscheduler.c new file mode 100644 index 000000000..29c0d0c98 --- /dev/null +++ b/nuttx/sched/sched_setscheduler.c @@ -0,0 +1,188 @@ +/************************************************************ + * sched_setscheduler.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 <nuttx/os_external.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) +{ + _TCB *tcb; +#if CONFIG_RR_INTERVAL > 0 + uint32 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 + { + *get_errno_ptr() = 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) + { + *get_errno_ptr() = 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_setparam(pid, param); + 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..c8be5478c --- /dev/null +++ b/nuttx/sched/sched_setupidlefiles.c @@ -0,0 +1,113 @@ +/************************************************************ + * sched_setupidlefiles.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <nuttx/config.h> + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#include <stdio.h> +#include <unistd.h> +#include <sched.h> +#include <errno.h> +#include "os_internal.h" + +/************************************************************ + * 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(_TCB *tcb) +{ + int fd; + + /* Allocate file descriptors for the TCB */ + + tcb->filelist = files_alloclist(); + if (!tcb->filelist) + { + *get_errno_ptr() = ENOMEM; + return ERROR; + } + +#ifdef CONFIG_DEV_CONSOLE + /* Open stdin, dup to get stdout and stderr. */ + + fd = open("/dev/console", O_RDWR); + if (fd == 0) + { + (void)dup2(0, 1); + (void)dup2(0, 2); + } + else + { + (void)close(fd); + *get_errno_ptr() = ENFILE; + return ERROR; + } + +#if CONFIG_NFILE_STREAMS > 0 + /* Allocate file strems for the TCB */ + + return sched_setupstreams(tcb); +#else + return OK; +#endif /* CONFIG_NFILE_STREAMS */ +#endif /* CONFIG_DEV_CONSOLE */ +} + +#endif /* CONFIG_NFILE_DESCRIPTORS */ diff --git a/nuttx/sched/sched_setuppthreadfiles.c b/nuttx/sched/sched_setuppthreadfiles.c new file mode 100644 index 000000000..0935b487d --- /dev/null +++ b/nuttx/sched/sched_setuppthreadfiles.c @@ -0,0 +1,94 @@ +/************************************************************ + * sched_setuppthreadfiles.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <nuttx/config.h> + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#include <sched.h> +#include <nuttx/fs.h> +#include <nuttx/lib.h> +#include "os_internal.h" + +/************************************************************ + * 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: + * None + * + * Assumptions: + * + ************************************************************/ + +int sched_setuppthreadfiles(_TCB *tcb) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + + /* 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 */ + + return OK; +} + +#endif /* CONFIG_NFILE_DESCRIPTORS */ diff --git a/nuttx/sched/sched_setupstreams.c b/nuttx/sched/sched_setupstreams.c new file mode 100644 index 000000000..325ba92e9 --- /dev/null +++ b/nuttx/sched/sched_setupstreams.c @@ -0,0 +1,80 @@ +/************************************************************ + * sched_setupstreams.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <nuttx/config.h> + +#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 + +#include <sched.h> +#include <nuttx/fs.h> +#include <nuttx/lib.h> + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +int sched_setupstreams(_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 + * fd = 1 is stdout + * fd = 2 is stderr + */ + + (void)lib_fdopen(0, "r", tcb->filelist, tcb->streams); + (void)lib_fdopen(1, "w", tcb->filelist, tcb->streams); + (void)lib_fdopen(2, "w", tcb->filelist, tcb->streams); + } + + 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..269e98e51 --- /dev/null +++ b/nuttx/sched/sched_setuptaskfiles.c @@ -0,0 +1,112 @@ +/************************************************************ + * sched_setuptaskfiles.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <nuttx/config.h> + +#if CONFIG_NFILE_DESCRIPTORS > 0 + +#include <sched.h> +#include <errno.h> +#include <nuttx/fs.h> +#include "os_internal.h" + +/************************************************************ + * 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(_TCB *tcb) +{ +#ifdef CONFIG_DEV_CONSOLE + _TCB *rtcb = (_TCB*)g_readytorun.head; + int i; +#endif /* CONFIG_DEV_CONSOLE */ + + /* Allocate file descriptors for the TCB */ + + tcb->filelist = files_alloclist(); + if (!tcb->filelist) + { + *get_errno_ptr() = ENOMEM; + return ERROR; + } + +#ifdef CONFIG_DEV_CONSOLE + /* Duplicate the first three file descriptors */ + + if (rtcb->filelist) + { + for (i = 0; i < 3; i++) + { + (void)files_dup(&rtcb->filelist->fl_files[i], + &tcb->filelist->fl_files[i]); + } + } + +#if CONFIG_NFILE_STREAMS > 0 + /* Allocate file strems for the TCB */ + + return sched_setupstreams(tcb); +#else + return OK; +#endif /* CONFIG_NFILE_STREAMS */ +#endif /* CONFIG_DEV_CONSOLE */ +} + +#endif /* CONFIG_NFILE_DESCRIPTORS */ diff --git a/nuttx/sched/sched_unlock.c b/nuttx/sched/sched_unlock.c new file mode 100644 index 000000000..773b3dd71 --- /dev/null +++ b/nuttx/sched/sched_unlock.c @@ -0,0 +1,122 @@ +/************************************************************ + * sched_unlock.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 <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. + ************************************************************/ + +STATUS 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()) + { + /* 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(); + } + } + } + return OK; +} diff --git a/nuttx/sched/sched_yield.c b/nuttx/sched/sched_yield.c new file mode 100644 index 000000000..e91f8ecf6 --- /dev/null +++ b/nuttx/sched/sched_yield.c @@ -0,0 +1,103 @@ +/************************************************************ + * sched_yield.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 <nuttx/arch.h> +#include <nuttx/os_external.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) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + struct sched_param param; + + /* 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. + */ + + param.sched_priority = rtcb->sched_priority; + return sched_setparam(0, ¶m); +} diff --git a/nuttx/sched/sem_close.c b/nuttx/sched/sem_close.c new file mode 100644 index 000000000..3113b5156 --- /dev/null +++ b/nuttx/sched/sem_close.c @@ -0,0 +1,144 @@ +/************************************************************ + * sem_close.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <errno.h> +#include <semaphore.h> +#include <sched.h> +#include "os_internal.h" +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * 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 (sem_t *sem) +{ + nsem_t *psem; + int ret = ERROR; + + /* Verify the inputs */ + + if (sem) + { + sched_lock(); + + /* Search the list of named semaphores */ + + for (psem = (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((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..1d88563ff --- /dev/null +++ b/nuttx/sched/sem_destroy.c @@ -0,0 +1,122 @@ +/************************************************************ + * sem_destroy.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <semaphore.h> +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * 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 name 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 (sem_t *sem) +{ + int ret = ERROR; + + /* 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). + * + * 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; + } + ret = OK; + } + + return ret; +} diff --git a/nuttx/sched/sem_findnamed.c b/nuttx/sched/sem_findnamed.c new file mode 100644 index 000000000..d513f7a31 --- /dev/null +++ b/nuttx/sched/sem_findnamed.c @@ -0,0 +1,103 @@ +/************************************************************ + * sem_findnamed.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * 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 + * + ************************************************************/ + +nsem_t *sem_findnamed(const char *name) +{ + nsem_t *psem; + + /* Search the list of named semaphores */ + + for (psem = (nsem_t*)g_nsems.head; (psem); psem = psem->flink) + { + if (!strcmp(name, psem->name)) + { + break; + } + } + + return(psem); +} + diff --git a/nuttx/sched/sem_getvalue.c b/nuttx/sched/sem_getvalue.c new file mode 100644 index 000000000..b7dd201c7 --- /dev/null +++ b/nuttx/sched/sem_getvalue.c @@ -0,0 +1,112 @@ +/************************************************************ + * sem_getvalue.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <semaphore.h> +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: sem_getvalue + * + * Description: + * This function updates the location referenced by sval + * argument to have the value of the semaphore referenced + * by sem without effecting the state of the semaphore. + * The updated value represents the actual semaphore value + * that occurred at some unspecified time during the call, + * but may not reflect the actual value of the semaphore + * when it is returned to the calling task. + * + * If sem is locked, the value return by sem_getvalue() + * will either be zero or a negative number whose absolute + * value represents the number of tasks waiting for the + * semaphore. + * + * Parameters: + * sem - Semaphore descriptor + * sval - Buffer by which the value is returned + * + * Return Value: + * 0 (OK), or -1 (ERROR) if unsuccessful + * + * Assumptions: + * + ************************************************************/ + +int sem_getvalue(sem_t *sem, int *sval) +{ + int ret = ERROR; + + if (sem && sval) + { + *sval = sem->semcount; + ret = OK; + } + + return ret; +} + diff --git a/nuttx/sched/sem_init.c b/nuttx/sched/sem_init.c new file mode 100644 index 000000000..36f2b9942 --- /dev/null +++ b/nuttx/sched/sem_init.c @@ -0,0 +1,110 @@ +/************************************************************ + * sem_init.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <semaphore.h> +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: sem_init + * + * Description: + * This function initializes the UNAMED semaphore sem. + * Following a successful call to sem_init(), the + * semaophore may be used in subsequent calls to + * sem_wait(), sem_post(), and sem_trywait(). The + * semaphore remains usable until it is destroyed. + * + * Only sem itself may be used for performing + * synchronization. The result of referring to copies of + * sem in calls to sem_wait(), sem_trywait(), sem_post(), + * and sem_destroy() is undefined. + * + * Parameters: + * sem - Semaphore to be initialized + * pshared - Process sharing (not used) + * value - Semaphore initialization value + * + * Return Value: + * 0 (OK), or -1 (ERROR) if unsuccessful. + * + * Assumptions: + * + ************************************************************/ + +int sem_init (sem_t *sem, int pshared, unsigned int value) +{ + int ret = ERROR; + + if (sem && value <= SEM_MAX_VALUE) + { + sem->semcount = (sint16)value; + ret = OK; + } + + return ret; +} diff --git a/nuttx/sched/sem_initialize.c b/nuttx/sched/sem_initialize.c new file mode 100644 index 000000000..ed5e75599 --- /dev/null +++ b/nuttx/sched/sem_initialize.c @@ -0,0 +1,99 @@ +/************************************************************ + * sem_initialize.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <queue.h> +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * 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); +} diff --git a/nuttx/sched/sem_internal.h b/nuttx/sched/sem_internal.h new file mode 100644 index 000000000..460b358fc --- /dev/null +++ b/nuttx/sched/sem_internal.h @@ -0,0 +1,99 @@ +/************************************************************ + * sem_internal.h + * + * 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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (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 __SEM_INTERNAL_H +#define __SEM_INTERNAL_H + +/************************************************************ + * Included Files + ************************************************************/ + +#include <sys/types.h> +#include <semaphore.h> +#include <sched.h> +#include <queue.h> +#include <nuttx/compiler.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Public Type Declarations + ************************************************************/ + +/* This is the named semaphore structure */ + +struct nsem_s +{ + struct nsem_s *flink; /* Forward link */ + struct nsem_s *blink; /* Backward link */ + uint16 nconnect; /* Number of connections to semaphore */ + char *name; /* Semaphore name (NULL if un-named) */ + boolean 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(_TCB *wtcb); +EXTERN nsem_t *sem_findnamed(const char *name); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __SEM_INTERNAL_H */ + diff --git a/nuttx/sched/sem_open.c b/nuttx/sched/sem_open.c new file mode 100644 index 000000000..f6139ec5e --- /dev/null +++ b/nuttx/sched/sem_open.c @@ -0,0 +1,206 @@ +/************************************************************ + * sem_open.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <stdarg.h> +#include <string.h> +#include <semaphore.h> +#include <nuttx/kmalloc.h> +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * 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_MAX_VALUE. + * + * Return Value: + * A pointer to sem_t or -1 (ERROR) if unsuccessful. + * + * Assumptions: + * + ************************************************************/ + +sem_t *sem_open (const char *name, int oflag, ...) +{ + int namelen; + nsem_t *psem; + sem_t *sem = (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_MAX_VALUE) + { + /* Allocate memory for the new semaphore */ + + psem = (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 = (char*)psem + sizeof(nsem_t); + strcpy(psem->name, name); + + /* Add the new semaphore to the list of named + * semaphores + */ + + dq_addfirst((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..c07b1d534 --- /dev/null +++ b/nuttx/sched/sem_post.c @@ -0,0 +1,165 @@ +/************************************************************ + * sem_post.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <semaphore.h> +#include <sched.h> +#include <nuttx/arch.h> +#include "os_internal.h" +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * 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 (sem_t *sem) +{ + _TCB *stcb; + STATUS ret = ERROR; + uint32 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_MAX_VALUE); + sem->semcount++; + + /* If the result of of semaphore unlock is non-positive, then + * there must be some task waiting for the semaphore. + */ + + if (sem->semcount <= 0) + { + /* Check if there are any tasks in the waiting for semaphore + * task list that are waiting for this semaphore. This is a + * prioritized list so the first one we encounter is the one + * that we want. + */ + + for (stcb = (_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); + } + } + ret = OK; + + /* Interrupts may now be enabled. */ + + irqrestore(saved_state); + } + + return ret; +} + diff --git a/nuttx/sched/sem_trywait.c b/nuttx/sched/sem_trywait.c new file mode 100644 index 000000000..561ba0b44 --- /dev/null +++ b/nuttx/sched/sem_trywait.c @@ -0,0 +1,141 @@ +/************************************************************ + * sem_trywait.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <semaphore.h> +#include <sched.h> +#include <errno.h> +#include <nuttx/arch.h> +#include "os_internal.h" +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * 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(sem_t *sem) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + uint32 saved_state; + int ret = ERROR; + + /* 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..467db622e --- /dev/null +++ b/nuttx/sched/sem_unlink.c @@ -0,0 +1,141 @@ +/************************************************************ + * sem_unlink.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <semaphore.h> +#include <sched.h> +#include <queue.h> +#include "os_internal.h" +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * 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 processes, 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 (const char *name) +{ + 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((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..006c55960 --- /dev/null +++ b/nuttx/sched/sem_wait.c @@ -0,0 +1,174 @@ +/************************************************************ + * sem_wait.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <semaphore.h> +#include <errno.h> +#include <assert.h> +#include <nuttx/arch.h> +#include "os_internal.h" +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * 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 (sem_t *sem) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + int ret = ERROR; + uint32 saved_state; + + /* 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(); + + /* Check if the lock is available */ + + if (sem->semcount > 0) + { + /* It is, let the task take the semaphore. */ + + sem->semcount--; + 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 */ + + sem->semcount--; + + /* Save the waited on semaphore in the TCB */ + + rtcb->waitsem = sem; + + /* Add the TCB to the prioritized semaphore wait queue */ + + 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. + */ + + if (*get_errno_ptr() != EINTR) + ret = OK; + else + sem->semcount++; + } + + /* 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..96ab61f44 --- /dev/null +++ b/nuttx/sched/sem_waitirq.c @@ -0,0 +1,128 @@ +/************************************************************ + * sem_waitirq.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <errno.h> +#include <nuttx/arch.h> +#include "sem_internal.h" + +/************************************************************ + * Compilation Switches + ************************************************************/ + +/************************************************************ + * 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 semphare, but has received a signal instead. + * + * Return Value: + * None + * + * Assumptions: + * + ************************************************************/ + +void sem_waitirq (_TCB *wtcb) +{ + uint32 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) + { + /* Indicate that the semaphore wait is over. */ + + wtcb->waitsem = NULL; + + /* Mark the errno value for the thread. */ + + wtcb->errno = EINTR; + + /* Restart the 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..14388c3d5 --- /dev/null +++ b/nuttx/sched/sig_action.c @@ -0,0 +1,273 @@ +/************************************************************ + * sig_action.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <signal.h> +#include <queue.h> +#include <sched.h> +#include "os_internal.h" +#include "sig_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Function: sig_allocateaction + * + * Description: + * Allocate a new element for a sigaction queue + * + ************************************************************/ + +static sigactq_t *sig_allocateaction(void) +{ + sigactq_t *sigact; + + /* Try to get the signal action structure from the free list */ + + sigact = (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 = (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, const struct sigaction *act, + struct sigaction *oact) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + 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) + { + *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 = (ubyte)signo; + + /* Add the new sigaction to sigactionq */ + + sq_addlast((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) + { + sigact->act = *act; + } + + /* No.. It is a request to remove the old handler */ + + else + { + /* Remove the old sigaction from sigactionq */ + + sq_rem((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(sigactq_t *sigact) +{ + /* Just put it back on the free list */ + + sq_addlast((sq_entry_t*)sigact, &g_sigfreeaction); +} diff --git a/nuttx/sched/sig_addset.c b/nuttx/sched/sig_addset.c new file mode 100644 index 000000000..b212a37a7 --- /dev/null +++ b/nuttx/sched/sig_addset.c @@ -0,0 +1,99 @@ +/************************************************************ + * sig_addset.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <signal.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: sigaddset + * + * Description: + * This function adds the signal specified by signo to the + * signal set specified by set. + * + * Parameters: + * set - Signal set to add signal to + * signo - Signal to add + * + * Return Value: + * 0 (OK), or -1 (ERROR) if the signal number is invalid. + * + * Assumptions: + * + ************************************************************/ + +int sigaddset(sigset_t *set, int signo) +{ + int ret = ERROR; + + /* Verify the signal */ + + if (GOOD_SIGNO(signo)) + { + /* Add the signal to the set */ + + *set |= SIGNO2SET(signo); + ret = OK; + } + + return ret; +} diff --git a/nuttx/sched/sig_allocatependingsigaction.c b/nuttx/sched/sig_allocatependingsigaction.c new file mode 100644 index 000000000..a6304e205 --- /dev/null +++ b/nuttx/sched/sig_allocatependingsigaction.c @@ -0,0 +1,134 @@ +/************************************************************ + * sig_allocatependingsigaction.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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 + ************************************************************/ + +sigq_t *sig_allocatependingsigaction(void) +{ + sigq_t *sigq; + uint32 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 = (sigq_t*)sq_remfirst(&g_sigpendingaction); + + /* If so, then try the special list of structures reserved for + * interrupt handlers + */ + + if (!sigq) + { + sigq = (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 = (sigq_t*)sq_remfirst(&g_sigpendingaction); + irqrestore(saved_state); + + /* Check if we got one. */ + + if (!sigq) + { + /* No...Try the resource pool */ + + if (!sigq) + { + sigq = (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..d9e1073df --- /dev/null +++ b/nuttx/sched/sig_cleanup.c @@ -0,0 +1,117 @@ +/************************************************************ + * sig_cleanup.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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(_TCB *stcb) +{ + sigactq_t *sigact; + sigq_t *sigq; + sigpendq_t *sigpend; + + /* Deallocate all entries in the list of signal actions */ + + while ((sigact = (sigactq_t*)sq_remfirst(&stcb->sigactionq)) != NULL) + { + sig_releaseaction(sigact); + } + + /* Deallocate all entries in the list of pending signals */ + + while ((sigpend = (sigpendq_t*)sq_remfirst(&stcb->sigpendingq)) != NULL) + { + sig_releasependingsignal(sigpend); + } + + /* Deallocate all entries in the list of pending signal actions */ + + while ((sigq = (sigq_t*)sq_remfirst(&stcb->sigpendactionq)) != NULL) + { + sig_releasependingsigaction(sigq); + } + + /* Deallocate all entries in the list of posted signal actions */ + + while ((sigq = (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..dfbbc1092 --- /dev/null +++ b/nuttx/sched/sig_deliver.c @@ -0,0 +1,164 @@ +/************************************************************ + * sig_deliver.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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(_TCB *stcb) +{ + pid_t rpid; + sigq_t *sigq; + sigq_t *next; + sigset_t savesigprocmask; + uint32 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->errno; + for (sigq = (sigq_t*)stcb->sigpendactionq.head; (sigq); sigq = next) + { + next = sigq->flink; + dbg("sig_deliver: 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((sq_entry_t*)sigq, &(stcb->sigpendactionq)); + sq_addlast((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 using its address environment */ + + (*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((sq_entry_t*)sigq, &(stcb->sigpostedq)); + irqrestore(saved_state); + + /* Then deallocate it */ + + sig_releasependingsigaction(sigq); + } + + stcb->errno = saved_errno; + sched_unlock(); +} + diff --git a/nuttx/sched/sig_delset.c b/nuttx/sched/sig_delset.c new file mode 100644 index 000000000..b18454562 --- /dev/null +++ b/nuttx/sched/sig_delset.c @@ -0,0 +1,99 @@ +/************************************************************ + * sig_delset.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <signal.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: sigdelset + * + * Description: + * This function deletes the signal specified by signo from + * the signal set specified by set. + * + * Parameters: + * set - Signal set to delete the signal from + * signo - Signal to delete + * + * Return Value: + * 0 (OK), or -1 (ERROR) if the signal number is invalid. + * + * Assumptions: + * + ************************************************************/ + +int sigdelset(sigset_t *set, int signo) +{ + int ret = ERROR; + + /* Verify the signal */ + + if (GOOD_SIGNO(signo)) + { + /* Delete the signal to the set */ + + *set &= ~SIGNO2SET(signo); + ret = OK; + } + + return ret; +} diff --git a/nuttx/sched/sig_emptyset.c b/nuttx/sched/sig_emptyset.c new file mode 100644 index 000000000..7c5c9d58a --- /dev/null +++ b/nuttx/sched/sig_emptyset.c @@ -0,0 +1,88 @@ +/************************************************************ + * sig_emptyset.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <signal.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: sigemptyset + * + * Description: + * This function initializes the signal set specified by + * set such that all signals are excluded. + * + * Parameters: + * set - Signal set to initalize + * + * Return Value: + * 0 (OK), or -1 (ERROR) if the signal set cannot be + * initialized. + * + * Assumptions: + * + ************************************************************/ + +int sigemptyset(sigset_t *set) +{ + *set = NULL_SIGNAL_SET; + return OK; +} diff --git a/nuttx/sched/sig_fillset.c b/nuttx/sched/sig_fillset.c new file mode 100644 index 000000000..2159c380c --- /dev/null +++ b/nuttx/sched/sig_fillset.c @@ -0,0 +1,88 @@ +/************************************************************ + * sig_fillset.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <signal.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/************************************************************ + * Publics Functioins + ************************************************************/ + +/************************************************************ + * Function: sigfillset + * + * Description: + * This function initializes the signal set specified by + * set such that all signals are included. + * + * Parameters: + * set - Signal set to initalize + * + * Return Value: + * 0 (OK), or -1 (ERROR) if the signal set cannot be + * initialized. + * + * Assumptions: + * + ************************************************************/ + +int sigfillset(sigset_t *set) +{ + *set = ALL_SIGNAL_SET; + return OK; +} diff --git a/nuttx/sched/sig_findaction.c b/nuttx/sched/sig_findaction.c new file mode 100644 index 000000000..98df313ec --- /dev/null +++ b/nuttx/sched/sig_findaction.c @@ -0,0 +1,100 @@ +/************************************************************ + * sig_findaction.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 "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 + * + ************************************************************/ + +sigactq_t *sig_findaction(_TCB *stcb, int signo) +{ + 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 = (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..1c1e8c23c --- /dev/null +++ b/nuttx/sched/sig_initialize.c @@ -0,0 +1,262 @@ +/************************************************************ + * sig_initialize.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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 nSigs, + ubyte sigType); +static sigpendq_t *sig_allocatependingsignalblock(sq_queue_t *sigList, + uint16 nSigs, ubyte 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 nSigs, + ubyte 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((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 nSigs, ubyte 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((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_sigpendingaction, + 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((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..8f3bebe1c --- /dev/null +++ b/nuttx/sched/sig_internal.h @@ -0,0 +1,190 @@ +/************************************************************ + * sig_internal.h + * + * 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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (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 <queue.h> +#include <sched.h> +#include <nuttx/kmalloc.h> +#include <nuttx/os_external.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 +{ + struct sigactq *flink; /* Forward link */ + struct sigaction act; /* Sigaction data */ + ubyte 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 +{ + struct sigpendq *flink; /* Forward link */ + siginfo_t info; /* Signal information */ + ubyte 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 +{ + struct sigq_s *flink; /* Forward link */ + union + { + saVxHandType *sighandler; + } action; /* Signal action */ + sigset_t mask; /* Additional signals to mask while the + * the signal-catching functin executes */ + siginfo_t info; /* Signal information */ + ubyte 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 Inline Functions + ************************************************************/ + +/************************************************************ + * 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(sigactq_t *sigact); + +/* sig_pending.c */ + +extern sigset_t sig_pendingset(_TCB *stcb); + +/* In files of the same name */ + +extern sigq_t *sig_allocatependingsigaction(void); +extern void sig_cleanup(_TCB *stcb); +extern void sig_deliver(_TCB *stcb); +extern sigactq_t *sig_findaction(_TCB *stcb, int signo); +extern int sig_lowest(sigset_t *set); +extern int sig_mqnotempty (int tid, int signo, + const union sigval value); +extern int sig_received(_TCB *stcb, siginfo_t *info); +extern void sig_releasependingsigaction(sigq_t *sigq); +extern void sig_releasependingsignal(sigpendq_t *sigpend); +extern sigpendq_t *sig_removependingsignal(_TCB *stcb, int signo); +extern void sig_unmaskpendingsignal(void); + +#endif /* __SIG_INTERNAL_H */ diff --git a/nuttx/sched/sig_ismember.c b/nuttx/sched/sig_ismember.c new file mode 100644 index 000000000..3c363f710 --- /dev/null +++ b/nuttx/sched/sig_ismember.c @@ -0,0 +1,99 @@ +/************************************************************ + * sig_ismember.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <signal.h> + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Function: sigismember + * + * Description: + * This function tests whether the signal specified by signo + * is a member of the set specified by set. + * + * Parameters: + * set - Signal set to test + * signo - Signal to test for + * + * Return Value: + * 1 (TRUE), if the specified signal is a member of the set, + * 0 (OK or FALSE), if it is not, or + * -1 (ERROR) if the signal number is invalid. + * + * Assumptions: + * + ************************************************************/ + +int sigismember(const sigset_t *set, int signo) +{ + int ret = ERROR; + + /* Verify the signal */ + + if (GOOD_SIGNO(signo)) + { + /* Check if the signal is in the set */ + ret = ((*set & SIGNO2SET(signo)) != 0); + } + + return ret; +} diff --git a/nuttx/sched/sig_lowest.c b/nuttx/sched/sig_lowest.c new file mode 100644 index 000000000..7cbf9c1fe --- /dev/null +++ b/nuttx/sched/sig_lowest.c @@ -0,0 +1,88 @@ +/************************************************************ + * sig_lowest.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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..cc5a064f6 --- /dev/null +++ b/nuttx/sched/sig_mqnotempty.c @@ -0,0 +1,113 @@ +/************************************************************ + * sig_mqnotempty.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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. + * + ************************************************************/ + +int sig_mqnotempty (int pid, int signo, const union sigval value) +{ + _TCB *stcb; + siginfo_t info; + int ret = ERROR; + + sched_lock(); + + /* Get the TCB of the receiving task */ + + stcb = sched_gettcb(pid); + dbg("sig_mqnotempty: TCB=0x%08x signo=%d value=%d\n", + stcb, signo, value.sival_int); + + /* Create the siginfo structure */ + + info.si_signo = signo; + info.si_code = SI_MESGQ; + info.si_value = value; + + /* 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..3600c6d94 --- /dev/null +++ b/nuttx/sched/sig_pending.c @@ -0,0 +1,128 @@ +/************************************************************ + * sig_pending.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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(sigset_t *set) +{ + _TCB *rtcb = (_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(_TCB *stcb) +{ + sigset_t sigpendset; + sigpendq_t *sigpend; + uint32 saved_state; + + sigpendset = NULL_SIGNAL_SET; + + saved_state = irqsave(); + for (sigpend = (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..b733bac0e --- /dev/null +++ b/nuttx/sched/sig_procmask.c @@ -0,0 +1,172 @@ +/************************************************************ + * sig_procmask.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <sys/types.h> +#include <unistd.h> +#include <signal.h> +#include <time.h> +#include <wdog.h> +#include <assert.h> +#include <debug.h> +#include <sched.h> +#include <nuttx/kmalloc.h> +#include <nuttx/arch.h> +#include <nuttx/os_external.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, const sigset_t *set, sigset_t *oset) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + sigset_t oldsigprocmask; + uint32 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; + } /* end switch */ + irqrestore(saved_state); + + /* Now, process any pending signals that were just unmasked */ + + sig_unmaskpendingsignal(); + } /* end if */ + + sched_unlock(); + return ret; +} diff --git a/nuttx/sched/sig_queue.c b/nuttx/sched/sig_queue.c new file mode 100644 index 000000000..b9abf7f39 --- /dev/null +++ b/nuttx/sched/sig_queue.c @@ -0,0 +1,131 @@ +/************************************************************ + * sig_queue.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <signal.h> +#include <debug.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: 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: + * None + * + * Assumptions: + * + ************************************************************/ + +int sigqueue (int pid, int signo, const union sigval value) +{ + _TCB *stcb; + siginfo_t info; + int ret = ERROR; + + sched_lock(); + + /* Get the TCB of the receiving task */ + + stcb = sched_gettcb(pid); + dbg("sigqueue: TCB=0x%08x signo=%d value=%d\n", + stcb, signo, value.sival_int); + + /* Create the siginfo structure */ + + info.si_signo = signo; + info.si_code = SI_QUEUE; + info.si_value = value; + + /* 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_received.c b/nuttx/sched/sig_received.c new file mode 100644 index 000000000..8a2c3928d --- /dev/null +++ b/nuttx/sched/sig_received.c @@ -0,0 +1,384 @@ +/************************************************************ + * sig_received.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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 + ************************************************************/ + +/************************************************************ + * Function: sig_queueaction + * + * Description: + * Queue a signal action for delivery to a task. + * + ************************************************************/ + +static int sig_queueaction(_TCB *stcb, siginfo_t *info) +{ + sigactq_t *sigact; + sigq_t *sigq; + uint32 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; + sigq->info = *info; + + /* Put it at the end of the pending signals list */ + + saved_state = irqsave(); + sq_addlast((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 sigpendq_t *sig_findpendingsignal(_TCB *stcb, int signo) +{ + sigpendq_t *sigpend = NULL; + uint32 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 = (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 sigpendq_t *sig_allocatependingsignal(void) +{ + sigpendq_t *sigpend; + uint32 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 = (sigpendq_t*)sq_remfirst(&g_sigpendingsignal); + + /* If so, then try the special list of structures reserved for + * interrupt handlers + */ + + sigpend = (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 = (sigpendq_t*)sq_remfirst(&g_sigpendingsignal); + irqrestore(saved_state); + + /* Check if we got one. */ + + if (!sigpend) + { + /* No...Try the resource pool */ + + if (!sigpend) + { + sigpend = (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 sigpendq_t *sig_addpendingsignal(_TCB *stcb, siginfo_t *info) +{ + sigpendq_t *sigpend; + uint32 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 */ + + sigpend->info = *info; + } + + /* 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 */ + + sigpend->info = *info; + + /* Add the structure to the pending signal list */ + + saved_state = irqsave(); + sq_addlast((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(_TCB *stcb, siginfo_t *info) +{ + int ret = ERROR; + uint32 saved_state; + + dbg("sig_received: TCB=0x%08x signo=%d code=%d value=%d\n", + stcb, info->si_signo, info->si_code, info->si_value.sival_int); + + 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)) + { + stcb->sigunbinfo = *info; + 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) + { + stcb->sigunbinfo = *info; + 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); + } + + /* If the task is blocked waiting on a message queue, then that + * task must be unblocked when a signal is received. + */ + + /* NOT YET IMPLEMENTED. */ + } + + return ret; +} diff --git a/nuttx/sched/sig_releasependingsigaction.c b/nuttx/sched/sig_releasependingsigaction.c new file mode 100644 index 000000000..7187c03c7 --- /dev/null +++ b/nuttx/sched/sig_releasependingsigaction.c @@ -0,0 +1,118 @@ +/************************************************************ + * sig_releasependingsigaction.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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" +#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(sigq_t *sigq) +{ + uint32 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((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((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..453118fb4 --- /dev/null +++ b/nuttx/sched/sig_releasependingsignal.c @@ -0,0 +1,126 @@ +/************************************************************ + * sig_releasependingsignal.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <sys/types.h> +#include <unistd.h> +#include <signal.h> +#include <time.h> +#include <wdog.h> +#include <assert.h> +#include <debug.h> +#include <sched.h> +#include <nuttx/kmalloc.h> +#include <nuttx/arch.h> +#include <nuttx/os_external.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(sigpendq_t *sigpend) +{ + uint32 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((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((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..4163f13f0 --- /dev/null +++ b/nuttx/sched/sig_removependingsignal.c @@ -0,0 +1,108 @@ +/************************************************************ + * sig_removependingsignal.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <sys/types.h> +#include <unistd.h> +#include <signal.h> +#include <time.h> +#include <wdog.h> +#include <assert.h> +#include <debug.h> +#include <sched.h> +#include <nuttx/kmalloc.h> +#include <nuttx/arch.h> +#include <nuttx/os_external.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 + ************************************************************/ + +sigpendq_t *sig_removependingsignal(_TCB *stcb, int signo) +{ + sigpendq_t *currsig, *prevsig; + uint32 saved_state; + + saved_state = irqsave(); + for (prevsig = NULL, currsig = (sigpendq_t*)stcb->sigpendingq.head; + (currsig && currsig->info.si_signo != signo); + prevsig = currsig, currsig = currsig->flink); + if (currsig) + { + if (prevsig) + { + sq_remafter((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..d0167b226 --- /dev/null +++ b/nuttx/sched/sig_suspend.c @@ -0,0 +1,180 @@ +/************************************************************ + * sig_suspend.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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 + * process with the set of signals pointed to by the argument + * set and then suspends the process until delivery of a + * signal to the process. + * + * 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(const sigset_t *set) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + sigset_t intersection; + sigset_t saved_sigprocmask; + sigpendq_t *sigpend; + uint32 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..842f68c2f --- /dev/null +++ b/nuttx/sched/sig_timedwait.c @@ -0,0 +1,267 @@ +/************************************************************ + * sig_timedwait.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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 itcb, int parm2, int parm3, int parm4) +{ + _TCB *wtcb = (_TCB*)itcb; + + if (!wtcb) + { + PANIC(OSERR_TIMEOUTNOTCB); + } + + /* There may be a race condition -- make sure the task is + * still waiting for a signal + */ + + if (wtcb->task_state == TSTATE_WAIT_SIG) + { + wtcb->sigunbinfo.si_signo = ERROR; + wtcb->sigunbinfo.si_code = SI_TIMEOUT; + wtcb->sigunbinfo.si_value.sival_int = 0; + up_unblock_task(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_QUEUE - Signal sent from sigqueue + * SI_MESGQ - Signal generated by arrival of a message on an + * empty message queue + * SI_NOWAIT - Signal already pending -- don't know how sent + * SI_TIMEOUT - No Signal, restarted by timeout + * + * 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(const sigset_t *set, struct siginfo *info, + const struct timespec *timeout) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + sigset_t intersection; + sigpendq_t *sigpend; + WDOG_ID wdog; + uint32 saved_state; + sint32 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) *info = sigpend->info; + + /* 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) + { + /* Start the watchdog */ + + wd_start(wdog, waitticks, (wdentry_t)sig_timeout, + (int)rtcb, 0, 0, 0); + + /* 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) + { + *info = rtcb->sigunbinfo; + } + irqrestore(saved_state); + + /* The return value is the number of the signal that awakened us */ + + ret = info->si_signo; + } + sched_unlock(); + + return ret; +} + diff --git a/nuttx/sched/sig_unmaskpendingsignal.c b/nuttx/sched/sig_unmaskpendingsignal.c new file mode 100644 index 000000000..c27ad1266 --- /dev/null +++ b/nuttx/sched/sig_unmaskpendingsignal.c @@ -0,0 +1,135 @@ +/************************************************************ + * sig_unmaskpendingsignal.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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" +#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) +{ + _TCB *rtcb = (_TCB*)g_readytorun.head; + sigset_t unmaskedset; + 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..3d539defb --- /dev/null +++ b/nuttx/sched/sig_waitinfo.c @@ -0,0 +1,89 @@ +/************************************************************ + * sig_waitinfo.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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. (see above). + * + * 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(const sigset_t *set, 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..38eefd200 --- /dev/null +++ b/nuttx/sched/sleep.c @@ -0,0 +1,101 @@ +/************************************************************ + * sleep.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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: 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_create.c b/nuttx/sched/task_create.c new file mode 100644 index 000000000..ecfd68056 --- /dev/null +++ b/nuttx/sched/task_create.c @@ -0,0 +1,498 @@ +/************************************************************ + * task_create.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <string.h> +#include <errno.h> +#include <nuttx/arch.h> +#include <nuttx/os_external.h> +#include "os_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * Global Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Function Prototypes + ************************************************************/ + +static void task_start(void); +static STATUS task_assignpid(_TCB* tcb); + +/************************************************************ + * Private 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 + * + ************************************************************/ + +static void task_start(void) +{ + _TCB *tcb = (_TCB*)g_readytorun.head; + int argc; + + /* Count how many non-null arguments we are passing */ + + for (argc = 1; argc <= NUM_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)); +} + +/************************************************************ + * 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 STATUS task_assignpid(_TCB *tcb) +{ + pid_t next_pid; + int hash_ndx; + int tries = 0; + + /* 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 < MAX_TASKS_ALLOWED; 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; +} + +/************************************************************ + * Public Functions + ************************************************************/ + +/************************************************************ + * Name: _task_init and task_init + * + * Description: + * These functions initializes a Task Control Block (TCB) + * in preparation for starting a new thread. _task_init() + * is an internal version of the function that has some + * additional control arguments and task_init() is a wrapper + * function that creates a VxWorks-like user API. + * task_init() is, otherwise, not used by the OS. + * + * _task_init() is called from task_init() and task_start().\ + * It is also called from pthread_create() to create a + * a pthread (distinguished by the pthread argument). + * + * Unlike task_create(), task_init() does not activate the + * task. This must be done by calling task_activate() + * afterward. + * + * Input Parameters: + * tcb - Address of the new task's TCB + * name - Name of the new task (not used) + * priority - Priority of the new task + * entry - Entry point of a new task + * main - Application start point of the new task + * pthread - TRUE is the task emulates pthread behavior + * arg1-4 - Four required task arguments to pass to + * the task when it is started. + * + * 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). + * + ************************************************************/ + +STATUS _task_init(_TCB *tcb, char *name, int priority, + start_t start, main_t main, boolean pthread, + char *arg1, char *arg2, char *arg3, char *arg4) +{ + STATUS 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 = (ubyte)priority; + tcb->sched_priority = (ubyte)priority; + tcb->start = start; + tcb->entry.main = main; + +#if CONFIG_TASK_NAME_SIZE > 0 + /* Give a name to the unnamed threads */ + + if (!name) + { + name = "no name"; + } + + /* copy the name into the TCB */ + + strncpy(tcb->name, name, CONFIG_TASK_NAME_SIZE); +#endif /* CONFIG_TASK_NAME_SIZE */ + + /* Save the arguments in the TCB */ + +#if CONFIG_TASK_NAME_SIZE > 0 + tcb->argv[0] = tcb->name; +#else + tcb->argv[0] = "no name"; +#endif + + /* For pthreads, args are strictly pass-by-value; the char* + * arguments wrap some unknown value cast to char*. However, + * 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. + */ + + if (!pthread) + { + /* The first NULL argument terminates the list of + * arguments. + */ + + if (arg1) + { + tcb->argv[1] = strdup(arg1); + if (arg2) + { + tcb->argv[2] = strdup(arg2); + if (arg3) + { + tcb->argv[3] = strdup(arg3); + if (arg4) + { + tcb->argv[4] = strdup(arg4); + } + } + } + } + } + else + { + /* Mark this task as a pthread */ + + tcb->flags |= TCB_FLAG_PTHREAD; + + /* And just copy the argument. (For pthreads, there + * is really only a single argument, arg1). + */ + + tcb->argv[1] = arg1; + tcb->argv[2] = arg2; + tcb->argv[3] = arg3; + tcb->argv[4] = arg4; + } + + /* Initialize other (non-zero) elements of the TCB */ + + tcb->sigprocmask = ALL_SIGNAL_SET; + tcb->task_state = TSTATE_TASK_INVALID; + + /* Initialize the processor-specific portion of the TCB */ + + up_initial_state(tcb); + + /* Add the task to the inactive task list */ + + sched_lock(); + dq_addfirst((dq_entry_t*)tcb, &g_inactivetasks); + tcb->task_state = TSTATE_TASK_INACTIVE; + sched_unlock(); + } + + return ret; +} + +/************************************************************ + * Name: _task_init and task_init + * + * Description: + * This is a wrapper around the internal _task_init() that + * provides a VxWorks-like API. See _task_init() for + * further information. + * + * 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 + * arg1-4 - Four required task arguments to pass to + * the task when it is started. + * + * Return Value: + * see _task_init() + * + ************************************************************/ + +STATUS task_init(_TCB *tcb, char *name, int priority, + uint32 *stack, uint32 stack_size, main_t entry, + char *arg1, char *arg2, char *arg3, char *arg4) +{ + up_use_stack(tcb, stack, stack_size); + return _task_init(tcb, name, priority, task_start, entry, + FALSE, arg1, arg2, arg3, arg4); +} + +/************************************************************ + * Name: task_activate + * + * Description: + * This function activates tasks initialized by _task_init(). + * 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 + * + ************************************************************/ + +STATUS task_activate(_TCB *tcb) +{ +#ifdef CONFIG_SCHED_INSTRUMENTATION + uint32 savedState; +#endif + +#ifdef CONFIG_SCHED_INSTRUMENTATION + savedState = irqsave(); + + /* 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); + irqrestore(savedState); +#endif + + up_unblock_task(tcb); + return OK; +} + +/************************************************************ + * 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* - Ten required task arguments to pass to func + * + * Return Value: + * Returns the non-zero process ID of the new task or + * ERROR if memory is insufficient or the task cannot be + * created (errno is not set). + * + ************************************************************/ + +int task_create(char *name, int priority, + int stack_size, main_t entry, + char *arg1, char *arg2, char *arg3, char *arg4) +{ + _TCB *tcb; + STATUS status; + pid_t pid; + + /* Allocate a TCB for the new task. */ + + tcb = (_TCB*)kzmalloc(sizeof(_TCB)); + if (!tcb) + { + *get_errno_ptr() = ENOMEM; + return ERROR; + } + + /* Associate file descriptors with the new task */ + + if (sched_setuptaskfiles(tcb) != OK) + { + sched_releasetcb(tcb); + return ERROR; + } + + /* Allocate the stack for the TCB */ + + status = up_create_stack(tcb, stack_size); + if (status != OK) + { + sched_releasetcb(tcb); + return ERROR; + } + + /* Initialize the task control block */ + + status = _task_init(tcb, name, priority, task_start, entry, + FALSE, arg1, arg2, arg3, arg4); + if (status != OK) + { + sched_releasetcb(tcb); + return ERROR; + } + + /* Get the assigned pid before we start the task */ + + pid = (int)tcb->pid; + + /* Activate the task */ + + status = task_activate(tcb); + if (status != OK) + { + dq_rem((dq_entry_t*)tcb, &g_inactivetasks); + sched_releasetcb(tcb); + return ERROR; + } + + return pid; +} diff --git a/nuttx/sched/task_delete.c b/nuttx/sched/task_delete.c new file mode 100644 index 000000000..5a28c3d42 --- /dev/null +++ b/nuttx/sched/task_delete.c @@ -0,0 +1,165 @@ +/************************************************************ + * task_delete.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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/os_external.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_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) + * + ************************************************************/ + +STATUS task_delete(pid_t pid) +{ + _TCB *rtcb; + _TCB *dtcb; + uint32 saved_state; + STATUS ret = ERROR; + + /* Check if the task to delete is the calling task */ + + rtcb = (_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. + * + * Frist, 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); + } + + saved_state = irqsave(); + + /* Inform the instrumentation layer that the task has stopped */ + + sched_note_stop(dtcb); + + /* Remove the task from the OS's tasks lists. */ + + dq_rem((dq_entry_t*)dtcb, 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(); + + /* Deallocate anything left in the TCB's queues */ + + sig_cleanup(dtcb); /* Deallocate Signal lists */ + + /* Deallocate its TCB */ + + sched_releasetcb(dtcb); + return ret; +} diff --git a/nuttx/sched/task_restart.c b/nuttx/sched/task_restart.c new file mode 100644 index 000000000..6d4b7a83a --- /dev/null +++ b/nuttx/sched/task_restart.c @@ -0,0 +1,178 @@ +/************************************************************ + * task_restart.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY 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 <nuttx/os_external.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. + * + ************************************************************/ + +STATUS task_restart(pid_t pid) +{ + _TCB *rtcb; + _TCB *tcb; + STATUS status; + uint32 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 = (_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((dq_entry_t*)tcb, 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; + + /* 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((dq_entry_t*)tcb, &g_inactivetasks); + tcb->task_state = TSTATE_TASK_INACTIVE; + + /* Activate the task */ + + status = task_activate(tcb); + if (status != OK) + { + dq_rem((dq_entry_t*)tcb, &g_inactivetasks); + sched_releasetcb(tcb); + return ERROR; + } + } + + sched_unlock(); + return OK; +} diff --git a/nuttx/sched/usleep.c b/nuttx/sched/usleep.c new file mode 100644 index 000000000..69e379c7b --- /dev/null +++ b/nuttx/sched/usleep.c @@ -0,0 +1,98 @@ +/************************************************************ + * usleep.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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. suleep() + * is a simple application of sigtimedwait. + * + * Parameters: + * seconds + * + * Returned Value: + * None + * + * Assumptions: + * + ************************************************************/ + +void usleep(unsigned long usec) +{ + sigset_t set; + struct timespec ts; + struct siginfo value; + + if (usec) + { + (void)sigemptyset(&set); + ts.tv_sec = usec / 1000000; + ts.tv_nsec = usec % 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..9a3a223fd --- /dev/null +++ b/nuttx/sched/wd_cancel.c @@ -0,0 +1,154 @@ +/************************************************************ + * wd_cancel.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <assert.h> +#include <wdog.h> +#include <nuttx/arch.h> +#include "os_internal.h" +#include "wd_internal.h" + +/************************************************************ + * 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: + * + ************************************************************/ + +STATUS wd_cancel (WDOG_ID wdid) +{ + wdog_t *curr; + wdog_t *prev; + uint32 saved_state; + STATUS ret = ERROR; + + /* Prohibit timer interactions with the timer queue until the + * cancellation is complete + */ + + saved_state = irqsave(); + + /* Make sure that the the watchdog is still active */ + + if (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((sq_entry_t*)prev, &g_wdactivelist); + else + (void)sq_remfirst(&g_wdactivelist); + wdid->next = NULL; + + /* If we made it this far, then we were successful */ + + 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..14a1c5410 --- /dev/null +++ b/nuttx/sched/wd_create.c @@ -0,0 +1,105 @@ +/************************************************************ + * wd_create.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <wdog.h> +#include <queue.h> +#include <nuttx/arch.h> +#include "wd_internal.h" + +/************************************************************ + * 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 free list. + * + * 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) +{ + wdog_t *wdog; + sint32 saved_state; + + saved_state = irqsave(); + wdog = (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..b4039cce0 --- /dev/null +++ b/nuttx/sched/wd_delete.c @@ -0,0 +1,108 @@ +/************************************************************ + * wd_delete.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <wdog.h> +#include <queue.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. + * + ************************************************************/ + +STATUS wd_delete (WDOG_ID wdId) +{ + uint32 saved_state; + + /* Check if the watchdog has been started. */ + + saved_state = irqsave(); + if (wdId->active) wd_cancel(wdId); + + /* Put the watchdog back on the free list */ + + sq_addlast((sq_entry_t*)wdId, &g_wdfreelist); + irqrestore(saved_state); + + /* Return success */ + + return OK; +} diff --git a/nuttx/sched/wd_initialize.c b/nuttx/sched/wd_initialize.c new file mode 100644 index 000000000..5d979bb3d --- /dev/null +++ b/nuttx/sched/wd_initialize.c @@ -0,0 +1,136 @@ +/************************************************************ + * wd_initialize.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <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. + */ + +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 = (wdog_t*)kmalloc(sizeof(wdog_t) * CONFIG_PREALLOC_WDOGS); + if (g_wdpool) + { + wdog_t *wdog = g_wdpool; + int i; + + for (i = 0; i < CONFIG_PREALLOC_WDOGS; i++) + { + sq_addlast((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..9198387cc --- /dev/null +++ b/nuttx/sched/wd_internal.h @@ -0,0 +1,121 @@ +/************************************************************ + * wd_internal.h + * + * 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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (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 __WD_INTERNAL_H +#define __WD_INTERNAL_H + +/************************************************************ + * Included Files + ************************************************************/ + +#include <sys/types.h> +#include <wdog.h> +#include <nuttx/compiler.h> + +/************************************************************ + * Compilations Switches + ************************************************************/ + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Public Type Declarations + ************************************************************/ + +/* This is the watchdog structure. The WDOG_ID is a pointer to + * a watchdog structure. + */ + +struct wdog_s +{ + struct wdog_s *next; /* Support for singly linked lists. */ + wdentry_t func; /* Function to execute when delay expires */ + sint32 lag; /* Timer associated with the delay */ + uint32 parm[4]; /* Four parameters passed to func */ + boolean active; /* TRUE if the watchdog is actively timing */ +}; + +typedef struct wdog_s wdog_t; +typedef struct wdog_s *WDOG_ID; + +/************************************************************ + * 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 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 /* __WD_INTERNAL_H */ + diff --git a/nuttx/sched/wd_start.c b/nuttx/sched/wd_start.c new file mode 100644 index 000000000..04ece3493 --- /dev/null +++ b/nuttx/sched/wd_start.c @@ -0,0 +1,312 @@ +/************************************************************ + * wd_start.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 Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 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 <wdog.h> +#include <unistd.h> +#include <sched.h> +#include "wd_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Private Type Declarations + ************************************************************/ + +/************************************************************ + * 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 wdId; only + * the most recent wdStart() on a given watchdog ID has + * any effect. + * + * Parameters: + * wdId = 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. + * + ************************************************************/ + +STATUS wd_start(WDOG_ID wdId, int delay, wdentry_t wdentry, + int parm1, int parm2, int parm3, int parm4) +{ + wdog_t *curr; + wdog_t *prev; + wdog_t *next; + sint32 now; + sint32 saved_state; + + /* Verify the wdId */ + + if (!wdId) + { + 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 (wdId->active) + { + wd_cancel(wdId); + } + + /* Save the data in the watchdog structure */ + + wdId->func = wdentry; /* Function to execute when delay expires */ + wdId->parm[0] = parm1; /* Same as the parameter to pass */ + wdId->parm[1] = parm2; /* 2nd parameter not used */ + wdId->parm[2] = parm3; /* 3rd parameter not used */ + wdId->parm[3] = parm4; /* 4th parameter not used */ + + /* 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((sq_entry_t*)wdId,&g_wdactivelist); + } + + /* There are other active watchdogs in the timer queue */ + + else + { + now = 0; + prev = curr = (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 wdId 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 == (wdog_t*)g_wdactivelist.head) + { + sq_addfirst((sq_entry_t*)wdId, &g_wdactivelist); + } + else + { + sq_addafter((sq_entry_t*)prev, (sq_entry_t*)wdId, + &g_wdactivelist); + } + } + + /* The new watchdog delay time is greater than the curr delay time, + * so the new wdId must be inserted after the curr. This only occurs + * if the wdId is to be added to the end of the list. + */ + + else + { + delay -= now; + if (!curr->next) + { + sq_addlast((sq_entry_t*)wdId, &g_wdactivelist); + } + else + { + next = curr->next; + next->lag -= delay; + sq_addafter((sq_entry_t*)curr, (sq_entry_t*)wdId, + &g_wdactivelist); + } + } + } + + /* Put the lag into the watchdog structure and mark it as active. */ + + wdId->lag = delay; + wdId->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; + wdog_t *wdog; + + /* Check if there are any active watchdogs to process */ + + if (g_wdactivelist.head) + { + /* There are. Decrement the lag counter */ + + --(((wdog_t*)g_wdactivelist.head)->lag); + + /* Check if the watchdog at the head of the list is ready to run */ + + if (((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 && + ((wdog_t*)g_wdactivelist.head)->lag <= 0) + { + /* Remove the watchdog from the head of the list */ + + wdog = (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) + { + ((wdog_t*)g_wdactivelist.head)->lag += wdog->lag; + } + + /* Indicate that the watchdog is no longer activer. */ + + 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 */ + + (*wdog->func)(wdog->parm[0], wdog->parm[1], + wdog->parm[2] ,wdog->parm[3]); + } + } + } +} |