diff options
Diffstat (limited to 'cpukit/rtems')
212 files changed, 24514 insertions, 0 deletions
diff --git a/cpukit/rtems/.cvsignore b/cpukit/rtems/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/cpukit/rtems/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am new file mode 100644 index 0000000000..4af1752512 --- /dev/null +++ b/cpukit/rtems/Makefile.am @@ -0,0 +1,149 @@ +## +## $Id$ +## + +include $(top_srcdir)/automake/multilib.am +include $(top_srcdir)/automake/compile.am + +AM_CPPFLAGS += -D__RTEMS_INSIDE__ + +noinst_LIBRARIES = librtems.a +librtems_a_CPPFLAGS = $(AM_CPPFLAGS) + +# include + +include_HEADERS = include/rtems.h + +# include/rtems/rtems +include_rtems_rtemsdir = $(includedir)/rtems/rtems + +include_rtems_rtems_HEADERS = include/rtems/rtems/asr.h \ + include/rtems/rtems/attr.h include/rtems/rtems/barrier.h \ + include/rtems/rtems/cache.h include/rtems/rtems/clock.h \ + include/rtems/rtems/config.h include/rtems/rtems/dpmem.h \ + include/rtems/rtems/event.h include/rtems/rtems/eventset.h \ + include/rtems/rtems/intr.h include/rtems/rtems/message.h \ + include/rtems/rtems/modes.h include/rtems/rtems/object.h \ + include/rtems/rtems/options.h include/rtems/rtems/part.h \ + include/rtems/rtems/ratemon.h include/rtems/rtems/region.h \ + include/rtems/rtems/rtemsapi.h include/rtems/rtems/sem.h \ + include/rtems/rtems/signal.h include/rtems/rtems/status.h \ + include/rtems/rtems/support.h include/rtems/rtems/tasks.h \ + include/rtems/rtems/timer.h include/rtems/rtems/types.h \ + mainpage.h + +if HAS_MP +## We only build multiprocessing related files if HAS_MP was defined +include_rtems_rtems_HEADERS += include/rtems/rtems/eventmp.h \ + include/rtems/rtems/mp.h include/rtems/rtems/msgmp.h \ + include/rtems/rtems/partmp.h include/rtems/rtems/regionmp.h \ + include/rtems/rtems/semmp.h include/rtems/rtems/signalmp.h \ + include/rtems/rtems/taskmp.h +endif + +include_rtems_rtems_HEADERS += inline/rtems/rtems/asr.inl \ + inline/rtems/rtems/attr.inl inline/rtems/rtems/barrier.inl \ + inline/rtems/rtems/dpmem.inl \ + inline/rtems/rtems/event.inl inline/rtems/rtems/eventset.inl \ + inline/rtems/rtems/message.inl inline/rtems/rtems/modes.inl \ + inline/rtems/rtems/options.inl inline/rtems/rtems/part.inl \ + inline/rtems/rtems/ratemon.inl inline/rtems/rtems/region.inl \ + inline/rtems/rtems/sem.inl inline/rtems/rtems/status.inl \ + inline/rtems/rtems/support.inl inline/rtems/rtems/tasks.inl \ + inline/rtems/rtems/timer.inl + +## src +librtems_a_SOURCES = src/rtemsbuildid.c src/rtemsbuildname.c \ + src/rtemsobjectgetname.c src/rtemsobjectsetname.c \ + src/rtemsobjectidapimaximum.c src/rtemsobjectidapiminimum.c \ + src/rtemsobjectidgetapi.c src/rtemsobjectidgetclass.c \ + src/rtemsobjectidgetindex.c src/rtemsobjectidgetnode.c \ + src/rtemsobjectapiminimumclass.c src/rtemsobjectapimaximumclass.c \ + src/rtemsobjectgetapiname.c src/rtemsobjectgetapiclassname.c \ + src/rtemsobjectgetclassinfo.c src/rtemsobjectgetclassicname.c + +## TASK_C_FILES +librtems_a_SOURCES += src/tasks.c src/taskcreate.c src/taskdelete.c \ + src/taskgetnote.c src/taskident.c src/taskinitusers.c \ + src/taskissuspended.c src/taskmode.c src/taskrestart.c src/taskresume.c \ + src/taskself.c src/tasksetnote.c src/tasksetpriority.c src/taskstart.c \ + src/tasksuspend.c src/taskwakeafter.c src/taskwakewhen.c \ + src/taskvariableadd.c src/taskvariabledelete.c src/taskvariableget.c \ + src/taskvariable_invoke_dtor.c src/taskdata.c + +## RATEMON_C_FILES +librtems_a_SOURCES += src/ratemon.c src/ratemoncancel.c src/ratemoncreate.c \ + src/ratemondelete.c src/ratemongetstatus.c src/ratemongetstatistics.c \ + src/ratemonresetstatistics.c src/ratemonresetall.c \ + src/ratemonreportstatistics.c src/ratemonident.c \ + src/ratemonperiod.c src/ratemontimeout.c src/ratemondata.c + +## INTR_C_FILES +librtems_a_SOURCES += src/intrbody.c src/intrcatch.c + +## BARRIER_C_FILES +librtems_a_SOURCES += src/barrier.c src/barriercreate.c src/barrierdelete.c \ + src/barrierident.c src/barriertranslatereturncode.c src/barrierrelease.c \ + src/barrierwait.c src/barrierdata.c + +## CLOCK_C_FILES +librtems_a_SOURCES += src/clockget.c src/clockgetsecondssinceepoch.c \ + src/clockgettickspersecond.c src/clockgettickssinceboot.c \ + src/clockgettod.c src/clockgettodtimeval.c src/clockgetuptime.c \ + src/clockset.c src/clocksetnsecshandler.c src/clocktick.c \ + src/clocktodtoseconds.c src/clocktodvalidate.c + +## TIMER_C_FILES +librtems_a_SOURCES += src/rtemstimer.c src/timercancel.c src/timercreate.c \ + src/timerdelete.c src/timerfireafter.c src/timerfirewhen.c \ + src/timergetinfo.c src/timerident.c src/timerreset.c src/timerserver.c \ + src/timerserverfireafter.c src/timerserverfirewhen.c src/rtemstimerdata.c + +## MESSAGE_QUEUE_C_FILES +librtems_a_SOURCES += src/msg.c src/msgqallocate.c src/msgqbroadcast.c \ + src/msgqcreate.c src/msgqdelete.c src/msgqflush.c \ + src/msgqgetnumberpending.c src/msgqident.c src/msgqreceive.c \ + src/msgqsend.c src/msgqtranslatereturncode.c src/msgqurgent.c \ + src/msgdata.c + +## SEMAPHORE_C_FILES +librtems_a_SOURCES += src/sem.c src/semcreate.c src/semdelete.c src/semident.c \ + src/semobtain.c src/semrelease.c src/semflush.c \ + src/semtranslatereturncode.c src/semdata.c + +## EVENT_C_FILES +librtems_a_SOURCES += src/event.c src/eventreceive.c src/eventseize.c \ + src/eventsend.c src/eventsurrender.c src/eventtimeout.c src/eventdata.c + +## SIGNAL_C_FILES +librtems_a_SOURCES += src/signal.c src/signalcatch.c src/signalsend.c + +## REGION_C_FILES +librtems_a_SOURCES += src/region.c src/regioncreate.c src/regiondelete.c \ + src/regionextend.c src/regiongetsegment.c src/regiongetsegmentsize.c \ + src/regionident.c src/regionreturnsegment.c src/regiongetinfo.c \ + src/regiongetfreeinfo.c src/regionresizesegment.c \ + src/regionprocessqueue.c src/regiondata.c + +## PARTITION_C_FILES +librtems_a_SOURCES += src/part.c src/partcreate.c src/partdelete.c \ + src/partgetbuffer.c src/partident.c src/partreturnbuffer.c src/partdata.c + +## DPMEM_C_FILES +librtems_a_SOURCES += src/dpmem.c src/dpmemcreate.c src/dpmemdelete.c \ + src/dpmemexternal2internal.c src/dpmemident.c \ + src/dpmeminternal2external.c src/dpmemdata.c + +## WORKSPACE_FILES +librtems_a_SOURCES += src/workspace.c + +librtems_a_SOURCES += src/attr.c + +if HAS_MP +# We only build multiprocessing related files if HAS_MP was defined +librtems_a_SOURCES += src/eventmp.c src/mp.c src/msgmp.c src/partmp.c \ + src/regionmp.c src/semmp.c src/signalmp.c src/taskmp.c +endif + +include $(srcdir)/preinstall.am +include $(top_srcdir)/automake/local.am diff --git a/cpukit/rtems/include/rtems.h b/cpukit/rtems/include/rtems.h new file mode 100644 index 0000000000..17b1ce0394 --- /dev/null +++ b/cpukit/rtems/include/rtems.h @@ -0,0 +1,207 @@ +/** + * @file + * + * @ingroup ClassicRTEMS + * + * @brief Provides the public interface to the RTEMS Classic API. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_H +#define _RTEMS_H + +/** + * @defgroup ClassicRTEMS RTEMS Classic API + * + * RTEMS Classic API definitions and modules. + * + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if (!defined(__RTEMS_VIOLATE_KERNEL_VISIBILITY__)) && \ + (!defined(__RTEMS_INSIDE__)) +/** + * @brief Compiling RTEMS application macro. + * + * Unless told otherwise, the RTEMS include files will hide some stuff from + * normal application code. Defining this crosses a boundary which is + * undesirable since it means your application is using RTEMS features which + * are not included in the formally defined and supported API. Define this at + * your own risk. + */ +#define __RTEMS_APPLICATION__ +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> + +#include <rtems/config.h> +#include <rtems/init.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/tasks.h> +#include <rtems/rtems/intr.h> +#include <rtems/rtems/barrier.h> +#include <rtems/rtems/cache.h> +#include <rtems/rtems/clock.h> +#include <rtems/extension.h> +#include <rtems/rtems/timer.h> +#include <rtems/rtems/sem.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/event.h> +#include <rtems/rtems/signal.h> +#include <rtems/rtems/event.h> +#include <rtems/rtems/object.h> +#include <rtems/rtems/part.h> +#include <rtems/rtems/region.h> +#include <rtems/rtems/dpmem.h> +#include <rtems/io.h> +#include <rtems/fatal.h> +#include <rtems/rtems/ratemon.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/mp.h> +#endif + +#include <rtems/rtems/support.h> +#include <rtems/score/sysstate.h> + +/** + * @brief Returns the pointer to the RTEMS version string. + */ +const char *rtems_get_version_string(void); + +/** + * @brief Indicates whether this processor variant has hardware floating point + * support. + */ +#define RTEMS_HAS_HARDWARE_FP CPU_HARDWARE_FP + +/********************************************************************** + * CONSTANTS WHICH MAY BE USED IN OBJECT NAME TO ID SEARCHES + **********************************************************************/ + +/** + * @brief Indicates that a search is across all nodes. + */ +#define RTEMS_SEARCH_ALL_NODES OBJECTS_SEARCH_ALL_NODES + +/** + * @brief Indicates that a search is across all nodes except the one the call + * is made from. + */ +#define RTEMS_SEARCH_OTHER_NODES OBJECTS_SEARCH_OTHER_NODES + +/** + * @brief Indicates that the search is to be restricted to the local node. + */ +#define RTEMS_SEARCH_LOCAL_NODE OBJECTS_SEARCH_LOCAL_NODE + +/** + * @brief Indicates that the caller wants to obtain the name of the currently + * executing thread. + * + * This constant is only meaningful when obtaining the name of a task. + */ +#define RTEMS_WHO_AM_I OBJECTS_WHO_AM_I + +/********************************************************************** + * Parameters and return Id's for _Objects_Get_next + **********************************************************************/ + +/** + * @brief Lowest valid index value for the index portion of an object + * identifier. + */ +#define RTEMS_OBJECT_ID_INITIAL_INDEX OBJECTS_ID_INITIAL_INDEX + +/** + * @brief Maximum valid index value for the index portion of an object + * identifier. + */ +#define RTEMS_OBJECT_ID_FINAL_INDEX OBJECTS_ID_FINAL_INDEX + +/** + * @brief Returns the identifier of the object with the lowest valid index + * value. + * + * The object is specified by the API @a _api, the object class @a _class and + * the node @a _node where the object resides. + */ +#define RTEMS_OBJECT_ID_INITIAL(_api, _class, _node) \ + OBJECTS_ID_INITIAL(_api, _class, _node) + +/** + * @brief Maximum valid object identifier. + */ +#define RTEMS_OBJECT_ID_FINAL OBJECTS_ID_FINAL + +/** + * @brief Minimum stack size which every thread must exceed. + * + * It is the minimum stack size recommended for use on this processor. This + * value is selected by the RTEMS developers conservatively to minimize the + * risk of blown stacks for most user applications. Using this constant when + * specifying the task stack size, indicates that the stack size will be at + * least RTEMS_MINIMUM_STACK_SIZE bytes in size. If the user configured minimum + * stack size is larger than the recommended minimum, then it will be used. + */ +#define RTEMS_MINIMUM_STACK_SIZE STACK_MINIMUM_SIZE + +/** + * @brief Specifies that the task should be created with the configured minimum + * stack size. + * + * Using this constant when specifying the task stack size indicates that this + * task is to be created with a stack size of the minimum stack size that was + * configured by the application. If not explicitly configured by the + * application, the default configured minimum stack size is the processor + * dependent value RTEMS_MINIMUM_STACK_SIZE. Since this uses the configured + * minimum stack size value, you may get a stack size that is smaller or larger + * than the recommended minimum. This can be used to provide large stacks for + * all tasks on complex applications or small stacks on applications that are + * trying to conserve memory. + */ +#define RTEMS_CONFIGURED_MINIMUM_STACK_SIZE 0 + +/** + * @brief Constant for indefinite wait. + * + * This is actually an illegal interval value. + */ +#define RTEMS_NO_TIMEOUT WATCHDOG_NO_TIMEOUT + +/** + * @brief An MPCI must support packets of at least this size. + */ +#define RTEMS_MINIMUM_PACKET_SIZE MP_PACKET_MINIMUM_PACKET_SIZE + +/** + * @brief Defines the count of @c uint32_t numbers in a packet which must be + * converted to native format in a heterogeneous system. + * + * In packets longer than this value, some of the extra data may be a user + * message buffer which is not automatically endian swapped. + */ +#define RTEMS_MINIMUN_HETERO_CONVERSION MP_PACKET_MINIMUN_HETERO_CONVERSION + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/asr.h b/cpukit/rtems/include/rtems/rtems/asr.h new file mode 100644 index 0000000000..d733bd0626 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/asr.h @@ -0,0 +1,156 @@ +/** + * @file rtems/rtems/asr.h + * + * This include file contains all the constants and structures associated + * with the Asynchronous Signal Handler. This Handler provides the low-level + * support required by the Signal Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_ASR_H +#define _RTEMS_RTEMS_ASR_H + +#include <rtems/rtems/modes.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicASR ASR Support + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * The following type defines the control block used to manage + * each signal set. + */ +typedef uint32_t rtems_signal_set; + +/** + * Return type for ASR Handler + */ +typedef void rtems_asr; + +/** + * The following type corresponds to the applications asynchronous + * signal processing routine. + */ +typedef rtems_asr ( *rtems_asr_entry )( + rtems_signal_set + ); + +/** + * The following defines the control structure used to manage + * signals. Each thread has a copy of this record. + */ +typedef struct { + /** This field indicates if are ASRs enabled currently. */ + bool is_enabled; + /** This field indicates if address of the signal handler function. */ + rtems_asr_entry handler; + /** This field indicates if the task mode the signal will run with. */ + Modes_Control mode_set; + /** This field indicates the signal set that is posted. */ + rtems_signal_set signals_posted; + /** This field indicates the signal set that is pending. */ + rtems_signal_set signals_pending; + /** This field indicates if nest level of signals being processed */ + uint32_t nest_level; +} ASR_Information; + +/* + * The following constants define the individual signals which may + * be used to compose a signal set. + */ + +/** This defines the bit in the signal set associated with signal 0. */ +#define RTEMS_SIGNAL_0 0x00000001 +/** This defines the bit in the signal set associated with signal 1. */ +#define RTEMS_SIGNAL_1 0x00000002 +/** This defines the bit in the signal set associated with signal 2. */ +#define RTEMS_SIGNAL_2 0x00000004 +/** This defines the bit in the signal set associated with signal 3. */ +#define RTEMS_SIGNAL_3 0x00000008 +/** This defines the bit in the signal set associated with signal 4. */ +#define RTEMS_SIGNAL_4 0x00000010 +/** This defines the bit in the signal set associated with signal 5. */ +#define RTEMS_SIGNAL_5 0x00000020 +/** This defines the bit in the signal set associated with signal 6. */ +#define RTEMS_SIGNAL_6 0x00000040 +/** This defines the bit in the signal set associated with signal 7. */ +#define RTEMS_SIGNAL_7 0x00000080 +/** This defines the bit in the signal set associated with signal 8. */ +#define RTEMS_SIGNAL_8 0x00000100 +/** This defines the bit in the signal set associated with signal 9. */ +#define RTEMS_SIGNAL_9 0x00000200 +/** This defines the bit in the signal set associated with signal 10. */ +#define RTEMS_SIGNAL_10 0x00000400 +/** This defines the bit in the signal set associated with signal 11. */ +#define RTEMS_SIGNAL_11 0x00000800 +/** This defines the bit in the signal set associated with signal 12. */ +#define RTEMS_SIGNAL_12 0x00001000 +/** This defines the bit in the signal set associated with signal 13. */ +#define RTEMS_SIGNAL_13 0x00002000 +/** This defines the bit in the signal set associated with signal 14. */ +#define RTEMS_SIGNAL_14 0x00004000 +/** This defines the bit in the signal set associated with signal 15. */ +#define RTEMS_SIGNAL_15 0x00008000 +/** This defines the bit in the signal set associated with signal 16. */ +#define RTEMS_SIGNAL_16 0x00010000 +/** This defines the bit in the signal set associated with signal 17. */ +#define RTEMS_SIGNAL_17 0x00020000 +/** This defines the bit in the signal set associated with signal 18. */ +#define RTEMS_SIGNAL_18 0x00040000 +/** This defines the bit in the signal set associated with signal 19. */ +#define RTEMS_SIGNAL_19 0x00080000 +/** This defines the bit in the signal set associated with signal 20. */ +#define RTEMS_SIGNAL_20 0x00100000 +/** This defines the bit in the signal set associated with signal 21. */ +#define RTEMS_SIGNAL_21 0x00200000 +/** This defines the bit in the signal set associated with signal 22. */ +#define RTEMS_SIGNAL_22 0x00400000 +/** This defines the bit in the signal set associated with signal 23. */ +#define RTEMS_SIGNAL_23 0x00800000 +/** This defines the bit in the signal set associated with signal 24. */ +#define RTEMS_SIGNAL_24 0x01000000 +/** This defines the bit in the signal set associated with signal 25. */ +#define RTEMS_SIGNAL_25 0x02000000 +/** This defines the bit in the signal set associated with signal 26. */ +#define RTEMS_SIGNAL_26 0x04000000 +/** This defines the bit in the signal set associated with signal 27. */ +#define RTEMS_SIGNAL_27 0x08000000 +/** This defines the bit in the signal set associated with signal 28. */ +#define RTEMS_SIGNAL_28 0x10000000 +/** This defines the bit in the signal set associated with signal 29. */ +#define RTEMS_SIGNAL_29 0x20000000 +/** This defines the bit in the signal set associated with signal 30. */ +#define RTEMS_SIGNAL_30 0x40000000 +/** This defines the bit in the signal set associated with signal 31. */ +#define RTEMS_SIGNAL_31 0x80000000 + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/asr.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/attr.h b/cpukit/rtems/include/rtems/rtems/attr.h new file mode 100644 index 0000000000..0206ad5cc6 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/attr.h @@ -0,0 +1,198 @@ +/** + * @file rtems/rtems/attr.h + * + * This include file contains all information about the Object Attributes + * Handler. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_ATTR_H +#define _RTEMS_RTEMS_ATTR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicAttributes Attributes + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which defines and manages the + * set of Classic API object attributes. + */ +/**@{*/ + +/** + * This defines the type used to contain Classic API attributes. These + * are primarily used when creating objects. + */ +typedef uint32_t rtems_attribute; + +/** This is the default value for an attribute set. */ + +#define RTEMS_DEFAULT_ATTRIBUTES 0x00000000 + +/** + * This is the attribute constant to indicate local resource. + */ +#define RTEMS_LOCAL 0x00000000 + +/** + * This is the attribute constant to indicate global resource. + */ +#define RTEMS_GLOBAL 0x00000002 + +/** + * This is the attribute constant which reflects that blocking + * tasks will be managed using FIFO discipline. + */ +#define RTEMS_FIFO 0x00000000 + +/** + * This is the attribute constant which reflects that blocking + * tasks will be managed using task priority discipline. + */ +#define RTEMS_PRIORITY 0x00000004 + +/******************** RTEMS Task Specific Attributes *********************/ + +/** + * This attribute constant indicates that the task will not use the + * floating point hardware. If the architecture permits it, then + * the FPU will be disabled when the task is executing. + */ +#define RTEMS_NO_FLOATING_POINT 0x00000000 + +/** + * This attribute constant indicates that the task will use the + * floating point hardware. There will be a floating point + * context associated with this task. + */ +#define RTEMS_FLOATING_POINT 0x00000001 + +/***************** RTEMS Semaphore Specific Attributes ********************/ + +/** + * This is the mask for the attribute bits associated with the + * Classic API Semaphore Manager. + */ +#define RTEMS_SEMAPHORE_CLASS 0x00000030 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will be a counting semaphore. + */ +#define RTEMS_COUNTING_SEMAPHORE 0x00000000 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will be a proper binary semaphore or mutex. + */ +#define RTEMS_BINARY_SEMAPHORE 0x00000010 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will be a simple binary semaphore. + */ +#define RTEMS_SIMPLE_BINARY_SEMAPHORE 0x00000020 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will NOT use the Priority Inheritance Protocol. + */ +#define RTEMS_NO_INHERIT_PRIORITY 0x00000000 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will use the Priority Inheritance Protocol. + * + * @note The semaphore instance must be a binary semaphore. + */ +#define RTEMS_INHERIT_PRIORITY 0x00000040 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will NOT use the Priority Ceiling Protocol. + */ +#define RTEMS_NO_PRIORITY_CEILING 0x00000000 + +/** + * This attribute constant indicates that the Classic API Semaphore + * instance created will use the Priority Ceiling Protocol. + * + * @note The semaphore instance must be a binary semaphore. + */ +#define RTEMS_PRIORITY_CEILING 0x00000080 + +/******************** RTEMS Barrier Specific Attributes ********************/ + +/** + * This attribute constant indicates that the Classic API Barrier + * instance created will use an automatic release protocol. + */ +#define RTEMS_BARRIER_AUTOMATIC_RELEASE 0x00000010 + +/** + * This attribute constant indicates that the Classic API Barrier + * instance created will use the manual release protocol. + */ +#define RTEMS_BARRIER_MANUAL_RELEASE 0x00000000 + +/**************** RTEMS Internal Task Specific Attributes ****************/ + +/** + * This attribute constant indicates that the task was created + * by the application using normal Classic API methods. + */ +#define RTEMS_APPLICATION_TASK 0x00000000 + +/** + * This attribute constant indicates that the task was created + * by RTEMS as a support task. + */ +#define RTEMS_SYSTEM_TASK 0x00008000 + +/****************** Forced Attributes in Configuration ****************/ + +/** + * This attribute constant indicates the attributes that are not + * supportable given the hardware configuration. + */ +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) +#define ATTRIBUTES_NOT_SUPPORTED 0 +#else +#define ATTRIBUTES_NOT_SUPPORTED RTEMS_FLOATING_POINT +#endif + +/** + * This attribute constant indicates the attributes that are + * required given the hardware configuration. + */ +#if ( CPU_ALL_TASKS_ARE_FP == TRUE ) +#define ATTRIBUTES_REQUIRED RTEMS_FLOATING_POINT +#else +#define ATTRIBUTES_REQUIRED 0 +#endif + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/attr.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/barrier.h b/cpukit/rtems/include/rtems/rtems/barrier.h new file mode 100644 index 0000000000..566d0299e5 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/barrier.h @@ -0,0 +1,205 @@ +/** + * @file rtems/rtems/barrier.h + * + * This include file contains all the constants and structures associated + * with the Barrier Manager. + * + * Directives provided are: + * + * - create a barrier + * - get an ID of a barrier + * - delete a barrier + * - wait for a barrier + * - signal a barrier + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_BARRIER_H +#define _RTEMS_RTEMS_BARRIER_H + +/** + * @defgroup ClassicBarrier Barriers + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * This constant is defined to extern most of the time when using + * this header file. However by defining it to nothing, the data + * declared in this header file can be instantiated. This is done + * in a single per manager file. + */ +#ifndef RTEMS_BARRIER_EXTERN +#define RTEMS_BARRIER_EXTERN extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/rtems/types.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/status.h> +#include <rtems/score/object.h> +#include <rtems/score/corebarrier.h> + +/** + * This type defines the control block used to manage each barrier. + */ +typedef struct { + /** This is used to manage a barrier as an object. */ + Objects_Control Object; + /** This is used to specify the attributes of a barrier. */ + rtems_attribute attribute_set; + /** This is used to implement the barrier. */ + CORE_barrier_Control Barrier; +} Barrier_Control; + +/** + * The following defines the information control block used to manage + * this class of objects. + */ +RTEMS_BARRIER_EXTERN Objects_Information _Barrier_Information; + +/** + * @brief _Barrier_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Barrier_Manager_initialization(void); + +/** + * @brief rtems_barrier_create + * + * This routine implements the rtems_barrier_create directive. The + * barrier will have the name name. The starting count for + * the barrier is count. The attribute_set determines if + * the barrier is global or local and the thread queue + * discipline. It returns the id of the created barrier in ID. + * + * @param[in] name is the name of this barrier instance. + * @param[in] attribute_set specifies the attributes of this barrier instance. + * @param[in] maximum_waiters is the maximum number of threads which will + * be allowed to concurrently wait at the barrier. + * @param[out] id will contain the id of this barrier. + * + * @return a status code indicating success or the reason for failure. + */ +rtems_status_code rtems_barrier_create( + rtems_name name, + rtems_attribute attribute_set, + uint32_t maximum_waiters, + rtems_id *id +); + +/** + * @brief rtems_barrier_ident + * + * This routine implements the rtems_barrier_ident directive. + * This directive returns the barrier ID associated with name. + * If more than one barrier is named name, then the barrier + * to which the ID belongs is arbitrary. node indicates the + * extent of the search for the ID of the barrier named name. + * The search can be limited to a particular node or allowed to + * encompass all nodes. + * + * @param[in] name is the name of this barrier instance. + * @param[out] id will contain the id of this barrier. + * + * @return a status code indicating success or the reason for failure. + */ +rtems_status_code rtems_barrier_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief rtems_barrier_delete + * + * This routine implements the rtems_barrier_delete directive. The + * barrier indicated by @a id is deleted. + * + * @param[in] id indicates the barrier to delete + * + * @return a status code indicating success or the reason for failure. + */ +rtems_status_code rtems_barrier_delete( + rtems_id id +); + +/** + * @brief rtems_barrier_wait + * + * This routine implements the rtems_barrier_wait directive. It + * attempts to wait at the barrier associated with @a id. The calling task + * may block waiting for the barrier with an optional timeout of @a timeout + * clock ticks. + * + * @param[in] id indicates the barrier to wait at. + * @param[in] timeout is the maximum length of time in ticks the calling + * thread is willing to block. + * + * @return a status code indicating success or the reason for failure. + */ +rtems_status_code rtems_barrier_wait( + rtems_id id, + rtems_interval timeout +); + +/** + * @brief rtems_barrier_release + * + * This routine implements the rtems_barrier_release directive. It + * unblocks all of the threads waiting on the barrier associated with + * @a id. The number of threads unblocked is returned in @a released. + * + * + * @param[in] id indicates the barrier to wait at. + * @param[out] released will contain the number of threads unblocked. + * + * @return a status code indicating success or the reason for failure. + */ +rtems_status_code rtems_barrier_release( + rtems_id id, + uint32_t *released +); + +/** + * @brief Translate SuperCore Barrier Status Code to RTEMS Status Code + * + * This function returns a RTEMS status code based on the barrier + * status code specified. + * + * @param[in] the_status is the SuperCore Barrier status to translate. + * + * @return a status code indicating success or the reason for failure. + */ +rtems_status_code _Barrier_Translate_core_barrier_return_code ( + CORE_barrier_Status the_status +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/barrier.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/barriermp.h b/cpukit/rtems/include/rtems/rtems/barriermp.h new file mode 100644 index 0000000000..1a20680665 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/barriermp.h @@ -0,0 +1,151 @@ +/** + * @file rtems/rtems/barriermp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Barrier Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_SEMMP_H +#define _RTEMS_RTEMS_SEMMP_H + +/** + * @defgroup ClassicBarrierMP Barrier MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality which XXX + */ +/**{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/barrier.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> + +/** + * The following enumerated type defines the list of + * remote barrier operations. + */ +typedef enum { + BARRIER_MP_ANNOUNCE_CREATE = 0, + BARRIER_MP_ANNOUNCE_DELETE = 1, + BARRIER_MP_EXTRACT_PROXY = 2, + BARRIER_MP_WAIT_REQUEST = 3, + BARRIER_MP_WAIT_RESPONSE = 4, + BARRIER_MP_RELEASE_REQUEST = 5, + BARRIER_MP_RELEASE_RESPONSE = 6 +} Barrier_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote barrier operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + Barrier_MP_Remote_operations operation; + rtems_name name; + rtems_option option_set; + Objects_Id proxy_id; +} Barrier_MP_Packet; + +/** + * @brief _Barrier_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ +void _Barrier_MP_Send_process_packet ( + Barrier_MP_Remote_operations operation, + Objects_Id barrier_id, + rtems_name name, + Objects_Id proxy_id +); + +/** + * @brief _Barrier_MP_Send_request_packet + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ +rtems_status_code _Barrier_MP_Send_request_packet ( + Barrier_MP_Remote_operations operation, + Objects_Id barrier_id, + rtems_interval timeout +); + +/** + * @brief _Barrier_MP_Send_response_packet + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _Barrier_MP_Send_response_packet ( + Barrier_MP_Remote_operations operation, + Objects_Id barrier_id, + Thread_Control *the_thread +); + +/** + * @brief _Barrier_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Barrier_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/** + * @brief _Barrier_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + */ +void _Barrier_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +); + +/** + * @brief _Barrier_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ +void _Barrier_MP_Send_extract_proxy ( + void *argument +); + +/** + * @brief _Barrier_MP_Get_packet + * + * This function is used to obtain a barrier mp packet. + */ +Barrier_MP_Packet *_Barrier_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/cache.h b/cpukit/rtems/include/rtems/rtems/cache.h new file mode 100644 index 0000000000..72aab56cea --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/cache.h @@ -0,0 +1,158 @@ +/** + * @file rtems/rtems/cache.h + * + * Cache Manager + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * + * The functions in this file define the API to the RTEMS Cache Manager and + * are divided into data cache and instruction cache functions. Data cache + * functions are only meaningful if a data cache is supported. Instruction + * cache functions are only meaningful if an instruction cache is supported. + * + * The functions below are implemented with CPU dependent support routines + * implemented as part of libcpu. In the event that a CPU does not support a + * specific function, the CPU dependent routine does nothing (but does exist). + * + * At this point, the Cache Manager makes no considerations, and provides no + * support for BSP specific issues such as a secondary cache. In such a system, + * the CPU dependent routines would have to be modified, or a BSP layer added + * to this Manager. + */ + +#ifndef _RTEMS_RTEMS_CACHE_H +#define _RTEMS_RTEMS_CACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/system.h> +#include <sys/types.h> + +/** + * @defgroup ClassicCache Cache + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/* + * These functions will ONLY do something if the + * libcpu support includes data cache routines AND + * the CPU model supports data caching. + */ + +/** + * This function is called to flush the data cache by performing cache + * copybacks. It must determine how many cache lines need to be copied + * back and then perform the copybacks. + */ +void rtems_cache_flush_multiple_data_lines( const void *, size_t ); + +/** + * This function is responsible for performing a data cache invalidate. + * It must determine how many cache lines need to be invalidated and then + * perform the invalidations. + */ +void rtems_cache_invalidate_multiple_data_lines( const void *, size_t ); + +/** + * This function is responsible for performing a data cache flush. + * It flushes the entire cache. + */ +void rtems_cache_flush_entire_data( void ); + +/** + * This function is responsible for performing a data cache + * invalidate. It invalidates the entire cache. + */ +void rtems_cache_invalidate_entire_data( void ); + +/** + * This function returns the data cache granularity. + */ +int rtems_cache_get_data_line_size( void ); + +/** + * This function freezes the data cache. + */ +void rtems_cache_freeze_data( void ); + +/** + * This function unfreezes the data cache. + */ +void rtems_cache_unfreeze_data( void ); + +/** + * This function enables the data cache. + */ +void rtems_cache_enable_data( void ); + +/** + * This function disables the data cache. + */ +void rtems_cache_disable_data( void ); + +/** + * These functions will ONLY do something if the + * libcpu support includes instruction cache routines AND + * the CPU model supports instruction caching. + */ + +/** + * This function is responsible for performing an instruction cache + * invalidate. It must determine how many cache lines need to be invalidated + * and then perform the invalidations. + */ +void rtems_cache_invalidate_multiple_instruction_lines( const void *, size_t ); + +/** + * This function is responsible for performing an instruction cache + * invalidate. It invalidates the entire cache. + */ +void rtems_cache_invalidate_entire_instruction( void ); + +/** + * This function returns the instruction cache granularity. + */ +int rtems_cache_get_instruction_line_size( void ); + +/** + * This function freezes the instruction cache. + */ +void rtems_cache_freeze_instruction( void ); + +/** + * This function unfreezes the instruction cache. + */ +void rtems_cache_unfreeze_instruction( void ); + +/** + * This function enables the instruction cache. + */ +void rtems_cache_enable_instruction( void ); + +/** + * This function disables the instruction cache. + */ +void rtems_cache_disable_instruction( void ); + + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/clock.h b/cpukit/rtems/include/rtems/rtems/clock.h new file mode 100644 index 0000000000..7e2d776fe6 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/clock.h @@ -0,0 +1,267 @@ +/** + * @file rtems/rtems/clock.h + * + * This include file contains all the constants and structures associated + * with the Clock Manager. This manager provides facilities to set, obtain, + * and continually update the current date and time. + * + * This manager provides directives to: + * + * - set the current date and time + * - obtain the current date and time + * - set the nanoseconds since last clock tick handler + * - announce a clock tick + * - obtain the system uptime + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_CLOCK_H +#define _RTEMS_RTEMS_CLOCK_H + +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> + +#include <sys/time.h> /* struct timeval */ + +/** + * @defgroup ClassicClock Clocks + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * List of things which can be returned by the rtems_clock_get directive. + */ +typedef enum { + /** This value indicates obtain TOD in Classic API format. */ + RTEMS_CLOCK_GET_TOD, + /** This value indicates obtain the number of seconds since the epoch. */ + RTEMS_CLOCK_GET_SECONDS_SINCE_EPOCH, + /** This value indicates obtain the number of ticks since system boot. */ + RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, + /** This value indicates obtain the number of ticks per second. */ + RTEMS_CLOCK_GET_TICKS_PER_SECOND, + /** This value indicates obtain the TOD in struct timeval format. */ + RTEMS_CLOCK_GET_TIME_VALUE +} rtems_clock_get_options; + +/** + * Type for the nanoseconds since last tick BSP extension. + */ +typedef Watchdog_Nanoseconds_since_last_tick_routine + rtems_nanoseconds_extension_routine; + +/** + * @brief Obtain Current Time of Day + * + * This routine implements the rtems_clock_get directive. It returns + * one of the following: + * + current time of day + * + seconds since epoch + * + ticks since boot + * + ticks per second + * + * @param[in] option is the format of time to return + * @param[in] time_buffer points to the output area + * + * @return This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_clock_get( + rtems_clock_get_options option, + void *time_buffer +); + +/** + * @brief Obtain Current Time of Day (Classic TOD) + * + * This routine implements the rtems_clock_get_tod directive. It returns + * the current time of day in the format defined by RTEID. + * + * @param[in] time_buffer points to the time of day structure + * + * @return This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the time_buffer will + * be filled in with the current time of day. + */ +rtems_status_code rtems_clock_get_tod( + rtems_time_of_day *time_buffer +); + +/** + * @brief Obtain TOD in struct timeval Format + * + * This routine implements the rtems_clock_get_tod_timeval + * directive. + * + * @param[in] time points to the struct timeval variable to fill in + * + * @return This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the time will + * be filled in with the current time of day. + */ +rtems_status_code rtems_clock_get_tod_timeval( + struct timeval *time +); + +/** + * @brief Obtain Seconds Since Epoch + * + * This routine implements the rtems_clock_get_seconds_since_epoch + * directive. + * + * @param[in] the_interval points to the interval variable to fill in + * + * @return This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the time_buffer will + * be filled in with the current time of day. + */ +rtems_status_code rtems_clock_get_seconds_since_epoch( + rtems_interval *the_interval +); + +/** + * @brief Obtain Ticks Since Boot + * + * This routine implements the rtems_clock_get_ticks_since_boot + * directive. + * + * @return This method returns the number of ticks since boot. It cannot + * fail since RTEMS always keeps a running count of ticks since boot. + */ +rtems_interval rtems_clock_get_ticks_since_boot(void); + +/** + * @brief Obtain Ticks Per Seconds + * + * This routine implements the rtems_clock_get_ticks_per_second + * directive. + * + * @return This method returns the number of ticks since boot. It cannot + * fail since RTEMS is always configured to know the number of + * ticks per second. + */ +rtems_interval rtems_clock_get_ticks_per_second(void); + +/** + * @brief Set the Current TOD + * + * This routine implements the rtems_clock_set directive. It sets + * the current time of day to that in the time_buffer record. + * + * @param[in] time_buffer points to the new TOD + * + * @return This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + * + * @note Activities scheduled based upon the current time of day + * may be executed immediately if the time is moved forward. + */ +rtems_status_code rtems_clock_set( + rtems_time_of_day *time_buffer +); + +/** + * @brief Announce a Clock Tick + * + * This routine implements the rtems_clock_tick directive. It is invoked + * to inform RTEMS of the occurrence of a clock tick. + * + * @return This directive always returns RTEMS_SUCCESSFUL. + * + * @note This method is typically called from an ISR and is the basis + * for all timeouts and delays. + */ +rtems_status_code rtems_clock_tick( void ); + +/** + * @brief Set the BSP specific Nanoseconds Extension + * + * This directive sets the BSP provided nanoseconds since last tick + * extension. + * + * @param[in] routine is a pointer to the extension routine + * + * @return This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. + */ +rtems_status_code rtems_clock_set_nanoseconds_extension( + rtems_nanoseconds_extension_routine routine +); + +/** + * @brief Obtain the System Uptime + * + * This directive returns the system uptime. + * + * @param[in] uptime is a pointer to the time structure + * + * @return This method returns RTEMS_SUCCESSFUL if there was not an + * error. Otherwise, a status code is returned indicating the + * source of the error. If successful, the uptime will be + * filled in. + */ +rtems_status_code rtems_clock_get_uptime( + struct timespec *uptime +); + +/** + * @brief _TOD_Validate + * + * This support function returns true if @a the_tod contains + * a valid time of day, and false otherwise. + * + * @param[in] the_tod is the TOD structure to validate + * + * @return This method returns true if the TOD is valid and false otherwise. + */ +bool _TOD_Validate( + const rtems_time_of_day *the_tod +); + +/** + * @brief _TOD_To_seconds + * + * This function returns the number seconds between the epoch and @a the_tod. + * + * @param[in] the_tod is the TOD structure to convert to seconds + * + * @return This method returns the number of seconds since epoch represented + * by @a the_tod + */ +Watchdog_Interval _TOD_To_seconds( + const rtems_time_of_day *the_tod +); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/config.h b/cpukit/rtems/include/rtems/rtems/config.h new file mode 100644 index 0000000000..2217463d5a --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/config.h @@ -0,0 +1,151 @@ +/** + * @file rtems/rtems/config.h + * + * This include file contains the table of user defined configuration + * parameters specific for the RTEMS API. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_CONFIG_H +#define _RTEMS_RTEMS_CONFIG_H + +#include <rtems/rtems/types.h> +#include <rtems/rtems/tasks.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicConfig Configuration + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * The following records define the Configuration Table. The + * information contained in this table is required in all + * RTEMS systems, whether single or multiprocessor. This + * table primarily defines the following: + * + * + required number of each object type + */ +typedef struct { + /** + * This field contains the maximum number of Classic API + * Tasks which are configured for this application. + */ + uint32_t maximum_tasks; + + /** + * This field indicates whether Classic API notepads are + * enabled or disabled. + */ + bool notepads_enabled; + + /** + * This field contains the maximum number of Classic API + * Timers which are configured for this application. + */ + uint32_t maximum_timers; + + /** + * This field contains the maximum number of Classic API + * Semaphores which are configured for this application. + */ + uint32_t maximum_semaphores; + + /** + * This field contains the maximum number of Classic API + * Message Queues which are configured for this application. + */ + uint32_t maximum_message_queues; + + /** + * This field contains the maximum number of Classic API + * Partitions which are configured for this application. + */ + uint32_t maximum_partitions; + + /** + * This field contains the maximum number of Classic API + * Regions which are configured for this application. + */ + uint32_t maximum_regions; + + /** + * This field contains the maximum number of Classic API + * Dual Ported Memory Areas which are configured for this + * application. + */ + uint32_t maximum_ports; + + /** + * This field contains the maximum number of Classic API + * Rate Monotonic Periods which are configured for this + * application. + */ + uint32_t maximum_periods; + + /** + * This field contains the maximum number of Classic API + * Barriers which are configured for this application. + */ + uint32_t maximum_barriers; + + /** + * This field contains the number of Classic API Initialization + * Tasks which are configured for this application. + */ + uint32_t number_of_initialization_tasks; + + /** + * This field is the set of Classic API Initialization + * Tasks which are configured for this application. + */ + rtems_initialization_tasks_table *User_initialization_tasks_table; +} rtems_api_configuration_table; + +/** + * @brief RTEMS API Configuration Table + * + * This is the RTEMS API Configuration Table expected to be generated + * by confdefs.h. + */ +extern rtems_api_configuration_table Configuration_RTEMS_API; + +/**@}*/ + +/** + * This macro returns the value of the notepads enabled field + * in the Classic API configuration table. + */ +#define rtems_configuration_get_notepads_enabled() \ + rtems_configuration_get_rtems_api_configuration()->notepads_enabled + +/** + * This macro returns the number of Classic API semaphores configured. + */ +#define rtems_configuration_get_maximum_semaphores() \ + rtems_configuration_get_rtems_api_configuration()->maximum_semaphores + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/dpmem.h b/cpukit/rtems/include/rtems/rtems/dpmem.h new file mode 100644 index 0000000000..86885143b5 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/dpmem.h @@ -0,0 +1,164 @@ +/** + * @file rtems/rtems/dpmem.h + * + * This include file contains all the constants and structures associated + * with the Dual Ported Memory Manager. This manager provides a mechanism + * for converting addresses between internal and external representations + * for multiple dual-ported memory areas. + * + * Directives provided are: + * + * - create a port + * - get ID of a port + * - delete a port + * - convert external to internal address + * - convert internal to external address + * + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_DPMEM_H +#define _RTEMS_RTEMS_DPMEM_H + +/** + * This constant is defined to extern most of the time when using + * this header file. However by defining it to nothing, the data + * declared in this header file can be instantiated. This is done + * in a single per manager file. + */ +#ifndef RTEMS_DPMEM_EXTERN +#define RTEMS_DPMEM_EXTERN extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/object.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/status.h> + +/** + * @defgroup ClassicDPMEM Dual Ported Memory + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the + * Classic API Dual Ported Memory Manager. + */ +/**@{*/ + +/** + * The following structure defines the port control block. Each port + * has a control block associated with it. This control block contains + * all information required to support the port related operations. + */ +typedef struct { + /** This field is the object management portion of a Port instance. */ + Objects_Control Object; + /** This field is the base internal address of the port. */ + void *internal_base; + /** This field is the base external address of the port. */ + void *external_base; + /** This field is the length of dual-ported area of the port. */ + uint32_t length; +} Dual_ported_memory_Control; + +/** + * The following define the internal Dual Ported Memory information. + */ +RTEMS_DPMEM_EXTERN Objects_Information _Dual_ported_memory_Information; + +/** + * @brief _Dual_ported_memory_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Dual_ported_memory_Manager_initialization(void); + +/** + * @brief rtems_port_create + * + * This routine implements the rtems_port_create directive. The port + * will have the name name. The port maps onto an area of dual ported + * memory of length bytes which has internal_start and external_start + * as the internal and external starting addresses, respectively. + * It returns the id of the created port in ID. + */ +rtems_status_code rtems_port_create( + rtems_name name, + void *internal_start, + void *external_start, + uint32_t length, + rtems_id *id +); + +/** + * @brief rtems_port_ident + * + * This routine implements the rtems_port_ident directive. This directive + * returns the port ID associated with name. If more than one port is + * named name, then the port to which the ID belongs is arbitrary. + */ +rtems_status_code rtems_port_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief rtems_port_delete + * + * This routine implements the rtems_port_delete directive. It deletes + * the port associated with ID. + */ +rtems_status_code rtems_port_delete( + rtems_id id +); + +/** + * @brief rtems_port_external_to_internal + * + * This routine implements the rtems_port_external_to_internal directive. + * It returns the internal port address which maps to the provided + * external port address for the specified port ID. + */ +rtems_status_code rtems_port_external_to_internal( + rtems_id id, + void *external, + void **internal +); + +/** + * @brief rtems_port_internal_to_external + * + * This routine implements the Port_internal_to_external directive. + * It returns the external port address which maps to the provided + * internal port address for the specified port ID. + */ +rtems_status_code rtems_port_internal_to_external( + rtems_id id, + void *internal, + void **external +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/dpmem.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h new file mode 100644 index 0000000000..05f66d64cd --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/event.h @@ -0,0 +1,166 @@ +/** + * @file rtems/rtems/event.h + * + * This include file contains the information pertaining to the Event + * Manager. This manager provides a high performance method of communication + * and synchronization. + * + * Directives provided are: + * + * - send an event set to a task + * - receive event condition + * + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_EVENT_H +#define _RTEMS_RTEMS_EVENT_H + +/** + * This constant is defined to extern most of the time when using + * this header file. However by defining it to nothing, the data + * declared in this header file can be instantiated. This is done + * in a single per manager file. + */ +#ifndef RTEMS_EVENT_EXTERN +#define RTEMS_EVENT_EXTERN extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/object.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> +#include <rtems/rtems/options.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadsync.h> +#include <rtems/score/watchdog.h> +#include <rtems/rtems/eventset.h> + +/** + * @defgroup ClassicEvent Events + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * This constant is passed as the event_in to the + * rtems_event_receive directive to determine which events are pending. + */ +#define EVENT_CURRENT 0 + +/** + * @brief Event_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Event_Manager_initialization( void ); + +/** + * @brief rtems_event_send + * + * This routine implements the rtems_event_send directive. It sends + * event_in to the task specified by ID. If the task is blocked + * waiting to receive events and the posting of event_in satisfies + * the task's event condition, then it is unblocked. + */ +rtems_status_code rtems_event_send ( + rtems_id id, + rtems_event_set event_in +); + +/** + * @brief rtems_event_receive + * + * This routine implements the rtems_event_receive directive. This + * directive is invoked when the calling task wishes to receive + * the event_in event condition. One of the fields in the option_set + * parameter determines whether the receive request is satisfied if + * any or all of the events are pending. If the event condition + * is not satisfied immediately, then the task may block with an + * optional timeout of TICKS clock ticks or return immediately. + * This determination is based on another field in the option_set + * parameter. This directive returns the events received in the + * event_out parameter. + */ +rtems_status_code rtems_event_receive ( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +); + +/** + * @brief Event_Seize + * + * This routine determines if the event condition event_in is + * satisfied. If so or if the no_wait option is enabled in option_set, + * then the procedure returns immediately. If neither of these + * conditions is true, then the calling task is blocked with an + * optional timeout of ticks clock ticks. + */ +void _Event_Seize ( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +); + +/** + * @brief Event_Surrender + * + * This routine determines if the event condition of the_thread + * has been satisfied. If so, it unblocks the_thread. + */ +void _Event_Surrender ( + Thread_Control *the_thread +); + +/** + * @brief Event_Timeout + * + * This routine is invoked when a task's event receive request + * has not been satisfied after the specified timeout interval. + * The task represented by ID will be unblocked and its status + * code will be set in it's control block to indicate that a timeout + * has occurred. + */ +void _Event_Timeout ( + Objects_Id id, + void *ignored +); + +/** + * @brief he following defines the synchronization flag used by the + */ +RTEMS_EVENT_EXTERN volatile Thread_blocking_operation_States _Event_Sync_state; + +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/eventmp.h> +#endif +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/event.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/eventmp.h b/cpukit/rtems/include/rtems/rtems/eventmp.h new file mode 100644 index 0000000000..bc44fe6aab --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/eventmp.h @@ -0,0 +1,138 @@ +/** + * @file rtems/rtems/eventmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Event Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_EVENTMP_H +#define _RTEMS_RTEMS_EVENTMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/rtems/event.h> +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> + +/** + * @defgroup ClassicEventMP Event MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * The following enumerated type defines the list of + * remote event operations. + */ +typedef enum { + EVENT_MP_SEND_REQUEST = 0, + EVENT_MP_SEND_RESPONSE = 1 +} Event_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote event operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + Event_MP_Remote_operations operation; + rtems_event_set event_in; +} Event_MP_Packet; + +/* + * @brief Event_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + * + * @note This routine is not needed since there are no process + * packets to be sent by this manager. + */ + +/** + * @brief Event_MP_Send_request_packet + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ +rtems_status_code _Event_MP_Send_request_packet ( + Event_MP_Remote_operations operation, + Objects_Id event_id, + rtems_event_set event_in +); + +/** + * @brief Event_MP_Send_response_packet + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ +void _Event_MP_Send_response_packet ( + Event_MP_Remote_operations operation, + Thread_Control *the_thread +); + +/** + * @brief Event_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Event_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/* + * @brief Event_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + * + * This routine is not needed since there are no objects + * deleted by this manager. + */ + +/* + * @brief Event_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + * + * This routine is not needed since there are no objects + * deleted by this manager. + */ + +/** + * @brief Event_MP_Get_packet + * + * This function is used to obtain a event mp packet. + */ +Event_MP_Packet *_Event_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/eventset.h b/cpukit/rtems/include/rtems/rtems/eventset.h new file mode 100644 index 0000000000..679934f22b --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/eventset.h @@ -0,0 +1,135 @@ +/** + * @file rtems/rtems/eventset.h + * + * This include file contains the information pertaining to the + * Event Sets Handler. This handler provides methods for the manipulation + * of event sets which will be sent and received by tasks. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_EVENTSET_H +#define _RTEMS_RTEMS_EVENTSET_H + +/** + * @defgroup ClassicEventSet Event Sets + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to Classic API + * Event Sets. These are used by the Classic API Event Manager. + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The following defines the type used to control event sets. + */ +typedef uint32_t rtems_event_set; + +/** + * The following constant is used to receive the set of currently pending + * events. + */ +#define RTEMS_PENDING_EVENTS 0 + +/** + * The following constant is used when you wish to send or receive all + * events. + */ +#define RTEMS_ALL_EVENTS 0xFFFFFFFF + +/** This defines the bit in the event set associated with event 0. */ +#define RTEMS_EVENT_0 0x00000001 +/** This defines the bit in the event set associated with event 1. */ +#define RTEMS_EVENT_1 0x00000002 +/** This defines the bit in the event set associated with event 2. */ +#define RTEMS_EVENT_2 0x00000004 +/** This defines the bit in the event set associated with event 3. */ +#define RTEMS_EVENT_3 0x00000008 +/** This defines the bit in the event set associated with event 4. */ +#define RTEMS_EVENT_4 0x00000010 +/** This defines the bit in the event set associated with event 5. */ +#define RTEMS_EVENT_5 0x00000020 +/** This defines the bit in the event set associated with event 6. */ +#define RTEMS_EVENT_6 0x00000040 +/** This defines the bit in the event set associated with event 7. */ +#define RTEMS_EVENT_7 0x00000080 +/** This defines the bit in the event set associated with event 8. */ +#define RTEMS_EVENT_8 0x00000100 +/** This defines the bit in the event set associated with event 9. */ +#define RTEMS_EVENT_9 0x00000200 +/** This defines the bit in the event set associated with event 10. */ +#define RTEMS_EVENT_10 0x00000400 +/** This defines the bit in the event set associated with event 11. */ +#define RTEMS_EVENT_11 0x00000800 +/** This defines the bit in the event set associated with event 12. */ +#define RTEMS_EVENT_12 0x00001000 +/** This defines the bit in the event set associated with event 13. */ +#define RTEMS_EVENT_13 0x00002000 +/** This defines the bit in the event set associated with event 14. */ +#define RTEMS_EVENT_14 0x00004000 +/** This defines the bit in the event set associated with event 15. */ +#define RTEMS_EVENT_15 0x00008000 +/** This defines the bit in the event set associated with event 16. */ +#define RTEMS_EVENT_16 0x00010000 +/** This defines the bit in the event set associated with event 17. */ +#define RTEMS_EVENT_17 0x00020000 +/** This defines the bit in the event set associated with event 18. */ +#define RTEMS_EVENT_18 0x00040000 +/** This defines the bit in the event set associated with event 19. */ +#define RTEMS_EVENT_19 0x00080000 +/** This defines the bit in the event set associated with event 20. */ +#define RTEMS_EVENT_20 0x00100000 +/** This defines the bit in the event set associated with event 21. */ +#define RTEMS_EVENT_21 0x00200000 +/** This defines the bit in the event set associated with event 22. */ +#define RTEMS_EVENT_22 0x00400000 +/** This defines the bit in the event set associated with event 23. */ +#define RTEMS_EVENT_23 0x00800000 +/** This defines the bit in the event set associated with event 24. */ +#define RTEMS_EVENT_24 0x01000000 +/** This defines the bit in the event set associated with event 25. */ +#define RTEMS_EVENT_25 0x02000000 +/** This defines the bit in the event set associated with event 26. */ +#define RTEMS_EVENT_26 0x04000000 +/** This defines the bit in the event set associated with event 27. */ +#define RTEMS_EVENT_27 0x08000000 +/** This defines the bit in the event set associated with event 29. */ +#define RTEMS_EVENT_28 0x10000000 +/** This defines the bit in the event set associated with event 29. */ +#define RTEMS_EVENT_29 0x20000000 +/** This defines the bit in the event set associated with event 30. */ +#define RTEMS_EVENT_30 0x40000000 +/** This defines the bit in the event set associated with event 31. */ +#define RTEMS_EVENT_31 0x80000000 + +/** + * The following constant is the value of an event set which + * has no events pending. + */ +#define EVENT_SETS_NONE_PENDING 0 + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/eventset.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/intr.h b/cpukit/rtems/include/rtems/rtems/intr.h new file mode 100644 index 0000000000..9b0b1b4608 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/intr.h @@ -0,0 +1,136 @@ +/** + * @file rtems/rtems/intr.h + * + * @brief Header file for the Interrupt Manager. + * + * This include file contains all the constants and structures associated with + * the Interrupt Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_INTR_H +#define _RTEMS_RTEMS_INTR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/isr.h> + +/** + * @defgroup ClassicINTR Interrupts + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * @brief Interrupt level type. + */ +typedef ISR_Level rtems_interrupt_level; + +/** + * @brief Control block type used to manage the vectors. + */ +typedef ISR_Vector_number rtems_vector_number; + +/** + * @brief Return type for interrupt handler. + */ +typedef void rtems_isr; + +/** + * @brief Interrupt handler type. + * + * @see rtems_interrupt_catch() + */ +typedef rtems_isr ( *rtems_isr_entry )( + rtems_vector_number + ); + +#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE) +/** + * @brief Implementation of the rtems_interrupt_catch directive. + * + * This directive installs @a new_isr_handler as the RTEMS interrupt service + * routine for the interrupt vector with number @a vector. The previous RTEMS + * interrupt service routine is returned in @a old_isr_handler. + */ +rtems_status_code rtems_interrupt_catch( + rtems_isr_entry new_isr_handler, + rtems_vector_number vector, + rtems_isr_entry *old_isr_handler +); +#endif + +/** + * @brief Disables all maskable interrupts and returns the previous level in + * @a _isr_cookie. + * + * @note The interrupt level shall be of type @ref rtems_interrupt_level. + */ +#define rtems_interrupt_disable( _isr_cookie ) \ + _ISR_Disable(_isr_cookie) + +/** + * @brief Enables maskable interrupts to the level indicated by @a + * _isr_cookie. + * + * @note The interrupt level shall be of type @ref rtems_interrupt_level. + */ +#define rtems_interrupt_enable( _isr_cookie ) \ + _ISR_Enable(_isr_cookie) + +/** + * @brief Temporarily enables maskable interrupts to the level in @a + * _isr_cookie before redisabling them. + * + * @note The interrupt level shall be of type @ref rtems_interrupt_level. + */ +#define rtems_interrupt_flash( _isr_cookie ) \ + _ISR_Flash(_isr_cookie) + +/** + * @brief Returns true if the processor is currently servicing an interrupt + * and false otherwise. + * + * A return value of true indicates that the caller is an interrupt service + * routine and @b not a thread. The directives available to an interrupt + * service routine are restricted. + */ +#define rtems_interrupt_is_in_progress() \ + _ISR_Is_in_progress() + +/** + * @brief This routine generates an interrupt. + * + * @note No implementation. + */ +#define rtems_interrupt_cause( _interrupt_to_cause ) + +/** + * @brief This routine clears the specified interrupt. + * + * @note No implementation. + */ +#define rtems_interrupt_clear( _interrupt_to_clear ) + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/message.h b/cpukit/rtems/include/rtems/rtems/message.h new file mode 100644 index 0000000000..c56cc220a1 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/message.h @@ -0,0 +1,313 @@ +/** + * @file rtems/rtems/message.h + * + * This include file contains all the constants and structures associated + * with the Message Queue Manager. This manager provides a mechanism for + * communication and synchronization between tasks using messages. + * + * Directives provided are: + * + * - create a queue + * - get ID of a queue + * - delete a queue + * - put a message at the rear of a queue + * - put a message at the front of a queue + * - broadcast N messages to a queue + * - receive message from a queue + * - flush all messages on a queue + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_MESSAGE_H +#define _RTEMS_RTEMS_MESSAGE_H + +/** + * This constant is defined to extern most of the time when using + * this header file. However by defining it to nothing, the data + * declared in this header file can be instantiated. This is done + * in a single per manager file. + */ +#ifndef RTEMS_MESSAGE_EXTERN +#define RTEMS_MESSAGE_EXTERN extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/rtems/types.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/options.h> +#include <rtems/score/chain.h> +#include <rtems/score/object.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/coremsg.h> + +/** + * @defgroup ClassicMessageQueue Message Queues + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * The following enumerated type details the modes in which a message + * may be submitted to a message queue. The message may be posted + * in a send or urgent fashion. + */ +typedef enum { + /** + * This value indicates the user wants to send the message using the + * normal message insertion protocol (FIFO or priority). + */ + MESSAGE_QUEUE_SEND_REQUEST = 0, + /** + * This value indicates the user considers the message to be urgent + * and wants it inserted at the head of the pending message queue. + */ + MESSAGE_QUEUE_URGENT_REQUEST = 1 +} Message_queue_Submit_types; + +/** + * The following records define the control block used to manage + * each message queue. + */ +typedef struct { + /** This field is the inherited object characteristics. */ + Objects_Control Object; + /** This field is the attribute set as defined by the API. */ + rtems_attribute attribute_set; + /** This field is the instance of the SuperCore Message Queue. */ + CORE_message_queue_Control message_queue; +} Message_queue_Control; + +/** + * The following defines the information control block used to + * manage this class of objects. + */ +RTEMS_MESSAGE_EXTERN Objects_Information _Message_queue_Information; + +/** + * @brief Message_queue_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Message_queue_Manager_initialization(void); + +/** + * @brief rtems_message_queue_create + * + * This routine implements the rtems_message_queue_create directive. The + * message queue will have the name name. If the attribute_set indicates + * that the message queue is to be limited in the number of messages + * that can be outstanding, then count indicates the maximum number of + * messages that will be held. It returns the id of the created + * message queue in ID. + */ +rtems_status_code rtems_message_queue_create( + rtems_name name, + uint32_t count, + size_t max_message_size, + rtems_attribute attribute_set, + rtems_id *id +); + +/** + * @brief rtems_message_queue_ident + * + * This routine implements the rtems_message_queue_ident directive. + * This directive returns the message queue ID associated with NAME. + * If more than one message queue is named name, then the message + * queue to which the ID belongs is arbitrary. node indicates the + * extent of the search for the ID of the message queue named name. + * The search can be limited to a particular node or allowed to + * encompass all nodes. + */ +rtems_status_code rtems_message_queue_ident( + rtems_name name, + uint32_t node, + rtems_id *id +); + +/** + * @brief rtems_message_queue_delete + * + * This routine implements the rtems_message_queue_delete directive. The + * message queue indicated by ID is deleted. + */ +rtems_status_code rtems_message_queue_delete( + rtems_id id +); + +/** + * @brief rtems_message_queue_send + * + * This routine implements the rtems_message_queue_send directive. + * This directive sends the message buffer to the message queue + * indicated by ID. If one or more tasks is blocked waiting + * to receive a message from this message queue, then one will + * receive the message. The task selected to receive the + * message is based on the task queue discipline algorithm in + * use by this particular message queue. If no tasks are waiting, + * then the message buffer will be placed at the REAR of the + * chain of pending messages for this message queue. + */ +rtems_status_code rtems_message_queue_send( + rtems_id id, + const void *buffer, + size_t size +); + +/** + * @brief rtems_message_queue_urgent + * + * This routine implements the rtems_message_queue_urgent directive. + * This directive has the same behavior as rtems_message_queue_send + * except that if no tasks are waiting, the message buffer will + * be placed at the FRONT of the chain of pending messages rather + * than at the REAR. + */ +rtems_status_code rtems_message_queue_urgent( + rtems_id id, + const void *buffer, + size_t size +); + +/** + * @brief rtems_message_queue_broadcast + * + * This routine implements the rtems_message_queue_broadcast directive. + * This directive sends the message buffer to all of the tasks blocked + * waiting for a message on the message queue indicated by ID. + * If no tasks are waiting, then the message buffer will not be queued. + */ +rtems_status_code rtems_message_queue_broadcast( + rtems_id id, + const void *buffer, + size_t size, + uint32_t *count +); + +/** + * @brief rtems_message_queue_receive + * + * This routine implements the rtems_message_queue_receive directive. + * This directive is invoked when the calling task wishes to receive + * a message from the message queue indicated by ID. The received + * message is to be placed in buffer. If no messages are outstanding + * and the option_set indicates that the task is willing to block, + * then the task will be blocked until a message arrives or until, + * optionally, timeout clock ticks have passed. + */ +rtems_status_code rtems_message_queue_receive( + rtems_id id, + void *buffer, + size_t *size, + rtems_option option_set, + rtems_interval timeout +); + +/** + * @brief rtems_message_queue_flush + * + * This routine implements the rtems_message_queue_flush directive. + * This directive takes all outstanding messages for the message + * queue indicated by ID and returns them to the inactive message + * chain. The number of messages flushed is returned in COUNT. + */ +rtems_status_code rtems_message_queue_flush( + rtems_id id, + uint32_t *count +); + +/** + * @brief rtems_message_queue_get_number_pending + * + * This routine implements the rtems_message_queue_get_number_pending + * directive. This directive returns the number of pending + * messages for the message queue indicated by ID + * chain. The number of messages pending is returned in COUNT. + */ +rtems_status_code rtems_message_queue_get_number_pending( + rtems_id id, + uint32_t *count +); + + +/** + * @brief Message_queue_Submit + * + * This routine implements the directives rtems_message_queue_send + * and rtems_message_queue_urgent. It processes a message that is + * to be submitted to the designated message queue. The message will + * either be processed as a send send message which it will be inserted + * at the rear of the queue or it will be processed as an urgent message + * which will be inserted at the front of the queue. + */ +rtems_status_code _Message_queue_Submit( + rtems_id id, + const void *buffer, + size_t size, + Message_queue_Submit_types submit_type +); + +/** + * @brief Message_queue_Allocate + * + * This function allocates a message queue control block from + * the inactive chain of free message queue control blocks. + */ +Message_queue_Control *_Message_queue_Allocate (void); + +/** + * @brief Message_queue_Translate_core_message_queue_return_code + * + * This function returns a RTEMS status code based on the core message queue + * status code specified. + */ +rtems_status_code _Message_queue_Translate_core_message_queue_return_code ( + uint32_t the_message_queue_status +); + +#if defined(RTEMS_MULTIPROCESSING) +/** + * @brief Message_queue_Core_message_queue_mp_support + * + * Input parameters: + * the_thread - the remote thread the message was submitted to + * id - id of the message queue + * + * Output parameters: NONE + */ +void _Message_queue_Core_message_queue_mp_support ( + Thread_Control *the_thread, + rtems_id id +); +#endif + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/message.inl> +#endif +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/msgmp.h> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/modes.h b/cpukit/rtems/include/rtems/rtems/modes.h new file mode 100644 index 0000000000..0665d17c8b --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/modes.h @@ -0,0 +1,111 @@ +/** + * @file rtems/rtems/modes.h + * + * This include file contains all constants and structures associated + * with the RTEMS thread and RTEMS_ASR modes. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_MODES_H +#define _RTEMS_RTEMS_MODES_H + +/** + * @defgroup ClassicModes Modes + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/isr.h> + +/** + * The following type defines the control block used to manage + * each a mode set. + */ +typedef uint32_t Modes_Control; + +/** + * The following constants define the individual modes and masks + * which may be used to compose a mode set and to alter modes. + */ +#define RTEMS_ALL_MODE_MASKS 0x0000ffff + +/** + * This mode constant is the default mode set. + */ +#define RTEMS_DEFAULT_MODES 0x00000000 + +/** + * This mode constant is used when the user wishes to obtain their + * current execution mode. + */ +#define RTEMS_CURRENT_MODE 0 + +/** This mode constant corresponds to the timeslice enable/disable bit. */ +#define RTEMS_TIMESLICE_MASK 0x00000200 + +/** This mode constant corresponds to the preemption enable/disable bit. */ +#define RTEMS_PREEMPT_MASK 0x00000100 + +/** This mode constant corresponds to the signal enable/disable bit. */ +#define RTEMS_ASR_MASK 0x00000400 + +/** This mode constant corresponds to the interrupt enable/disable bits. */ +#define RTEMS_INTERRUPT_MASK CPU_MODES_INTERRUPT_MASK + +/** This mode constant is used to indicate preemption is enabled. */ +#define RTEMS_PREEMPT 0x00000000 +/** This mode constant is used to indicate preemption is disabled. */ +#define RTEMS_NO_PREEMPT 0x00000100 + +/** This mode constant is used to indicate timeslicing is disabled. */ +#define RTEMS_NO_TIMESLICE 0x00000000 +/** This mode constant is used to indicate timeslicing is enabled. */ +#define RTEMS_TIMESLICE 0x00000200 + +/** This mode constant is used to indicate signal processing is enabled. */ +#define RTEMS_ASR 0x00000000 +/** This mode constant is used to indicate signal processing is disabled. */ +#define RTEMS_NO_ASR 0x00000400 + +/** + * @brief RTEMS_INTERRUPT_LEVEL + * + * This function returns the processor dependent interrupt + * level which corresponds to the requested interrupt level. + * + * @note RTEMS supports 256 interrupt levels using the least + * significant eight bits of MODES.CONTROL. On any + * particular CPU, fewer than 256 levels may be supported. + */ +#define RTEMS_INTERRUPT_LEVEL( _mode_set ) \ + ( (_mode_set) & RTEMS_INTERRUPT_MASK ) + + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/modes.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/mp.h b/cpukit/rtems/include/rtems/rtems/mp.h new file mode 100644 index 0000000000..1f8252aac3 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/mp.h @@ -0,0 +1,57 @@ +/** + * @file rtems/rtems/mp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_MP_H +#define _RTEMS_RTEMS_MP_H + +/** + * @defgroup ClassicMP Multiprocessing + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Multiprocessing_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Multiprocessing_Manager_initialization ( void ); + +/** + * @brief rtems_multiprocessing_announce + * + * This routine implements the MULTIPROCESSING_ANNOUNCE directive. + * It is invoked by the MPCI layer to indicate that an MPCI packet + * has been received. + */ +void rtems_multiprocessing_announce ( void ); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/msgmp.h b/cpukit/rtems/include/rtems/rtems/msgmp.h new file mode 100644 index 0000000000..8aa5f533ae --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/msgmp.h @@ -0,0 +1,166 @@ +/** + * @file rtems/rtems/msgmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Message Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_MSGMP_H +#define _RTEMS_RTEMS_MSGMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/rtems/message.h> +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> + +/** + * @defgroup ClassicMsgMP Message Queue MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality which XXX + */ +/**{*/ + +/** + * The following enumerated type defines the list of + * remote message queue operations. + */ +typedef enum { + MESSAGE_QUEUE_MP_ANNOUNCE_CREATE = 0, + MESSAGE_QUEUE_MP_ANNOUNCE_DELETE = 1, + MESSAGE_QUEUE_MP_EXTRACT_PROXY = 2, + MESSAGE_QUEUE_MP_RECEIVE_REQUEST = 3, + MESSAGE_QUEUE_MP_RECEIVE_RESPONSE = 4, + MESSAGE_QUEUE_MP_SEND_REQUEST = 5, + MESSAGE_QUEUE_MP_SEND_RESPONSE = 6, + MESSAGE_QUEUE_MP_URGENT_REQUEST = 7, + MESSAGE_QUEUE_MP_URGENT_RESPONSE = 8, + MESSAGE_QUEUE_MP_BROADCAST_REQUEST = 9, + MESSAGE_QUEUE_MP_BROADCAST_RESPONSE = 10, + MESSAGE_QUEUE_MP_FLUSH_REQUEST = 11, + MESSAGE_QUEUE_MP_FLUSH_RESPONSE = 12, + MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST = 13, + MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE = 14 +} Message_queue_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote message queue operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + Message_queue_MP_Remote_operations operation; + rtems_name name; + rtems_option option_set; + Objects_Id proxy_id; + uint32_t count; + size_t size; + uint32_t pad0; + CORE_message_queue_Buffer Buffer; +} Message_queue_MP_Packet; + +/** + * @brief _Message_queue_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ +void _Message_queue_MP_Send_process_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + rtems_name name, + Objects_Id proxy_id +); + +/** + * @brief _Message_queue_MP_Send_request_packet + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ +rtems_status_code _Message_queue_MP_Send_request_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + const void *buffer, + size_t *size_p, + rtems_option option_set, + rtems_interval timeout +); + +/** + * @brief _Message_queue_MP_Send_response_packet + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ +void _Message_queue_MP_Send_response_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + Thread_Control *the_thread +); + +/** + * + @brief * _Message_queue_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Message_queue_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/** + * @brief _Message_queue_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + */ +void _Message_queue_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +); + +/** + * @brief _Message_queue_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ +void _Message_queue_MP_Send_extract_proxy ( + void *argument +); + +/** + * @brief _Message_queue_MP_Get_packet + * + * This function is used to obtain a message queue mp packet. + */ +Message_queue_MP_Packet *_Message_queue_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/object.h b/cpukit/rtems/include/rtems/rtems/object.h new file mode 100644 index 0000000000..72d65c6562 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/object.h @@ -0,0 +1,356 @@ +/** + * @file rtems/rtems/object.h + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_OBJECT_H +#define _RTEMS_RTEMS_OBJECT_H + +#include <stdint.h> +#include <rtems/score/object.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicClassInfo Object Class Information + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * This structure is used to return information to the application + * about the objects configured for a specific API/Class combination. + */ +typedef struct { + /** This field is the minimum valid object Id for this class. */ + rtems_id minimum_id; + /** This field is the maximum valid object Id for this class. */ + rtems_id maximum_id; + /** This field is the number of object instances configured for this class. */ + uint32_t maximum; + /** This field indicates if the class is configured for auto-extend. */ + bool auto_extend; + /** This field is the number of currently unallocated objects. */ + uint32_t unallocated; +} rtems_object_api_class_information; + +/** + * @brief Build Object Id + * + * This function returns an object id composed of the + * specified @a api, @a class, @a node, + * and @a index. + * + * @param[in] _api indicates the api to use for the Id + * @param[in] _class indicates the class to use for the Id + * @param[in] _node indicates the node to use for the Id + * @param[in] _index indicates the index to use for the Id + * + * @return This method returns an object Id built from the + * specified values. + * + * @note A body is also provided. + */ +#define rtems_build_id( _api, _class, _node, _index ) \ + _Objects_Build_id( _api, _class, _node, _index ) + +/** + * @brief Build Thirty-Two Bit Object Name + * + * This function returns an object name composed of the four characters + * C1, C2, C3, and C4. + * + * @param[in] _C1 is the first character of the name + * @param[in] _C2 is the second character of the name + * @param[in] _C3 is the third character of the name + * @param[in] _C4 is the fourth character of the name + * + * @note This must be implemented as a macro for use in + * Configuration Tables. A body is also provided. + * + */ +#define rtems_build_name( _C1, _C2, _C3, _C4 ) \ + _Objects_Build_name( _C1, _C2, _C3, _C4 ) + +/** @brief Obtain name of object + * + * This directive returns the name associated with the specified + * object ID. + * + * @param[in] id is the Id of the object to obtain the name of. + * @param[out] name will be set to the name of the object + * + * @note The object must be have a name of the 32-bit form. + * + * @return @a *name will contain user defined object name + * @return @a RTEMS_SUCCESSFUL - if successful + * @return error code - if unsuccessful + */ +rtems_status_code rtems_object_get_classic_name( + rtems_id id, + rtems_name *name +); + +/** + * @brief Obtain Object Name as String + * + * This directive returns the name associated with the specified + * object ID. + * + * @param[in] id is the Id of the object to obtain the name of + * @param[in] length is the length of the output name buffer + * @param[out] name will be set to the name of the object + * + * @return @a *name will contain user defined object name + * @return @a name - if successful + * @return @a NULL - if unsuccessful + */ +char *rtems_object_get_name( + rtems_id id, + size_t length, + char *name +); + +/** + * @brief Set Name of Object + * + * This method allows the caller to set the name of an + * object. This can be used to set the name of objects + * which do not have a naming scheme per their API. + * + * @param[in] id is the Id of the object to obtain the name of + * @param[out] name will be set to the name of the object + * + * @return @a *name will contain user defined object name + * @return @a RTEMS_SUCCESSFUL - if successful + * @return error code - if unsuccessful + */ +rtems_status_code rtems_object_set_name( + rtems_id id, + const char *name +); + +/** + * @brief Get API Portion of Object Id + * + * This function returns the API portion of the Id. + * + * @param[in] _id is the Id of the object to obtain the API from + * + * @return This method returns the API portion of the provided + * @a _id. + * + * @note This method does NOT validate the @a _id provided. + * + * @note A body is also provided. + */ +#define rtems_object_id_get_api( _id ) \ + _Objects_Get_API( _id ) + +/** + * @brief Get Class Portion of Object Id + * + * This function returns the class portion of the ID. + * + * @param[in] _id is the Id of the object to obtain the class from + * + * @return This method returns the class portion of the provided + * @a _id. + * + * @note This method does NOT validate the @a _id provided. + * + * @note A body is also provided. + */ +#define rtems_object_id_get_class( _id ) \ + _Objects_Get_class( _id ) + +/** + * @brief Get Node Portion of Object Id + * + * This function returns the node portion of the ID. + * + * @param[in] _id is the Id of the object to obtain the node from + * + * @return This method returns the node portion of the provided + * @a _id. + * + * @note This method does NOT validate the @a _id provided. + * + * @note A body is also provided. + */ +#define rtems_object_id_get_node( _id ) \ + _Objects_Get_node( _id ) + +/** + * @brief Get Index Portion of Object Id + * + * This function returns the index portion of the ID. + * + * @param[in] _id is the Id of the object to obtain the index from + * + * @return This method returns the index portion of the provided + * @a _id. + * + * @note This method does NOT validate the @a _id provided. + * + * @note A body is also provided. + */ +#define rtems_object_id_get_index( _id ) \ + _Objects_Get_index( _id ) + +/** + * @brief Get Lowest Valid API Index + * + * This method returns the lowest valid value for the API + * portion of an RTEMS object Id. + * + * @return This method returns the least valid value for + * the API portion of an RTEMS object Id. + * + * @note A body is also provided. + */ +#define rtems_object_id_api_minimum() \ + OBJECTS_INTERNAL_API + +/** + * @brief Get Highest Valid API Index + * + * This method returns the highest valid value for the API + * portion of an RTEMS object Id. + * + * @return This method returns the greatest valid value for + * the API portion of an RTEMS object Id. + * + * @note A body is also provided. + */ +#define rtems_object_id_api_maximum() \ + OBJECTS_APIS_LAST + +/** + * @brief Get Lowest Valid Class Value + * + * This method returns the lowest valid value Class for the + * specified @a api. Each API supports a different number + * of object classes. + * + * @param[in] api is the API to obtain the minimum class of + * + * @return This method returns the least valid value for + * class number for the specified @a api. + */ +int rtems_object_api_minimum_class( + int api +); + +/** + * @brief Get Highest Valid Class Value + * + * This method returns the highest valid value Class for the + * specified @a api. Each API supports a different number + * of object classes. + * + * @param[in] api is the API to obtain the maximum class of + * + * @return This method returns the greatet valid value for + * class number for the specified @a api. + */ +int rtems_object_api_maximum_class( + int api +); + + +/** + * @brief Get Highest Valid Class Value + * + * This method returns the lowest valid value Class for the + * specified @a api. Each API supports a different number + * of object classes. + * + * @param[in] api is the API to obtain the maximum class of + * + * @return This method returns the least valid value for + * class number for the specified @a api. + */ +int rtems_object_id_api_maximum_class( + int api +); + +/** + * @brief Get API Name + * + * This method returns a string containing the name of the + * specified @a api. + * + * @param[in] api is the API to obtain the name of + * + * @return If successful, this method returns the name of + * the specified @a api. Otherwise, it returns + * the string "BAD API" + */ +const char *rtems_object_get_api_name( + int api +); + +/** + * @brief Get Class Name + * + * This method returns a string containing the name of the + * @a class from the specified @a api. + * + * @param[in] the_api is the API for the class + * @param[in] the_class is the class to obtain the name of + * + * @return If successful, this method returns the name of + * the specified @a class. Otherwise, it returns + * the string "BAD CLASS" + */ +const char *rtems_object_get_api_class_name( + int the_api, + int the_class +); + +/** + * @brief Get Class Name + * + * This method returns a string containing the name of the + * @a the_class from the specified @a api. + * + * @param[in] the_api is the API for the class + * @param[in] the_class is the class to obtain information about + * @param[in] info points to the information structure to fill in + * + * @return If successful, this method returns the name of + * RTEMS_SUCCESSFUL with @a *info filled in. Otherwise, + * a status is returned to indicate the error. + * + */ +rtems_status_code rtems_object_get_class_information( + int the_api, + int the_class, + rtems_object_api_class_information *info +); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/options.h b/cpukit/rtems/include/rtems/rtems/options.h new file mode 100644 index 0000000000..240854519c --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/options.h @@ -0,0 +1,78 @@ +/** + * @file rtems/rtems/options.h + * + * This include file contains information which defines the + * options available on many directives. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_OPTIONS_H +#define _RTEMS_RTEMS_OPTIONS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicOptions Classic API Options + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * The following type defines the control block used to manage + * option sets. + */ +typedef uint32_t rtems_option; + +/** + * The following constants define the individual options which may + * be used to compose an option set. + */ +#define RTEMS_DEFAULT_OPTIONS 0x00000000 + +/** + * This option constants indicates that the task is to wait on resource. + */ +#define RTEMS_WAIT 0x00000000 +/** + * This option constants indicates that the task is to not wait on + * the resource. If it is not available, return immediately with + * a status to indicate unsatisfied. + */ +#define RTEMS_NO_WAIT 0x00000001 + +/** + * This option constants indicates that the task wishes to wait until + * all events of interest are available. + */ +#define RTEMS_EVENT_ALL 0x00000000 + +/** + * This option constants indicates that the task wishes to wait until + * ANY events of interest are available. + */ +#define RTEMS_EVENT_ANY 0x00000002 + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/options.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/part.h b/cpukit/rtems/include/rtems/rtems/part.h new file mode 100644 index 0000000000..3d3d2938ab --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/part.h @@ -0,0 +1,180 @@ +/** + * @file rtems/rtems/part.h + * + * This include file contains all the constants and structures associated + * with the Partition Manager. This manager provides facilities to + * dynamically allocate memory in fixed-sized units which are returned + * as buffers. + * + * Directives provided are: + * + * - create a partition + * - get an ID of a partition + * - delete a partition + * - get a buffer from a partition + * - return a buffer to a partition + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_PART_H +#define _RTEMS_RTEMS_PART_H + +/** + * This constant is defined to extern most of the time when using + * this header file. However by defining it to nothing, the data + * declared in this header file can be instantiated. This is done + * in a single per manager file. + */ +#ifndef RTEMS_PART_EXTERN +#define RTEMS_PART_EXTERN extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/address.h> +#include <rtems/score/object.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/types.h> + +/** + * @defgroup ClassicPart Partitions + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the + * Classic API Partition Manager. + */ +/**@{*/ + +/** + * The following defines the control block used to manage each partition. + */ +typedef struct { + /** This field is the object management portion of a Partition instance. */ + Objects_Control Object; + /** This field is the physical starting address of the Partition. */ + void *starting_address; + /** This field is the size of the Partition in bytes. */ + intptr_t length; + /** This field is the size of each buffer in bytes */ + uint32_t buffer_size; + /** This field is the attribute set provided at create time. */ + rtems_attribute attribute_set; + /** This field is the of allocated buffers. */ + uint32_t number_of_used_blocks; + /** This field is the chain used to manage unallocated buffers. */ + Chain_Control Memory; +} Partition_Control; + +/** + * The following defines the information control block used to + * manage this class of objects. + */ +RTEMS_PART_EXTERN Objects_Information _Partition_Information; + +/** + * @brief Partition_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Partition_Manager_initialization(void); + +/** + * @brief rtems_partition_create + * + * This routine implements the rtems_partition_create directive. The + * partition will have the name name. The memory area managed by + * the partition is of length bytes and starts at starting_address. + * The memory area will be divided into as many buffers of + * buffer_size bytes as possible. The attribute_set determines if + * the partition is global or local. It returns the id of the + * created partition in ID. + */ +rtems_status_code rtems_partition_create( + rtems_name name, + void *starting_address, + uint32_t length, + uint32_t buffer_size, + rtems_attribute attribute_set, + rtems_id *id +); + +/** + * @brief rtems_partition_ident + * + * This routine implements the rtems_partition_ident directive. + * This directive returns the partition ID associated with name. + * If more than one partition is named name, then the partition + * to which the ID belongs is arbitrary. node indicates the + * extent of the search for the ID of the partition named name. + * The search can be limited to a particular node or allowed to + * encompass all nodes. + */ +rtems_status_code rtems_partition_ident( + rtems_name name, + uint32_t node, + rtems_id *id +); + +/** + * @brief rtems_partition_delete + * + * This routine implements the rtems_partition_delete directive. The + * partition indicated by ID is deleted. + */ +rtems_status_code rtems_partition_delete( + rtems_id id +); + +/** + * @brief rtems_partition_get_buffer + * + * This routine implements the rtems_partition_get_buffer directive. It + * attempts to allocate a buffer from the partition associated with ID. + * If a buffer is allocated, its address is returned in buffer. + */ +rtems_status_code rtems_partition_get_buffer( + rtems_id id, + void **buffer +); + +/** + * @brief rtems_partition_return_buffer + * + * This routine implements the rtems_partition_return_buffer directive. It + * frees the buffer to the partition associated with ID. The buffer must + * have been previously allocated from the same partition. + */ +rtems_status_code rtems_partition_return_buffer( + rtems_id id, + void *buffer +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/part.inl> +#endif +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/partmp.h> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/partmp.h b/cpukit/rtems/include/rtems/rtems/partmp.h new file mode 100644 index 0000000000..f36f0e259c --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/partmp.h @@ -0,0 +1,151 @@ +/** + * @file rtems/rtems/partmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Partition Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_PARTMP_H +#define _RTEMS_RTEMS_PARTMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/thread.h> + +#include <rtems/rtems/part.h> + +/** + * @defgroup ClassicPartMP Partition MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality which XXX + */ +/**{*/ + +/** + * The following enumerated type defines the list of + * remote partition operations. + */ +typedef enum { + PARTITION_MP_ANNOUNCE_CREATE = 0, + PARTITION_MP_ANNOUNCE_DELETE = 1, + PARTITION_MP_EXTRACT_PROXY = 2, + PARTITION_MP_GET_BUFFER_REQUEST = 3, + PARTITION_MP_GET_BUFFER_RESPONSE = 4, + PARTITION_MP_RETURN_BUFFER_REQUEST = 5, + PARTITION_MP_RETURN_BUFFER_RESPONSE = 6 +} Partition_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote partition operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + Partition_MP_Remote_operations operation; + rtems_name name; + void *buffer; + Objects_Id proxy_id; +} Partition_MP_Packet; + +/** + * @brief Partition_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ +void _Partition_MP_Send_process_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + rtems_name name, + Objects_Id proxy_id +); + +/** + * @brief Partition_MP_Send_request_packet + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ +rtems_status_code _Partition_MP_Send_request_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + void *buffer +); + +/** + * @brief Partition_MP_Send_response_packet + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ +void _Partition_MP_Send_response_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + Thread_Control *the_thread +); + +/** + * + * @brief Partition_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Partition_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/* + * @brief Partition_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + * + * This routine is not needed by the Partition since a partition + * cannot be deleted when buffers are in use. + */ + +/** + * @brief Partition_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ +void _Partition_MP_Send_extract_proxy ( + void *argument +); + +/** + * @brief Partition_MP_Get_packet + * + * This function is used to obtain a partition mp packet. + */ +Partition_MP_Packet *_Partition_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/ratemon.h b/cpukit/rtems/include/rtems/rtems/ratemon.h new file mode 100644 index 0000000000..9e0f1fda09 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/ratemon.h @@ -0,0 +1,517 @@ +/** + * @file rtems/rtems/ratemon.h + * + * This include file contains all the constants, structures, and + * prototypes associated with the Rate Monotonic Manager. This manager + * provides facilities to implement threads which execute in a periodic + * fashion. + * + * Directives provided are: + * + * - create a rate monotonic timer + * - cancel a period + * - delete a rate monotonic timer + * - conclude current and start the next period + * - obtain status information on a period + */ + +/* COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_RATEMON_H +#define _RTEMS_RTEMS_RATEMON_H + +/** + * This constant is defined to extern most of the time when using + * this header file. However by defining it to nothing, the data + * declared in this header file can be instantiated. This is done + * in a single per manager file. + */ +#ifndef RTEMS_RATEMON_EXTERN +#define RTEMS_RATEMON_EXTERN extern +#endif + +#include <rtems/bspIo.h> + +/** + * @defgroup ClassicRateMon Rate Monotonic Scheduler + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the + * Classic API Rate Monotonic Manager. + * + * Statistics are kept for each period and can be obtained or printed via + * API calls. The statistics kept include minimum, maximum and average times + * for both cpu usage and wall time. The statistics indicate the execution time + * used by the owning thread between successive calls to rtems_rate_monotonic_period. + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This is the public type used for the rate monotonic timing + * statistics. + */ +#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + #include <rtems/score/timespec.h> + + typedef struct timespec rtems_rate_monotonic_period_time_t; +#else + typedef uint32_t rtems_rate_monotonic_period_time_t; +#endif + +/** + * This is the internal type used for the rate monotonic timing + * statistics. + */ +#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + #include <rtems/score/timestamp.h> + + typedef Timestamp_Control Rate_monotonic_Period_time_t; +#else + typedef uint32_t Rate_monotonic_Period_time_t; +#endif + +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> + +#include <string.h> + + +/** + * The following enumerated type defines the states in which a + * period may be. + */ +typedef enum { + /** + * This value indicates the period is off the watchdog chain, + * and has never been initialized. + */ + RATE_MONOTONIC_INACTIVE, + + /** + * This value indicates the period is on the watchdog chain, and + * the owner is blocked waiting on it. + */ + RATE_MONOTONIC_OWNER_IS_BLOCKING, + + /** + * This value indicates the period is on the watchdog chain, and + * running. The owner should be executed or blocked waiting on + * another object. + */ + RATE_MONOTONIC_ACTIVE, + + /** + * This value indicates the period is on the watchdog chain, and + * has expired. The owner should be blocked waiting for the next period. + */ + RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING, + + /** + * This value indicates the period is off the watchdog chain, and + * has expired. The owner is still executing and has taken too much + * all time to complete this iteration of the period. + */ + RATE_MONOTONIC_EXPIRED +} rtems_rate_monotonic_period_states; + +/** + * The following constant is the interval passed to the rate_monontonic_period + * directive to obtain status information. + */ +#define RTEMS_PERIOD_STATUS WATCHDOG_NO_TIMEOUT + +/** + * The following defines the PUBLIC data structure that has the + * statistics kept on each period instance. + * + * @note The public structure uses struct timespec while the + * internal one uses Timestamp_Control. + */ +typedef struct { + /** This field contains the number of periods executed. */ + uint32_t count; + /** This field contains the number of periods missed. */ + uint32_t missed_count; + + /** This field contains the least amount of CPU time used in a period. */ + rtems_thread_cpu_usage_t min_cpu_time; + /** This field contains the highest amount of CPU time used in a period. */ + rtems_thread_cpu_usage_t max_cpu_time; + /** This field contains the total amount of wall time used in a period. */ + rtems_thread_cpu_usage_t total_cpu_time; + + /** This field contains the least amount of wall time used in a period. */ + rtems_rate_monotonic_period_time_t min_wall_time; + /** This field contains the highest amount of wall time used in a period. */ + rtems_rate_monotonic_period_time_t max_wall_time; + /** This field contains the total amount of CPU time used in a period. */ + rtems_rate_monotonic_period_time_t total_wall_time; +} rtems_rate_monotonic_period_statistics; + +/** + * The following defines the INTERNAL data structure that has the + * statistics kept on each period instance. + */ +typedef struct { + /** This field contains the number of periods executed. */ + uint32_t count; + /** This field contains the number of periods missed. */ + uint32_t missed_count; + + /** This field contains the least amount of CPU time used in a period. */ + Thread_CPU_usage_t min_cpu_time; + /** This field contains the highest amount of CPU time used in a period. */ + Thread_CPU_usage_t max_cpu_time; + /** This field contains the total amount of wall time used in a period. */ + Thread_CPU_usage_t total_cpu_time; + + /** This field contains the least amount of wall time used in a period. */ + Rate_monotonic_Period_time_t min_wall_time; + /** This field contains the highest amount of wall time used in a period. */ + Rate_monotonic_Period_time_t max_wall_time; + /** This field contains the total amount of CPU time used in a period. */ + Rate_monotonic_Period_time_t total_wall_time; +} Rate_monotonic_Statistics; + +/** + * The following defines the period status structure. + */ +typedef struct { + /** This is the Id of the thread using this period. */ + rtems_id owner; + + /** This is the current state of this period. */ + rtems_rate_monotonic_period_states state; + + /** + * This is the length of wall time that has passed since this period + * was last initiated. If the period is expired or has not been initiated, + * then this field has no meaning. + */ + rtems_rate_monotonic_period_time_t since_last_period; + + /** + * This is the amount of CPU time that has been used since this period + * was last initiated. If the period is expired or has not been initiated, + * then this field has no meaning. + */ + rtems_thread_cpu_usage_t executed_since_last_period; +} rtems_rate_monotonic_period_status; + +/** + * The following structure defines the control block used to manage + * each period. + */ +typedef struct { + /** This field is the object management portion of a Period instance. */ + Objects_Control Object; + + /** This is the timer used to provide the unblocking mechanism. */ + Watchdog_Control Timer; + + /** This field indicates the current state of the period. */ + rtems_rate_monotonic_period_states state; + + /** + * This field contains the length of the next period to be + * executed. + */ + uint32_t next_length; + + /** + * This field contains a pointer to the TCB for the thread + * which owns and uses this period instance. + */ + Thread_Control *owner; + + /** + * This field contains the cpu usage value of the owning thread when + * the period was initiated. It is used to compute the period's + * statistics. + */ + Thread_CPU_usage_t cpu_usage_period_initiated; + + /** + * This field contains the wall time value when the period + * was initiated. It is used to compute the period's statistics. + */ + Rate_monotonic_Period_time_t time_period_initiated; + + /** + * This field contains the statistics maintained for the period. + */ + Rate_monotonic_Statistics Statistics; +} Rate_monotonic_Control; + +/** + * @brief Rate Monotonic Period Class Management Structure + * + * This instance of Objects_Information is used to manage the + * set of rate monotonic period instances. + */ +RTEMS_RATEMON_EXTERN Objects_Information _Rate_monotonic_Information; + +/** + * @brief Rate Monotonic Manager Initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Rate_monotonic_Manager_initialization(void); + +/** + * @brief rtems_rate_monotonic_create + * + * This routine implements the rate_monotonic_create directive. The + * period will have the name name. It returns the id of the + * created period in ID. + */ +rtems_status_code rtems_rate_monotonic_create( + rtems_name name, + rtems_id *id +); + +/** + * @brief rtems_rate_monotonic_ident + * + * This routine implements the rtems_rate_monotonic_ident directive. + * It returns the period ID associated with name. If more than one period + * is named name, then the period to which the ID belongs is arbitrary. + */ +rtems_status_code rtems_rate_monotonic_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief rtems_rate_monotonic_cancel + * + * This routine implements the rtems_rate_monotonic_cancel directive. This + * directive stops the period associated with ID from continuing to + * run. + */ +rtems_status_code rtems_rate_monotonic_cancel( + rtems_id id +); + +/** + * @brief rtems_rate_monotonic_delete + * + * This routine implements the rtems_rate_monotonic_delete directive. The + * period indicated by ID is deleted. + */ +rtems_status_code rtems_rate_monotonic_delete( + rtems_id id +); + +/** + * @brief rtems_rate_monotonic_get_status + * + * This routine implements the rtems_rate_monotonic_get_status directive. + * Information about the period indicated by ID is returned. + * + */ +rtems_status_code rtems_rate_monotonic_get_status( + rtems_id id, + rtems_rate_monotonic_period_status *status +); + +/** + * @brief rtems_rate_monotonic_get_statistics + * + * This routine implements the rtems_rate_monotonic_get_statistics directive. + * Statistics gathered from the use of this period are returned. + */ +rtems_status_code rtems_rate_monotonic_get_statistics( + rtems_id id, + rtems_rate_monotonic_period_statistics *statistics +); + +/** + * @brief rtems_rate_monotonic_reset_statistics + * + * This routine allows a thread to reset the statistics information + * on a specific period instance. + */ +rtems_status_code rtems_rate_monotonic_reset_statistics( + rtems_id id +); + +/** + * @brief rtems_rate_monotonic_reset_all_statistics + * + * This routine allows a thread to reset the statistics information + * on ALL period instances. + */ +void rtems_rate_monotonic_reset_all_statistics( void ); + +/** + * @brief rtems_rate_monotonic_report_statistics + * + * This routine allows a thread to print the statistics information + * on ALL period instances which have non-zero counts using printk. + */ +void rtems_rate_monotonic_report_statistics_with_plugin( + void *context, + rtems_printk_plugin_t print +); + +/** + * @brief rtems_rate_monotonic_report_statistics + * + * This routine allows a thread to print the statistics information + * on ALL period instances which have non-zero counts using printk. + */ +void rtems_rate_monotonic_report_statistics( void ); + +/** + * @brief rtems_rate_monotonic_period + * + * This routine implements the rtems_rate_monotonic_period directive. When + * length is non-zero, this directive initiates the period associated with + * ID from continuing for a period of length. If length is zero, then + * result is set to indicate the current state of the period. + */ +rtems_status_code rtems_rate_monotonic_period( + rtems_id id, + rtems_interval length +); + +/** + * @brief _Rate_monotonic_Timeout + * + * This routine is invoked when the period represented + * by ID expires. If the thread which owns this period is blocked + * waiting for the period to expire, then it is readied and the + * period is restarted. If the owning thread is not waiting for the + * period to expire, then the period is placed in the EXPIRED + * state and not restarted. + */ +void _Rate_monotonic_Timeout( + rtems_id id, + void *ignored +); + +/** + * @brief _Rate_monotonic_Get_status( + * + * This routine is invoked to compute the elapsed wall time and cpu + * time for a period. + * + * @param[in] the_period points to the period being operated upon. + * @param[out] wall_since_last_period is set to the wall time elapsed + * since the period was initiated. + * @param[out] cpu_since_last_period is set to the cpu time used by the + * owning thread since the period was initiated. + * + * @return This routine returns true if the status can be determined + * and false otherwise. + */ +bool _Rate_monotonic_Get_status( + Rate_monotonic_Control *the_period, + Rate_monotonic_Period_time_t *wall_since_last_period, + Thread_CPU_usage_t *cpu_since_last_period +); + +/** + * @brief _Rate_monotonic_Initiate_statistics( + * + * This routine is invoked when a period is initiated via an explicit + * call to rtems_rate_monotonic_period for the period's first iteration + * or from _Rate_monotonic_Timeout for period iterations 2-n. + * + * @param[in] the_period points to the period being operated upon. + */ +void _Rate_monotonic_Initiate_statistics( + Rate_monotonic_Control *the_period +); + +/** + * @brief _Rate_monotonic_Reset_wall_time_statistics + * + * This method resets the statistics information for a period instance. + */ +#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + #define _Rate_monotonic_Reset_wall_time_statistics( _the_period ) \ + do { \ + /* set the minimums to a large value */ \ + _Timestamp_Set( \ + &(_the_period)->Statistics.min_wall_time, \ + 0x7fffffff, \ + 0x7fffffff \ + ); \ + } while (0) +#else + #define _Rate_monotonic_Reset_wall_time_statistics( _the_period ) \ + do { \ + /* set the minimum to a large value */ \ + (_the_period)->Statistics.min_wall_time = 0xffffffff; \ + } while (0) +#endif + +/** + * @brief Rate_monotonic_Reset_cpu_use_statistics + * + * This helper method resets the period CPU usage statistics structure. + */ +#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + #define _Rate_monotonic_Reset_cpu_use_statistics( _the_period ) \ + do { \ + /* set the minimums to a large value */ \ + _Timestamp_Set( \ + &(_the_period)->Statistics.min_cpu_time, \ + 0x7fffffff, \ + 0x7fffffff \ + ); \ + } while (0) +#else + #define _Rate_monotonic_Reset_cpu_use_statistics( _the_period ) \ + do { \ + /* set the minimum to a large value */ \ + (_the_period)->Statistics.min_cpu_time = 0xffffffff; \ + } while (0) +#endif + +/** + * @brief Rate_monotonic_Reset_statistics + * + * This helper method resets the period wall time statistics structure. + */ +#define _Rate_monotonic_Reset_statistics( _the_period ) \ + do { \ + memset( \ + &(_the_period)->Statistics, \ + 0, \ + sizeof( rtems_rate_monotonic_period_statistics ) \ + ); \ + _Rate_monotonic_Reset_cpu_use_statistics( _the_period ); \ + _Rate_monotonic_Reset_wall_time_statistics( _the_period ); \ + } while (0) + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/ratemon.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/region.h b/cpukit/rtems/include/rtems/rtems/region.h new file mode 100644 index 0000000000..adab79b999 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/region.h @@ -0,0 +1,292 @@ +/** + * @file rtems/rtems/region.h + * + * This include file contains all the constants and structures associated + * with the Region Manager. This manager provides facilities to dynamically + * allocate memory in variable sized units which are returned as segments. + * + * Directives provided are: + * + * - create a region + * - get an ID of a region + * - delete a region + * - get a segment from a region + * - return a segment to a region + */ + +/* COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_REGION_H +#define _RTEMS_RTEMS_REGION_H + +#include <rtems/score/object.h> +#include <rtems/score/threadq.h> +#include <rtems/score/heap.h> +#include <rtems/debug.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/types.h> + +/** + * @defgroup ClassicRegion Regions + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * This constant is defined to extern most of the time when using + * this header file. However by defining it to nothing, the data + * declared in this header file can be instantiated. This is done + * in a single per manager file. + */ +#ifndef RTEMS_REGION_EXTERN +#define RTEMS_REGION_EXTERN extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The following records define the control block used to manage + * each region. + */ + +typedef struct { + Objects_Control Object; + Thread_queue_Control Wait_queue; /* waiting threads */ + void *starting_address; /* physical start addr */ + uintptr_t length; /* physical length(bytes) */ + uintptr_t page_size; /* in bytes */ + uintptr_t maximum_segment_size; /* in bytes */ + rtems_attribute attribute_set; + uint32_t number_of_used_blocks; /* blocks allocated */ + Heap_Control Memory; +} Region_Control; + +/** + * The following defines the information control block used to + * manage this class of objects. + */ +RTEMS_REGION_EXTERN Objects_Information _Region_Information; + +/** + * @brief _Region_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Region_Manager_initialization(void); + +/** + * @brief rtems_region_create + * + * This routine implements the rtems_region_create directive. The + * region will have the name name. The memory area managed by + * the region is of length bytes and starts at starting_address. + * The memory area will be divided into as many allocatable units of + * page_size bytes as possible. The attribute_set determines which + * thread queue discipline is used by the region. It returns the + * id of the created region in ID. + */ +rtems_status_code rtems_region_create( + rtems_name name, + void *starting_address, + uintptr_t length, + uintptr_t page_size, + rtems_attribute attribute_set, + rtems_id *id +); + +/** + * @brief rtems_region_extend + * + * This routine implements the rtems_region_extend directive. The + * region will have the name name. The memory area managed by + * the region will be attempted to be grown by length bytes using + * the memory starting at starting_address. + */ +rtems_status_code rtems_region_extend( + rtems_id id, + void *starting_address, + uintptr_t length +); + +/** + * @brief rtems_region_ident + * + * This routine implements the rtems_region_ident directive. + * This directive returns the region ID associated with name. + * If more than one region is named name, then the region + * to which the ID belongs is arbitrary. + */ +rtems_status_code rtems_region_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief rtems_region_get_information + * + * This routine implements the rtems_region_get_information directive. + * This directive returns information about the heap associated with + * this region. + */ +rtems_status_code rtems_region_get_information( + rtems_id id, + Heap_Information_block *the_info +); + +/** + * @brief rtems_region_get_free_information + * + * This routine implements the rtems_region_get_free_information directive. + * This directive returns information about the free blocks in the + * heap associated with this region. + */ +rtems_status_code rtems_region_get_free_information( + rtems_id id, + Heap_Information_block *the_info +); + +/** + * @brief rtems_region_delete + * + * This routine implements the rtems_region_delete directive. The + * region indicated by ID is deleted. + */ +rtems_status_code rtems_region_delete( + rtems_id id +); + +/** + * @brief rtems_region_get_segment + * + * This routine implements the rtems_region_get_segment directive. It + * attempts to allocate a segment from the region associated with ID. + * If a segment of the requested size can be allocated, its address + * is returned in segment. If no segment is available, then the task + * may return immediately or block waiting for a segment with an optional + * timeout of timeout clock ticks. Whether the task blocks or returns + * immediately is based on the no_wait option in the option_set. + */ +rtems_status_code rtems_region_get_segment( + rtems_id id, + uintptr_t size, + rtems_option option_set, + rtems_interval timeout, + void **segment +); + +/** + * @brief rtems_region_get_segment_size + * + * This routine implements the rtems_region_get_segment_size directive. It + * returns the size in bytes of the specified user memory area. + */ +rtems_status_code rtems_region_get_segment_size( + rtems_id id, + void *segment, + uintptr_t *size +); + +/** + * @brief rtems_region_return_segment + * + * This routine implements the rtems_region_return_segment directive. It + * frees the segment to the region associated with ID. The segment must + * have been previously allocated from the same region. If freeing the + * segment results in enough memory being available to satisfy the + * rtems_region_get_segment of the first blocked task, then that task and as + * many subsequent tasks as possible will be unblocked with their requests + * satisfied. + */ +rtems_status_code rtems_region_return_segment( + rtems_id id, + void *segment +); + +/** + * @brief rtems_region_resize_segment + * + * This routine implements the rtems_region_resize_segment directive. It + * tries to resize segment in the region associated with 'id' to the new size + * 'size' in place. The first 'size' or old size bytes of the segment + * (whatever is less) are guaranteed to remain unmodified. The segment must + * have been previously allocated from the same region. If resizing the + * segment results in enough memory being available to satisfy the + * rtems_region_get_segment of the first blocked task, then that task and as + * many subsequent tasks as possible will be unblocked with their requests + * satisfied. + * Returns: + * RTEMS_SUCCESSFUL - operation successful + * RTEMS_UNSATISFIED - the segment can't be resized in place + * any other code - failure. + * On RTEMS_SUCCESSFUL or RTEMS_UNSATISFIED exit it returns into the + * 'old_size' the old size in bytes of the user memory area of the specified + * segment. + */ +rtems_status_code rtems_region_resize_segment( + rtems_id id, + void *segment, + uintptr_t size, + uintptr_t *old_size +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/region.inl> +/** + * @brief Region_Process_queue + * + * This is a helper routine which is invoked any time memory is + * freed. It looks at the set of waiting tasks and attempts to + * satisfy all outstanding requests. + */ +extern void _Region_Process_queue(Region_Control *the_region); + +#endif + +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/regionmp.h> +#endif + +/** + * @brief _Region_Debug_Walk + * + * This routine is invoked to verify the integrity of a heap associated + * with the_region. + */ +#ifdef RTEMS_DEBUG + +#define _Region_Debug_Walk( _the_region, _source ) \ + do { \ + if ( rtems_debug_is_enabled( RTEMS_DEBUG_REGION ) ) \ + _Heap_Walk( &(_the_region)->Memory, _source, false ); \ + } while ( 0 ) + +#else + +#define _Region_Debug_Walk( _the_region, _source ) + +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/regionmp.h b/cpukit/rtems/include/rtems/rtems/regionmp.h new file mode 100644 index 0000000000..b748aba8e8 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/regionmp.h @@ -0,0 +1,155 @@ +/** + * @file rtems/rtems/regionmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Region Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_REGIONMP_H +#define _RTEMS_RTEMS_REGIONMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> + +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> + +/** + * @defgroup ClassicRegionMP Region MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * The following enumerated type defines the list of + * remote region operations. + */ +typedef enum { + REGION_MP_ANNOUNCE_CREATE = 0, + REGION_MP_ANNOUNCE_DELETE = 1, + REGION_MP_EXTRACT_PROXY = 2, + REGION_MP_GET_SEGMENT_REQUEST = 3, + REGION_MP_GET_SEGMENT_RESPONSE = 4, + REGION_MP_RETURN_SEGMENT_REQUEST = 5, + REGION_MP_RETURN_SEGMENT_RESPONSE = 6 +} Region_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote region operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + Region_MP_Remote_operations operation; + rtems_name name; + rtems_option option_set; + uint32_t size; + Objects_Id proxy_id; + void *segment; +} Region_MP_Packet; + +/** + * @brief _Region_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ +void _Region_MP_Send_process_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + rtems_name name, + Objects_Id proxy_id +); + +/** + * @brief _Region_MP_Send_request_packet + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ +rtems_status_code _Region_MP_Send_request_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + void *segment, + intptr_t size, + rtems_option option_set, + rtems_interval timeout +); + +/** + * @brief _Region_MP_Send_response_packet + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ +void _Region_MP_Send_response_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + Thread_Control *the_thread +); + +/** + * @brief _Region_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Region_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/* + * @brief _Region_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + * + * This routine is not needed by the Region since a region + * cannot be deleted when segments are in use. + */ + +/** + * @brief _Region_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ +void _Region_MP_Send_extract_proxy ( + void *argument +); + +/** + * @brief _Region_MP_Get_packet + * + * This function is used to obtain a region mp packet. + */ +Region_MP_Packet *_Region_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/rtemsapi.h b/cpukit/rtems/include/rtems/rtems/rtemsapi.h new file mode 100644 index 0000000000..d75dbb0490 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/rtemsapi.h @@ -0,0 +1,32 @@ +/** + * @file rtems/rtems/rtemsapi.h + * + * RTEMS API Support + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_RTEMSAPI_H +#define _RTEMS_RTEMS_RTEMSAPI_H + +#include <rtems/config.h> + +/** + * _RTEMS_API_Initialize + * + * This routine initializes the RTEMS API by invoking the initialization + * routine for each RTEMS manager with the appropriate parameters + * from the configuration_table. + */ +void _RTEMS_API_Initialize(void); + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/sem.h b/cpukit/rtems/include/rtems/rtems/sem.h new file mode 100644 index 0000000000..b4443241c0 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/sem.h @@ -0,0 +1,244 @@ +/** + * @file rtems/rtems/sem.h + * + * This include file contains all the constants and structures associated + * with the Semaphore Manager. This manager utilizes standard Dijkstra + * counting semaphores to provide synchronization and mutual exclusion + * capabilities. + * + * Directives provided are: + * + * - create a semaphore + * - get an ID of a semaphore + * - delete a semaphore + * - acquire a semaphore + * - release a semaphore + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_SEM_H +#define _RTEMS_RTEMS_SEM_H + +/** + * This constant is defined to extern most of the time when using + * this header file. However by defining it to nothing, the data + * declared in this header file can be instantiated. This is done + * in a single per manager file. + */ +#ifndef RTEMS_SEM_EXTERN +#define RTEMS_SEM_EXTERN extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/rtems/types.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/tasks.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/object.h> +#include <rtems/score/coresem.h> + +/** + * @defgroup ClassicSem Semaphores + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API + * Semaphore Manager. + */ +/**@{*/ + +/** + * The following defines the control block used to manage each semaphore. + */ +typedef struct { + /** This field is the object management portion of a Semaphore instance. */ + Objects_Control Object; + + /** + * This is the Classic API attribute provided to the create directive. + * It is translated into behavioral attributes on the SuperCore Semaphore + * or Mutex instance. + */ + rtems_attribute attribute_set; + + /** + * This contains the memory associated with the SuperCore Semaphore or + * Mutex instance that provides the primary functionality of each + * Classic API Semaphore instance. The structure used is dependent + * on the attributes specified by the user on the create directive. + * + * @note Only one of these has meaning in a particular Classic API + * Semaphore instance. + */ + union { + /** + * This is the SuperCore Mutex instance associated with this Classic + * API Semaphore instance. + */ + CORE_mutex_Control mutex; + + /** + * This is the SuperCore Semaphore instance associated with this Classic + * API Semaphore instance. + */ + CORE_semaphore_Control semaphore; + } Core_control; +} Semaphore_Control; + +/** + * The following defines the information control block used to manage + * this class of objects. + */ +RTEMS_SEM_EXTERN Objects_Information _Semaphore_Information; + +/** + * @brief Semaphore_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Semaphore_Manager_initialization(void); + +/** + * @brief rtems_semaphore_create + * + * This routine implements the rtems_semaphore_create directive. The + * semaphore will have the name name. The starting count for + * the semaphore is count. The attribute_set determines if + * the semaphore is global or local and the thread queue + * discipline. It returns the id of the created semaphore in ID. + */ +rtems_status_code rtems_semaphore_create( + rtems_name name, + uint32_t count, + rtems_attribute attribute_set, + rtems_task_priority priority_ceiling, + rtems_id *id +); + +/** + * @brief rtems_semaphore_ident + * + * This routine implements the rtems_semaphore_ident directive. + * This directive returns the semaphore ID associated with name. + * If more than one semaphore is named name, then the semaphore + * to which the ID belongs is arbitrary. node indicates the + * extent of the search for the ID of the semaphore named name. + * The search can be limited to a particular node or allowed to + * encompass all nodes. + */ +rtems_status_code rtems_semaphore_ident( + rtems_name name, + uint32_t node, + rtems_id *id +); + +/** + * @brief rtems_semaphore_delete + * + * This routine implements the rtems_semaphore_delete directive. The + * semaphore indicated by ID is deleted. + */ +rtems_status_code rtems_semaphore_delete( + rtems_id id +); + +/** + * @brief rtems_semaphore_obtain + * + * This routine implements the rtems_semaphore_obtain directive. It + * attempts to obtain a unit from the semaphore associated with ID. + * If a unit can be allocated, the calling task will return immediately. + * If no unit is available, then the task may return immediately or + * block waiting for a unit with an optional timeout of timeout + * clock ticks. Whether the task blocks or returns immediately + * is based on the RTEMS_NO_WAIT option in the option_set. + */ +rtems_status_code rtems_semaphore_obtain( + rtems_id id, + rtems_option option_set, + rtems_interval timeout +); + +/** + * @brief rtems_semaphore_release + * + * This routine implements the rtems_semaphore_release directive. It + * frees a unit to the semaphore associated with ID. If a task was + * blocked waiting for a unit from this semaphore, then that task will + * be readied and the unit given to that task. Otherwise, the unit + * will be returned to the semaphore. + */ +rtems_status_code rtems_semaphore_release( + rtems_id id +); + +/** + * @brief rtems_semaphore_flush + * pending on the semaphore. + */ +rtems_status_code rtems_semaphore_flush( + rtems_id id +); + +/** + * @brief _Semaphore_Seize + * + * This routine attempts to receive a unit from the_semaphore. + * If a unit is available or if the RTEMS_NO_WAIT option is enabled in + * option_set, then the routine returns. Otherwise, the calling task + * is blocked until a unit becomes available. + */ +bool _Semaphore_Seize( + Semaphore_Control *the_semaphore, + uint32_t option_set +); + +/** + * @brief _Semaphore_Translate_core_mutex_return_code + * + * This function returns a RTEMS status code based on the mutex + * status code specified. + */ +rtems_status_code _Semaphore_Translate_core_mutex_return_code ( + uint32_t the_mutex_status +); + +/** + * @brief _Semaphore_Translate_core_semaphore_return_code + * + * This function returns a RTEMS status code based on the semaphore + * status code specified. + */ +rtems_status_code _Semaphore_Translate_core_semaphore_return_code ( + uint32_t the_mutex_status +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/sem.inl> +#endif +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/semmp.h> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/semmp.h b/cpukit/rtems/include/rtems/rtems/semmp.h new file mode 100644 index 0000000000..f3a06aeb2f --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/semmp.h @@ -0,0 +1,175 @@ +/** + * @file rtems/rtems/semmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Semaphore Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_SEMMP_H +#define _RTEMS_RTEMS_SEMMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/sem.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> + +/** + * @defgroup ClassicSEM Semaphore MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +/** + * The following enumerated type defines the list of + * remote semaphore operations. + */ +typedef enum { + SEMAPHORE_MP_ANNOUNCE_CREATE = 0, + SEMAPHORE_MP_ANNOUNCE_DELETE = 1, + SEMAPHORE_MP_EXTRACT_PROXY = 2, + SEMAPHORE_MP_OBTAIN_REQUEST = 3, + SEMAPHORE_MP_OBTAIN_RESPONSE = 4, + SEMAPHORE_MP_RELEASE_REQUEST = 5, + SEMAPHORE_MP_RELEASE_RESPONSE = 6 +} Semaphore_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote semaphore operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + Semaphore_MP_Remote_operations operation; + rtems_name name; + rtems_option option_set; + Objects_Id proxy_id; +} Semaphore_MP_Packet; + +/** + * @brief Semaphore_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ +void _Semaphore_MP_Send_process_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + rtems_name name, + Objects_Id proxy_id +); + +/** + * @brief Semaphore_MP_Send_request_packet + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ +rtems_status_code _Semaphore_MP_Send_request_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + rtems_option option_set, + rtems_interval timeout +); + +/** + * @brief Semaphore_MP_Send_response_packet + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ +void _Semaphore_MP_Send_response_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + Thread_Control *the_thread +); + +/** + * @brief Semaphore_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Semaphore_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/** + * @brief Semaphore_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + */ +void _Semaphore_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +); + +/** + * @brief Semaphore_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ +void _Semaphore_MP_Send_extract_proxy ( + void *argument +); + +/** + * @brief Semaphore_MP_Get_packet + * + * This function is used to obtain a semaphore mp packet. + */ +Semaphore_MP_Packet *_Semaphore_MP_Get_packet ( void ); + +/** + * @brief _Semaphore_Core_mutex_mp_support + * + * This function processes the global actions necessary for remote + * accesses to a global semaphore based on a core mutex. This function + * is called by the core. + */ +void _Semaphore_Core_mutex_mp_support ( + Thread_Control *the_thread, + Objects_Id id +); + +/** + * @brief Semaphore_Core_mp_support + * + * This function processes the global actions necessary for remote + * accesses to a global semaphore based on a core semaphore. This function + * is called by the core. + */ +void _Semaphore_Core_semaphore_mp_support ( + Thread_Control *the_thread, + Objects_Id id +); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/signal.h b/cpukit/rtems/include/rtems/rtems/signal.h new file mode 100644 index 0000000000..1517dce734 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/signal.h @@ -0,0 +1,87 @@ +/** + * @file rtems/rtems/signal.h + * + * This include file contains all the constants and structures associated + * with the Signal Manager. This manager provides capabilities required + * for asynchronous communication between tasks via signal sets. + * + * Directives provided are: + * + * + establish an asynchronous signal routine + * + send a signal set to a task + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_SIGNAL_H +#define _RTEMS_RTEMS_SIGNAL_H + +/** + * @defgroup ClassicSignal Signals + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +#include <rtems/rtems/asr.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @brief _Signal_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Signal_Manager_initialization( void ); + +/** + * @brief rtems_signal_catch + * + * This routine implements the rtems_signal_catch directive. This directive + * is used to establish asr_handler as the Asynchronous Signal Routine + * (RTEMS_ASR) for the calling task. The asr_handler will execute with a + * mode of mode_set. + */ +rtems_status_code rtems_signal_catch( + rtems_asr_entry asr_handler, + rtems_mode mode_set +); + +/** + * @brief rtems_signal_send + * + * This routine implements the rtems_signal_send directive. This directive + * sends the signal_set to the task specified by ID. + */ +rtems_status_code rtems_signal_send( + rtems_id id, + rtems_signal_set signal_set +); + +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/signalmp.h> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/signalmp.h b/cpukit/rtems/include/rtems/rtems/signalmp.h new file mode 100644 index 0000000000..46e6a60538 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/signalmp.h @@ -0,0 +1,138 @@ +/** + * @file rtems/rtems/signalmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Signal Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_SIGNALMP_H +#define _RTEMS_RTEMS_SIGNALMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/rtems/asr.h> +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> + +/** + * @defgroup ClassicSignalMP Signal MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality which XXX + */ +/**{*/ + +/** + * The following enumerated type defines the list of + * remote signal operations. + */ +typedef enum { + SIGNAL_MP_SEND_REQUEST = 0, + SIGNAL_MP_SEND_RESPONSE = 1 +} Signal_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote signal operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + Signal_MP_Remote_operations operation; + rtems_signal_set signal_in; +} Signal_MP_Packet; + +/* + * @brief Signal_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + * + * This routine is not needed since there are no process + * packets to be sent by this manager. + */ + +/** + * @brief Signal_MP_Send_request_packet + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ +rtems_status_code _Signal_MP_Send_request_packet ( + Signal_MP_Remote_operations operation, + Objects_Id task_id, + rtems_signal_set signal_in +); + +/** + * @brief Signal_MP_Send_response_packet + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ +void _Signal_MP_Send_response_packet ( + Signal_MP_Remote_operations operation, + Thread_Control *the_thread +); + +/** + * @brief Signal_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _Signal_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/* + * @brief Signal_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + * + * This routine is not needed since there are no objects + * deleted by this manager. + */ + +/* + * @brief Signal_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + * + * This routine is not needed since there are no objects + * deleted by this manager. + */ + +/** + * @brief Signal_MP_Get_packet + * + * This function is used to obtain a signal mp packet. + */ +Signal_MP_Packet *_Signal_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/status.h b/cpukit/rtems/include/rtems/rtems/status.h new file mode 100644 index 0000000000..0f42a8b54d --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/status.h @@ -0,0 +1,220 @@ +/** + * @file rtems/rtems/status.h + * + * This include file contains the status codes returned from the + * executive directives. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_STATUS_H +#define _RTEMS_RTEMS_STATUS_H + +/** + * @defgroup ClassicStatus Status Codes + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Classic API Status + * + * This enumerates the possible status values returned b + * Classic API directives. + */ +typedef enum { + /** + * This is the status to indicate successful completion. + */ + RTEMS_SUCCESSFUL = 0, + /** + * This is the status to indicate that a thread exited. + */ + RTEMS_TASK_EXITTED = 1, + /** + * This is the status to indicate multiprocessing is not configured. + */ + RTEMS_MP_NOT_CONFIGURED = 2, + /** + * This is the status to indicate that the object name was invalid. + */ + RTEMS_INVALID_NAME = 3, + /** + * This is the status to indicate that the object Id was invalid. + */ + RTEMS_INVALID_ID = 4, + /** + * This is the status to indicate you have attempted to create too many + * instances of a particular object class. + */ + RTEMS_TOO_MANY = 5, + /** + * This is the status to indicate that a blocking directive timed out. + */ + RTEMS_TIMEOUT = 6, + /** + * This is the status to indicate the the object was deleted + * while the task was blocked waiting. + */ + RTEMS_OBJECT_WAS_DELETED = 7, + /** + * This is the status to indicate that the specified size was invalid. + */ + RTEMS_INVALID_SIZE = 8, + /** + * This is the status to indicate that the specified address is invalid. + */ + RTEMS_INVALID_ADDRESS = 9, + /** + * This is the status to indicate that the specified number was invalid. + */ + RTEMS_INVALID_NUMBER = 10, + /** + * This is the status to indicate that the item has not been initialized. + */ + RTEMS_NOT_DEFINED = 11, + /** + * This is the status to indicate that the object still has + * resources in use. + */ + RTEMS_RESOURCE_IN_USE = 12, + /** + * This is the status to indicate that the request was not satisfied. + */ + RTEMS_UNSATISFIED = 13, + /** + * This is the status to indicate that a thread is in wrong state + * was in the wrong execution state for the requested operation. + */ + RTEMS_INCORRECT_STATE = 14, + /** + * This is the status to indicate thread was already suspended. + */ + RTEMS_ALREADY_SUSPENDED = 15, + /** + * This is the status to indicate that the operation is illegal + * on calling thread. + */ + RTEMS_ILLEGAL_ON_SELF = 16, + /** + * This is the status to indicate illegal for remote object. + */ + RTEMS_ILLEGAL_ON_REMOTE_OBJECT = 17, + /** + * This is the status to indicate that the operation should not be + * called from from this excecution environment. + */ + RTEMS_CALLED_FROM_ISR = 18, + /** + * This is the status to indicate that an invalid thread priority + * was provided. + */ + RTEMS_INVALID_PRIORITY = 19, + /** + * This is the status to indicate that the specified date/time was invalid. + */ + RTEMS_INVALID_CLOCK = 20, + /** + * This is the status to indicate that the specified node Id was invalid. + */ + RTEMS_INVALID_NODE = 21, + /** + * This is the status to indicate that the directive was not configured. + */ + RTEMS_NOT_CONFIGURED = 22, + /** + * This is the status to indicate that the caller is not the + * owner of the resource. + */ + RTEMS_NOT_OWNER_OF_RESOURCE = 23, + /** + * This is the status to indicate the the directive or requested + * portion of the directive is not implemented. This is a hint + * that you have stumbled across an opportunity to submit code + * to the RTEMS Project. + */ + RTEMS_NOT_IMPLEMENTED = 24, + /** + * This is the status to indicate that an internal RTEMS inconsistency + * was detected. + */ + RTEMS_INTERNAL_ERROR = 25, + /** + * This is the status to indicate that the directive attempted to allocate + * memory but was unable to do so. + */ + RTEMS_NO_MEMORY = 26, + /** + * This is the status to indicate an driver IO error. + */ + RTEMS_IO_ERROR = 27, + /** + * This is the status is used internally to RTEMS when performing + * operations on behalf of remote tasks. This is referred to as + * proxying operations and this status indicates that the operation + * could not be completed immediately and the "proxy is blocking." + * + * @note This status will @b NOT be returned to the user. + */ + RTEMS_PROXY_BLOCKING = 28 +} rtems_status_code; + +/** + * This is the lowest valid value for a Classic API status code. + */ +#define RTEMS_STATUS_CODES_FIRST RTEMS_SUCCESSFUL + +/** + * This is the highest valid value for a Classic API status code. + */ +#define RTEMS_STATUS_CODES_LAST RTEMS_PROXY_BLOCKING + +/** + * This array is used to map SuperCore Object Handler return + * codes to Classic API status codes. + */ +#ifdef RTEMS_API_INIT +const rtems_status_code _Status_Object_name_errors_to_status[] = { + /** This maps OBJECTS_SUCCESSFUL to RTEMS_SUCCESSFUL. */ + RTEMS_SUCCESSFUL, + /** This maps OBJECTS_INVALID_NAME to RTEMS_INVALID_NAME. */ + RTEMS_INVALID_NAME, + /** This maps OBJECTS_INVALID_ADDRESS to RTEMS_INVALID_NAME. */ + RTEMS_INVALID_ADDRESS, + /** This maps OBJECTS_INVALID_ID to RTEMS_INVALID_ADDRESS. */ + RTEMS_INVALID_ID, + /** This maps OBJECTS_INVALID_NODE to RTEMS_INVALID_NODE. */ + RTEMS_INVALID_NODE +}; +#else +extern rtems_status_code _Status_Object_name_errors_to_status[]; +#endif + +/* + * Applications are allowed to use the macros to compare status codes. + */ +#include <rtems/rtems/status.inl> + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/support.h b/cpukit/rtems/include/rtems/rtems/support.h new file mode 100644 index 0000000000..220411d984 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/support.h @@ -0,0 +1,117 @@ +/** + * @file + * + * @ingroup ClassicRTEMS + * + * @ingroup ClassicRTEMSWorkspace + * + * @brief Classic API support. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_SUPPORT_H +#define _RTEMS_RTEMS_SUPPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/rtems/types.h> + +/** + * @addtogroup ClassicRTEMS + * + * @{ + */ + +/** + * @brief Returns the number of micro seconds for the milli seconds value @a _ms. + */ +#define RTEMS_MILLISECONDS_TO_MICROSECONDS(_ms) \ + TOD_MILLISECONDS_TO_MICROSECONDS(_ms) + +/** + * @brief Returns the number of ticks for the milli seconds value @a _ms. + */ +#define RTEMS_MILLISECONDS_TO_TICKS(_ms) \ + (TOD_MILLISECONDS_TO_MICROSECONDS(_ms) / \ + rtems_configuration_get_microseconds_per_tick()) + +/** + * @brief Returns the number of ticks for the micro seconds value @a _us. + */ +#define RTEMS_MICROSECONDS_TO_TICKS(_us) \ + ((_us) / rtems_configuration_get_microseconds_per_tick()) + +/** @} */ + +/** + * @defgroup ClassicRTEMSWorkspace Workspace + * + * @ingroup ClassicRTEMS + * + * Workspace definitions. + * + * @{ + */ + +/** + * @brief Gets workspace information. + * + * Returns information about the heap that is used as the RTEMS Executive + * Workspace in @a the_info. + * + * Returns @c true if successful, and @a false otherwise. + */ +bool rtems_workspace_get_information( + Heap_Information_block *the_info +); + +/** + * @brief Allocates memory from the workspace. + * + * A number of @a bytes bytes will be allocated from the RTEMS Executive + * Workspace and returned in @a pointer. + * + * Returns @c true if successful, and @a false otherwise. + */ +bool rtems_workspace_allocate( + size_t bytes, + void **pointer +); + +/** + * @brief Frees memory allocated from the workspace. + * + * This frees the memory indicated by @a pointer that was allocated from the + * RTEMS Executive Workspace. + * + * Returns @c true if successful, and @a false otherwise. + */ +bool rtems_workspace_free( + void *pointer +); + +/** @} */ + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/support.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/taskmp.h b/cpukit/rtems/include/rtems/rtems/taskmp.h new file mode 100644 index 0000000000..16bf205d8d --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/taskmp.h @@ -0,0 +1,156 @@ +/** + * @file rtems/rtems/taskmp.h + * + * This include file contains all the constants and structures associated + * with the multiprocessing support in the task manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_TASKMP_H +#define _RTEMS_RTEMS_TASKMP_H + +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/priority.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> + +/** + * @defgroup ClassicTaskMP Task MP Support + * + * @ingroup ClassicMP + * + * This encapsulates functionality which XXX + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif +/** + * The following enumerated type defines the list of + * remote task operations. + */ +typedef enum { + RTEMS_TASKS_MP_ANNOUNCE_CREATE = 0, + RTEMS_TASKS_MP_ANNOUNCE_DELETE = 1, + RTEMS_TASKS_MP_SUSPEND_REQUEST = 2, + RTEMS_TASKS_MP_SUSPEND_RESPONSE = 3, + RTEMS_TASKS_MP_RESUME_REQUEST = 4, + RTEMS_TASKS_MP_RESUME_RESPONSE = 5, + RTEMS_TASKS_MP_SET_PRIORITY_REQUEST = 6, + RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE = 7, + RTEMS_TASKS_MP_GET_NOTE_REQUEST = 8, + RTEMS_TASKS_MP_GET_NOTE_RESPONSE = 9, + RTEMS_TASKS_MP_SET_NOTE_REQUEST = 10, + RTEMS_TASKS_MP_SET_NOTE_RESPONSE = 11 +} RTEMS_tasks_MP_Remote_operations; + +/** + * The following data structure defines the packet used to perform + * remote task operations. + */ +typedef struct { + rtems_packet_prefix Prefix; + RTEMS_tasks_MP_Remote_operations operation; + rtems_name name; + rtems_task_priority the_priority; + uint32_t notepad; + uint32_t note; +} RTEMS_tasks_MP_Packet; + +/** + * @brief _RTEMS_tasks_MP_Send_process_packet + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ +void _RTEMS_tasks_MP_Send_process_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Objects_Id task_id, + rtems_name name +); + +/** + * @brief _RTEMS_tasks_MP_Send_request_packet + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ +rtems_status_code _RTEMS_tasks_MP_Send_request_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Objects_Id task_id, + rtems_task_priority the_priority, + uint32_t notepad, + uint32_t note +); + +/** + * @brief _RTEMS_tasks_MP_Send_response_packet + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ +void _RTEMS_tasks_MP_Send_response_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Thread_Control *the_thread +); + +/** + * @brief _RTEMS_tasks_MP_Process_packet + * + * This routine performs the actions specific to this package for + * the request from another node. + */ +void _RTEMS_tasks_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/** + * @brief _RTEMS_tasks_MP_Send_object_was_deleted + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + * + * This routine is not needed by RTEMS_tasks since a task + * cannot be deleted when segments are in use. + */ + +/* + * _RTEMS_tasks_MP_Send_extract_proxy + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + * + * This routine is not needed since there are no objects + * deleted by this manager. + * + */ + +/** + * @brief _RTEMS_tasks_MP_Get_packet + * + * This function is used to obtain a task mp packet. + */ +RTEMS_tasks_MP_Packet *_RTEMS_tasks_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h new file mode 100644 index 0000000000..1e9a9c57e6 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/tasks.h @@ -0,0 +1,505 @@ +/** + * @file rtems/rtems/tasks.h + * + * This include file contains all constants and structures associated + * with RTEMS tasks. This manager provides a comprehensive set of directives + * to create, delete, and administer tasks. + * + * Directives provided are: + * + * - create a task + * - get an ID of a task + * - start a task + * - restart a task + * - delete a task + * - suspend a task + * - resume a task + * - set a task's priority + * - change the current task's mode + * - get a task notepad entry + * - set a task notepad entry + * - wake up after interval + * - wake up when specified + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_TASKS_H +#define _RTEMS_RTEMS_TASKS_H + +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/types.h> +#include <rtems/rtems/eventset.h> +#include <rtems/rtems/asr.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/status.h> + +/** + * This constant is defined to extern most of the time when using + * this header file. However by defining it to nothing, the data + * declared in this header file can be instantiated. This is done + * in a single per manager file. + */ +#ifndef RTEMS_TASKS_EXTERN +#define RTEMS_TASKS_EXTERN extern +#endif + +/** + * @defgroup ClassicTasks Tasks + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality which X XX + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Constant to be used as the ID of current task + */ +#define RTEMS_SELF OBJECTS_ID_OF_SELF + +/** + * This constant is passed to the rtems_task_wake_after directive as the + * interval when a task wishes to yield the CPU. + */ +#define RTEMS_YIELD_PROCESSOR WATCHDOG_NO_TIMEOUT + +/** + * Define the type for an RTEMS API task priority. + */ +typedef Priority_Control rtems_task_priority; + +/** + * This is the constant used with the rtems_task_set_priority + * directive to indicate that the caller wants to obtain its + * current priority rather than set it as the name of the + * directive indicates. + */ +#define RTEMS_NO_PRIORITY RTEMS_CURRENT_PRIORITY + +/** + * This constant is the least valid value for a Classic API + * task priority. + */ +#define RTEMS_MINIMUM_PRIORITY (PRIORITY_MINIMUM + 1) + +/** + * This constant is the maximum valid value for a Classic API + * task priority. + * + * @note This is actually the priority of the IDLE thread so + * using this priority will result in having a task + * which never executes. This could be useful if you + * want to ensure that a task does not executes during + * certain operations such as a system mode change. + */ +#define RTEMS_MAXIMUM_PRIORITY PRIORITY_MAXIMUM + +/** + * The following constant is passed to rtems_task_set_priority when the + * caller wants to obtain the current priority. + */ +#define RTEMS_CURRENT_PRIORITY PRIORITY_MINIMUM + +/** This is used to indicate the lowest numbered notepad */ +#define RTEMS_NOTEPAD_FIRST 0 +/** This is used to indicate the notepad location 0. */ +#define RTEMS_NOTEPAD_0 0 +/** This is used to indicate the notepad location 1. */ +#define RTEMS_NOTEPAD_1 1 +/** This is used to indicate the notepad location 2. */ +#define RTEMS_NOTEPAD_2 2 +/** This is used to indicate the notepad location 3. */ +#define RTEMS_NOTEPAD_3 3 +/** This is used to indicate the notepad location 4. */ +#define RTEMS_NOTEPAD_4 4 +/** This is used to indicate the notepad location 5. */ +#define RTEMS_NOTEPAD_5 5 +/** This is used to indicate the notepad location 6. */ +#define RTEMS_NOTEPAD_6 6 +/** This is used to indicate the notepad location 7. */ +#define RTEMS_NOTEPAD_7 7 +/** This is used to indicate the notepad location 8. */ +#define RTEMS_NOTEPAD_8 8 +/** This is used to indicate the notepad location 9. */ +#define RTEMS_NOTEPAD_9 9 +/** This is used to indicate the notepad location 10. */ +#define RTEMS_NOTEPAD_10 10 +/** This is used to indicate the notepad location 11. */ +#define RTEMS_NOTEPAD_11 11 +/** This is used to indicate the notepad location 12. */ +#define RTEMS_NOTEPAD_12 12 +/** This is used to indicate the notepad location 13. */ +#define RTEMS_NOTEPAD_13 13 +/** This is used to indicate the notepad location 14. */ +#define RTEMS_NOTEPAD_14 14 +/** This is used to indicate the notepad location 15. */ +#define RTEMS_NOTEPAD_15 15 +/** This is used to indicate the highest numbered notepad. */ +#define RTEMS_NOTEPAD_LAST RTEMS_NOTEPAD_15 + +/** This is used to indicate the number of notepads available. */ +#define RTEMS_NUMBER_NOTEPADS (RTEMS_NOTEPAD_LAST+1) + +/** + * External API name for Thread_Control + */ +typedef Thread_Control rtems_tcb; + +/** + * The following defines the "return type" of an RTEMS task. + */ +typedef void rtems_task; + +/** + * The following defines the argument to an RTEMS task. + */ +typedef Thread_Entry_numeric_type rtems_task_argument; + +/** + * The following defines the type for the entry point of an RTEMS task. + */ +typedef rtems_task ( *rtems_task_entry )( + rtems_task_argument + ); + +/** + * The following records define the Initialization Tasks Table. + * Each entry contains the information required by RTEMS to + * create and start a user task automatically at executive + * initialization time. + */ +typedef struct { + /** This is the Initialization Task's name. */ + rtems_name name; + /** This is the Initialization Task's stack size. */ + size_t stack_size; + /** This is the Initialization Task's priority. */ + rtems_task_priority initial_priority; + /** This is the Initialization Task's attributes. */ + rtems_attribute attribute_set; + /** This is the Initialization Task's entry point. */ + rtems_task_entry entry_point; + /** This is the Initialization Task's initial mode. */ + rtems_mode mode_set; + /** This is the Initialization Task's argument. */ + rtems_task_argument argument; +} rtems_initialization_tasks_table; + +/** + * This is the API specific information required by each thread for + * the RTEMS API to function correctly. + * + * @note Notepads must be the last entry in the structure and memory + * will be taken away from this structure when allocated if + * notespads are disabled by the application configuration. + */ +typedef struct { + /** This field contains the pending events for this task. */ + rtems_event_set pending_events; + /** This field contains the event wait condition for this task. */ + rtems_event_set event_condition; + /** This field contains the Classic API Signal information for this task. */ + ASR_Information Signal; + /** + * This field contains the notepads for this task. + * + * @note MUST BE LAST ENTRY. + */ + uint32_t Notepads[ RTEMS_NUMBER_NOTEPADS ]; +} RTEMS_API_Control; + +/** + * The following instantiates the information control block used to + * manage this class of objects. + */ +RTEMS_TASKS_EXTERN Objects_Information _RTEMS_tasks_Information; + +/** + * When the user configures a set of Classic API initialization tasks, + * This variable will point to the method used to initialize them. + * + * @note It is instantiated and initialized by confdefs.h based upon + * application requirements. + */ +extern void (*_RTEMS_tasks_Initialize_user_tasks_p)(void); + +/** + * @brief _RTEMS_tasks_Manager_initialization + * + * This routine initializes all Task Manager related data structures. + */ +void _RTEMS_tasks_Manager_initialization(void); + +/** + * @brief rtems_task_create + * + * This routine implements the rtems_task_create directive. The task + * will have the name name. The attribute_set can be used to indicate + * that the task will be globally accessible or utilize floating point. + * The task's stack will be stack_size bytes. The task will begin + * execution with initial_priority and initial_modes. It returns the + * id of the created task in ID. + */ +rtems_status_code rtems_task_create( + rtems_name name, + rtems_task_priority initial_priority, + size_t stack_size, + rtems_mode initial_modes, + rtems_attribute attribute_set, + rtems_id *id +); + +/** + * @brief rtems_task_ident + * + * This routine implements the rtems_task_ident directive. + * This directive returns the task ID associated with name. + * If more than one task is named name, then the task to + * which the ID belongs is arbitrary. node indicates the + * extent of the search for the ID of the task named name. + * The search can be limited to a particular node or allowed to + * encompass all nodes. + */ +rtems_status_code rtems_task_ident( + rtems_name name, + uint32_t node, + rtems_id *id +); + +/** + * @brief rtems_task_delete + * + * This routine implements the rtems_task_delete directive. The + * task indicated by ID is deleted. + */ +rtems_status_code rtems_task_delete( + rtems_id id +); + +/** + * @brief rtems_task_get_note + * + * This routine implements the rtems_task_get_note directive. The + * value of the indicated notepad for the task associated with ID + * is returned in note. + */ +rtems_status_code rtems_task_get_note( + rtems_id id, + uint32_t notepad, + uint32_t *note +); + +/** + * @brief rtems_task_set_note + * + * This routine implements the rtems_task_set_note directive. The + * value of the indicated notepad for the task associated with ID + * is returned in note. + */ +rtems_status_code rtems_task_set_note( + rtems_id id, + uint32_t notepad, + uint32_t note +); + +/** + * @brief rtems_task_mode + * + * This routine implements the rtems_task_mode directive. The current + * values of the modes indicated by mask of the calling task are changed + * to that indicated in mode_set. The former mode of the task is + * returned in mode_set. + */ +rtems_status_code rtems_task_mode( + rtems_mode mode_set, + rtems_mode mask, + rtems_mode *previous_mode_set +); + +/** + * @brief rtems_task_restart + * + * This routine implements the rtems_task_restart directive. The + * task associated with ID is restarted at its initial entry + * point with the new argument. + */ +rtems_status_code rtems_task_restart( + rtems_id id, + uint32_t arg +); + +/** + * @brief rtems_task_suspend + * + * This routine implements the rtems_task_suspend directive. The + * SUSPENDED state is set for task associated with ID. + */ +rtems_status_code rtems_task_suspend( + rtems_id id +); + +/** + * @brief rtems_task_resume + * + * This routine implements the rtems_task_resume Directive. The + * SUSPENDED state is cleared for task associated with ID. + */ +rtems_status_code rtems_task_resume( + rtems_id id +); + +/** + * @brief rtems_task_set_priority + * + * This routine implements the rtems_task_set_priority directive. The + * current priority of the task associated with ID is set to + * new_priority. The former priority of that task is returned + * in old_priority. + */ +rtems_status_code rtems_task_set_priority( + rtems_id id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority +); + +/** + * @brief rtems_task_start + * + * This routine implements the rtems_task_start directive. The + * starting execution point of the task associated with ID is + * set to entry_point with the initial argument. + */ +rtems_status_code rtems_task_start( + rtems_id id, + rtems_task_entry entry_point, + rtems_task_argument argument +); + +/** + * @brief rtems_task_wake_when + * + * This routine implements the rtems_task_wake_when directive. The + * calling task is blocked until the current time of day is + * equal to that indicated by time_buffer. + */ +rtems_status_code rtems_task_wake_when( + rtems_time_of_day *time_buffer +); + +/** + * @brief rtems_task_wake_after + * + * This routine implements the rtems_task_wake_after directive. The + * calling task is blocked until the indicated number of clock + * ticks have occurred. + */ +rtems_status_code rtems_task_wake_after( + rtems_interval ticks +); + +/** + * @brief rtems_task_is_suspended + + * This directive returns a status indicating whether or not + * the specified task is suspended. + */ +rtems_status_code rtems_task_is_suspended( + rtems_id id +); + +/** + * @brief rtems_task_variable_add + * + * This directive adds a per task variable. + */ +rtems_status_code rtems_task_variable_add( + rtems_id tid, + void **ptr, + void (*dtor)(void *) +); + +/** + * @brief rtems_task_variable_get + * + * This directive gets the value of a task variable. + */ +rtems_status_code rtems_task_variable_get( + rtems_id tid, + void **ptr, + void **result +); + +/** + * @brief rtems_task_variable_delete + * + * This directive removes a per task variable. + */ +rtems_status_code rtems_task_variable_delete( + rtems_id tid, + void **ptr +); + +/** + * @brief rtems_task_self + * + * This directive returns the ID of the currently executing task. + */ +rtems_id rtems_task_self(void); + +/** + * @brief _RTEMS_tasks_Initialize_user_tasks + * + * This routine creates and starts all configured user + * initialzation threads. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ +void _RTEMS_tasks_Initialize_user_tasks( void ); + +/** + * @brief _RTEMS_Tasks_Invoke_task_variable_dtor( + * + * This routine invokes the optional user provided destructor on the + * task variable and frees the memory for the task variable. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ +void _RTEMS_Tasks_Invoke_task_variable_dtor( + Thread_Control *the_thread, + rtems_task_variable_t *tvp +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/tasks.inl> +#endif +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/taskmp.h> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/timer.h b/cpukit/rtems/include/rtems/rtems/timer.h new file mode 100644 index 0000000000..a328e9a0d1 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/timer.h @@ -0,0 +1,408 @@ +/** + * @file rtems/rtems/timer.h + * + * This include file contains all the constants, structures, and + * prototypes associated with the Timer Manager. This manager provides + * facilities to configure, initiate, cancel, and delete timers which will + * fire at specified intervals of time. + * + * Directives provided are: + * + * - create a timer + * - get an ID of a timer + * - delete a timer + * - set timer to fire in context of clock tick + * - after a number of ticks have passed + * - when a specified date and time has been reached + * - initiate the timer server task + * - set timer to fire in context of the timer server task + * - after a number of ticks have passed + * - when a specified date and time has been reached + * - reset a timer + * - cancel a time + */ + +/* COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * Copyright (c) 2009 embedded brains GmbH. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_TIMER_H +#define _RTEMS_RTEMS_TIMER_H + +/** + * This constant is defined to extern most of the time when using + * this header file. However by defining it to nothing, the data + * declared in this header file can be instantiated. This is done + * in a single per manager file. + */ +#ifndef RTEMS_TIMER_EXTERN +#define RTEMS_TIMER_EXTERN extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/object.h> +#include <rtems/score/watchdog.h> +#include <rtems/score/thread.h> +#include <rtems/score/chain.h> +#include <rtems/rtems/clock.h> +#include <rtems/rtems/attr.h> + +/** + * @defgroup ClassicTimer Timers + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the Classic API Timer + * Manager. This manager provides functionality which allows the + * application to schedule the execution of methods at a specified + * time in the future. These methods may be scheduled based upon + * interval or wall time and may be executed in either the clock tick + * ISR or in a special dedicated timer server task. + */ +/**@{*/ + +/** + * The following enumerated type details the classes to which a timer + * may belong. + */ +typedef enum { + /** + * This value indicates the timer is currently in use as an interval + * timer which will fire in the clock tick ISR. + */ + TIMER_INTERVAL, + + /** + * This value indicates the timer is currently in use as an interval + * timer which will fire in the timer server task. + */ + TIMER_INTERVAL_ON_TASK, + + /** + * This value indicates the timer is currently in use as an time of day + * timer which will fire in the clock tick ISR. + */ + TIMER_TIME_OF_DAY, + + /** + * This value indicates the timer is currently in use as an time of day + * timer which will fire in the timer server task. + */ + TIMER_TIME_OF_DAY_ON_TASK, + + /** + * This value indicates the timer is currently not in use. + */ + TIMER_DORMANT +} Timer_Classes; + +/** + * The following types define a pointer to a timer service routine. + */ +typedef void rtems_timer_service_routine; + +/** + * This type defines the type used to manage and indirectly invoke + * Timer Service Routines (TSRs). This defines the prototype and interface + * for a function which is to be used as a TSR. + */ +typedef rtems_timer_service_routine ( *rtems_timer_service_routine_entry )( + rtems_id, + void * + ); + +/** + * The following records define the control block used to manage + * each timer. + */ +typedef struct { + /** This field is the object management portion of a Timer instance. */ + Objects_Control Object; + /** This field is the Watchdog instance which will be the scheduled. */ + Watchdog_Control Ticker; + /** This field indicates what type of timer this currently is. */ + Timer_Classes the_class; +} Timer_Control; + +typedef struct Timer_server_Control Timer_server_Control; + +/** + * @brief Method used to schedule the insertion of task based timers. + */ +typedef void (*Timer_server_Schedule_operation)( + Timer_server_Control *timer_server, + Timer_Control *timer +); + +typedef struct { + /** + * @brief This watchdog that will be registered in the system tick mechanic + * for timer server wake-up. + */ + Watchdog_Control System_watchdog; + + /** + * @brief Chain for watchdogs which will be triggered by the timer server. + */ + Chain_Control Chain; + + /** + * @brief Last known time snapshot of the timer server. + * + * The units may be ticks or seconds. + */ + Watchdog_Interval volatile last_snapshot; +} Timer_server_Watchdogs; + +struct Timer_server_Control { + /** + * @brief Timer server thread. + */ + Thread_Control *thread; + + /** + * @brief The schedule operation method of the timer server. + */ + Timer_server_Schedule_operation schedule_operation; + + /** + * @brief Interval watchdogs triggered by the timer server. + */ + Timer_server_Watchdogs Interval_watchdogs; + + /** + * @brief TOD watchdogs triggered by the timer server. + */ + Timer_server_Watchdogs TOD_watchdogs; + + /** + * @brief Chain of timers scheduled for insert. + * + * This pointer is not @c NULL whenever the interval and TOD chains are + * processed. After the processing this list will be checked and if + * necessary the processing will be restarted. Processing of these chains + * can be only interrupted through interrupts. + */ + Chain_Control *volatile insert_chain; + + /** + * @brief Indicates that the timer server is active or not. + * + * The server is active after the delay on a system watchdog. The activity + * period of the server ends when no more watchdogs managed by the server + * fire. The system watchdogs must not be manipulated when the server is + * active. + */ + bool volatile active; +}; + +/** + * @brief Pointer to default timer server control block. + * + * This value is @c NULL when the default timer server is not initialized. + */ +RTEMS_TIMER_EXTERN Timer_server_Control *volatile _Timer_server; + +/** + * The following defines the information control block used to manage + * this class of objects. + */ +RTEMS_TIMER_EXTERN Objects_Information _Timer_Information; + +/** + * @brief _Timer_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _Timer_Manager_initialization(void); + +/** + * @brief rtems_timer_create + * + * This routine implements the rtems_timer_create directive. The + * timer will have the name name. It returns the id of the + * created timer in ID. + */ +rtems_status_code rtems_timer_create( + rtems_name name, + rtems_id *id +); + +/** + * @brief rtems_timer_ident + * + * This routine implements the rtems_timer_ident directive. + * This directive returns the timer ID associated with name. + * If more than one timer is named name, then the timer + * to which the ID belongs is arbitrary. + */ +rtems_status_code rtems_timer_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief rtems_timer_cancel + * + * This routine implements the rtems_timer_cancel directive. It is used + * to stop the timer associated with ID from firing. + */ +rtems_status_code rtems_timer_cancel( + rtems_id id +); + +/** + * @brief rtems_timer_delete + * + * This routine implements the rtems_timer_delete directive. The + * timer indicated by ID is deleted. + */ +rtems_status_code rtems_timer_delete( + rtems_id id +); + +/** + * @brief rtems_timer_fire_after + * + * This routine implements the rtems_timer_fire_after directive. It + * initiates the timer associated with ID to fire in ticks clock ticks. + * When the timer fires, the routine will be invoked in the context + * of the rtems_clock_tick directive which is normally invoked as + * part of servicing a periodic interupt. + */ +rtems_status_code rtems_timer_fire_after( + rtems_id id, + rtems_interval ticks, + rtems_timer_service_routine_entry routine, + void *user_data +); + +/** + * @brief rtems_timer_server_fire_after + * + * This routine implements the rtems_timer_server_fire_after directive. It + * initiates the timer associated with ID to fire in ticks clock + * ticks. When the timer fires, the routine will be invoked by the + * Timer Server in the context of a task NOT IN THE CONTEXT of the + * clock tick interrupt. + */ +rtems_status_code rtems_timer_server_fire_after( + rtems_id id, + rtems_interval ticks, + rtems_timer_service_routine_entry routine, + void *user_data +); + +/** + * @brief rtems_timer_fire_when + * + * This routine implements the rtems_timer_fire_when directive. It + * initiates the timer associated with ID to fire at wall_time + * When the timer fires, the routine will be invoked in the context + * of the rtems_clock_tick directive which is normally invoked as + * part of servicing a periodic interupt. + */ +rtems_status_code rtems_timer_fire_when( + rtems_id id, + rtems_time_of_day *wall_time, + rtems_timer_service_routine_entry routine, + void *user_data +); + +/** + * @brief rtems_timer_server_fire_when + * + * This routine implements the rtems_timer_server_fire_when directive. It + * initiates the timer associated with ID to fire at wall_time + * When the timer fires, the routine will be invoked by the + * Timer Server in the context of a task NOT IN THE CONTEXT of the + * clock tick interrupt. + */ +rtems_status_code rtems_timer_server_fire_when( + rtems_id id, + rtems_time_of_day *wall_time, + rtems_timer_service_routine_entry routine, + void *user_data +); + +/** + * @brief rtems_timer_reset + * + * This routine implements the rtems_timer_reset directive. It is used + * to reinitialize the interval timer associated with ID just as if + * rtems_timer_fire_after were re-invoked with the same arguments that + * were used to initiate this timer. + */ +rtems_status_code rtems_timer_reset( + rtems_id id +); + +/** + * @brief rtems_timer_initiate_server + * + * This routine implements the rtems_timer_initiate_server directive. + * It creates and starts the server that executes task-based timers. + * It must be invoked before any task-based timers can be initiated. + */ +rtems_status_code rtems_timer_initiate_server( + uint32_t priority, + uint32_t stack_size, + rtems_attribute attribute_set +); + +/** + * This is the default value for the priority of the Timer Server. + * When given this priority, a special high priority not accessible + * via the Classic API is used. + */ +#define RTEMS_TIMER_SERVER_DEFAULT_PRIORITY (uint32_t) -1 + +/** + * This is the structure filled in by the timer get information + * service. + */ +typedef struct { + /** This indicates the current type of the timer. */ + Timer_Classes the_class; + /** This indicates the initial requested interval. */ + Watchdog_Interval initial; + /** This indicates the time the timer was initially scheduled. */ + Watchdog_Interval start_time; + /** This indicates the time the timer is scheduled to fire. */ + Watchdog_Interval stop_time; +} rtems_timer_information; + +/** + * @brief rtems_timer_get_information + * + * This routine implements the rtems_timer_get_information directive. + * This directive returns information about the timer. + */ +rtems_status_code rtems_timer_get_information( + rtems_id id, + rtems_timer_information *the_info +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/rtems/timer.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/types.h b/cpukit/rtems/include/rtems/rtems/types.h new file mode 100644 index 0000000000..2ceeeaa203 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/types.h @@ -0,0 +1,238 @@ +/** + * @file + * + * @ingroup ClassicRTEMS + * + * @brief Types used by the Classic API. + */ + +/* COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_TYPES_H +#define _RTEMS_RTEMS_TYPES_H + +/* + * RTEMS basic type definitions + */ + +#include <stdint.h> +#include <rtems/score/heap.h> +#include <rtems/score/object.h> +#include <rtems/score/priority.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> +#include <rtems/rtems/modes.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#include <rtems/score/mppkt.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ClassicRTEMS + * + * @{ + */ + +#ifdef RTEMS_DEPRECATED_TYPES +/** + * @brief Single precision float type. + * + * @deprecated Use @c float instead. + */ +typedef single_precision rtems_single; + +/** + * @brief Double precision float type. + * + * @deprecated Use @c double instead. + */ +typedef double_precision rtems_double; + +/** + * @brief RTEMS boolean type. + * + * @deprecated Use @c bool instead + */ +typedef boolean rtems_boolean; +#endif + +/** + * @brief Classic API @ref ClassicRTEMSSubSecObjectNames "object name" type. + * + * Contains the name of a Classic API object. It is an unsigned 32-bit integer + * which can be treated as a numeric value or initialized using + * rtems_build_name() to contain four ASCII characters. + */ +typedef uint32_t rtems_name; + +/** + * @brief Used to manage and manipulate + * @ref ClassicRTEMSSubSecObjectIdentifiers "RTEMS object identifiers". + */ +typedef Objects_Id rtems_id; + +/** + * @brief Invalid object identifier value. + * + * No object can have this identifier value. + */ +#define RTEMS_ID_NONE OBJECTS_ID_NONE + +/** + * @brief Public name for task context area. + */ +typedef Context_Control rtems_context; + +#if (CPU_HARDWARE_FP == TRUE) || (CPU_SOFTWARE_FP == TRUE) +/** + * @brief Public name for task floating point context area. + */ +typedef Context_Control_fp rtems_context_fp; +#endif + +/** + * @brief Defines the format of the interrupt stack frame as it appears to a + * user ISR. + * + * This data structure may not be defined on all ports + */ +typedef CPU_Interrupt_frame rtems_interrupt_frame; + +/** + * @brief Information structure returned by the Heap Handler via the Region + * Manager. + */ +typedef Heap_Information_block region_information_block; + +/** + * @brief Used to manage and manipulate intervals specified by + * @ref ClassicRTEMSSecTime "clock ticks". + */ +typedef Watchdog_Interval rtems_interval; + +/** + * @brief Represents the CPU usage per thread. + * + * When using nano seconds granularity timing, RTEMS may internally use a + * variety of representations. + */ +#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + typedef struct timespec rtems_thread_cpu_usage_t; +#else + typedef uint32_t rtems_thread_cpu_usage_t; +#endif + +/** + * @brief Data structure to manage and manipulate calendar + * @ref ClassicRTEMSSecTime "time". + */ +typedef struct { + /** + * @brief Year, A.D. + */ + uint32_t year; + /** + * @brief Month, 1 .. 12. + */ + uint32_t month; + /** + * @brief Day, 1 .. 31. + */ + uint32_t day; + /** + * @brief Hour, 0 .. 23. + */ + uint32_t hour; + /** + * @brief Minute, 0 .. 59. + */ + uint32_t minute; + /** + * @brief Second, 0 .. 59. + */ + uint32_t second; + /** + * @brief Elapsed ticks between seconds. + */ + uint32_t ticks; +} rtems_time_of_day; + +/** + * @brief Task mode type. + */ +typedef Modes_Control rtems_mode; + +/* + * MPCI related entries + */ +#if defined(RTEMS_MULTIPROCESSING) +/** + * @brief Set of MPCI packet classes which are internally dispatched to the + * managers. + */ +typedef MP_packet_Classes rtems_mp_packet_classes; + +/** + * @brief Prefix found at the beginning of each MPCI packet sent between nodes. + */ +typedef MP_packet_Prefix rtems_packet_prefix; + +/** + * @brief Indirect pointer to the initialization entry point for an MPCI + * handler. + */ +typedef MPCI_initialization_entry rtems_mpci_initialization_entry; + +/** + * @brief Indirect pointer to the get_packet entry point for an MPCI handler. + */ +typedef MPCI_get_packet_entry rtems_mpci_get_packet_entry; + +/** + * @brief Indirect pointer to the return_packet entry point for an MPCI + * handler. + */ +typedef MPCI_return_packet_entry rtems_mpci_return_packet_entry; + +/** + * @brief Indirect pointer to the send_packet entry point for an MPCI handler. + */ +typedef MPCI_send_entry rtems_mpci_send_packet_entry; + +/** + * @brief Indirect pointer to the receive entry point for an MPCI handler. + */ +typedef MPCI_receive_entry rtems_mpci_receive_packet_entry; + +/** + * @brief Return type from every MPCI handler routine. + */ +typedef MPCI_Entry rtems_mpci_entry; + +/** + * @brief Structure which is used to configure an MPCI handler. + */ +typedef MPCI_Control rtems_mpci_table; + +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/asr.inl b/cpukit/rtems/inline/rtems/rtems/asr.inl new file mode 100644 index 0000000000..93587a312c --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/asr.inl @@ -0,0 +1,119 @@ +/** + * @file rtems/rtems/asr.inl + * + * This include file contains the implemenation of all routines + * associated with the asynchronous signal handler which are inlined. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_ASR_H +# error "Never use <rtems/rtems/asr.inl> directly; include <rtems/rtems/asr.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_ASR_INL +#define _RTEMS_RTEMS_ASR_INL + +#include <rtems/score/isr.h> + +/** + * @addtogroup ClassicASR + * @{ + */ + +/** + * @brief ASR_Initialize + * + * This routine initializes the given RTEMS_ASR information record. + */ +RTEMS_INLINE_ROUTINE void _ASR_Initialize ( + ASR_Information *information +) +{ + information->is_enabled = false; + information->handler = NULL; + information->mode_set = RTEMS_DEFAULT_MODES; + information->signals_posted = 0; + information->signals_pending = 0; + information->nest_level = 0; +} + +/** + * @brief ASR_Swap_signals + * + * This routine atomically swaps the pending and posted signal + * sets. This is done when the thread alters its mode in such a + * way that the RTEMS_ASR disable/enable flag changes. + */ +RTEMS_INLINE_ROUTINE void _ASR_Swap_signals ( + ASR_Information *information +) +{ + rtems_signal_set _signals; + ISR_Level _level; + + _ISR_Disable( _level ); + _signals = information->signals_pending; + information->signals_pending = information->signals_posted; + information->signals_posted = _signals; + _ISR_Enable( _level ); +} + +/** + * @brief ASR_Is_null_handler + * + * This function returns TRUE if the given asr_handler is NULL and + * FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _ASR_Is_null_handler ( + rtems_asr_entry asr_handler +) +{ + return asr_handler == NULL; +} + +/** + * @brief ASR_Are_signals_pending + * + * This function returns TRUE if there are signals pending in the + * given RTEMS_ASR information record and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _ASR_Are_signals_pending ( + ASR_Information *information +) +{ + return information->signals_posted != 0; +} + +/** + * @brief ASR_Post_signals + * + * This routine posts the given signals into the signal_set + * passed in. The result is returned to the user in signal_set. + * + * NOTE: This must be implemented as a macro. + */ +RTEMS_INLINE_ROUTINE void _ASR_Post_signals( + rtems_signal_set signals, + rtems_signal_set *signal_set +) +{ + ISR_Level _level; + + _ISR_Disable( _level ); + *signal_set |= signals; + _ISR_Enable( _level ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/attr.inl b/cpukit/rtems/inline/rtems/rtems/attr.inl new file mode 100644 index 0000000000..7a697588da --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/attr.inl @@ -0,0 +1,197 @@ +/** + * @file rtems/rtems/attr.inl + * + * This include file contains all of the inlined routines associated + * with attributes. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_ATTR_H +# error "Never use <rtems/rtems/attr.inl> directly; include <rtems/rtems/attr.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_ATTR_INL +#define _RTEMS_RTEMS_ATTR_INL + +#include <rtems/score/basedefs.h> /* RTEMS_INLINE_ROUTINE */ + +/** + * @addtogroup ClassicAttributes + * @{ + */ + +/** + * @brief Attributes_Set + * + * This function sets the requested new_attributes in the attribute_set + * passed in. The result is returned to the user. + */ +RTEMS_INLINE_ROUTINE rtems_attribute _Attributes_Set ( + rtems_attribute new_attributes, + rtems_attribute attribute_set +) +{ + return attribute_set | new_attributes; +} + +/** + * @brief Attributes_Clear + * + * This function clears the requested new_attributes in the attribute_set + * passed in. The result is returned to the user. + */ +RTEMS_INLINE_ROUTINE rtems_attribute _Attributes_Clear ( + rtems_attribute attribute_set, + rtems_attribute mask +) +{ + return attribute_set & ~mask; +} + +/** + * @brief Attributes_Is_floating_point + * + * This function returns TRUE if the floating point attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_floating_point( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_FLOATING_POINT ) ? true : false; +} + +#if defined(RTEMS_MULTIPROCESSING) +/** + * @brief Attributes_Is_global + * + * This function returns TRUE if the global object attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_global( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_GLOBAL ) ? true : false; +} +#endif + +/** + * @brief Attributes_Is_priority + * + * This function returns TRUE if the priority attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_priority( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_PRIORITY ) ? true : false; +} + +/** + * @brief Attributes_Is_binary_semaphore + * + * This function returns TRUE if the binary semaphore attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_binary_semaphore( + rtems_attribute attribute_set +) +{ + return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE); +} + +/** + * @brief Attributes_Is_simple_binary_semaphore + * + * This function returns TRUE if the simple binary semaphore attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_simple_binary_semaphore( + rtems_attribute attribute_set +) +{ + return + ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE); +} + +/** + * @brief Attributes_Is_counting_semaphore + * + * This function returns TRUE if the counting semaphore attribute is + * enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_counting_semaphore( + rtems_attribute attribute_set +) +{ + return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE); +} + +/** + * @brief Attributes_Is_inherit_priority + * + * This function returns TRUE if the priority inheritance attribute + * is enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_inherit_priority( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_INHERIT_PRIORITY ) ? true : false; +} + +/** + * @brief Attributes_Is_priority_ceiling + * + * This function returns TRUE if the priority ceiling attribute + * is enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_priority_ceiling( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_PRIORITY_CEILING ) ? true : false; +} + +/** + * @brief Attributes_Is_barrier_automatic + * + * This function returns TRUE if the barrier automatic release + * attribute is enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_barrier_automatic( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_BARRIER_AUTOMATIC_RELEASE ) ? true : false; +} + +/** + * @brief Attributes_Is_system_task + * + * This function returns TRUE if the system task attribute + * is enabled in the attribute_set and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Attributes_Is_system_task( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_SYSTEM_TASK ) ? true : false; +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/barrier.inl b/cpukit/rtems/inline/rtems/rtems/barrier.inl new file mode 100644 index 0000000000..3bec0f2075 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/barrier.inl @@ -0,0 +1,89 @@ +/** + * @file rtems/rtems/barrier.inl + * + * This file contains the static inlin implementation of the inlined + * routines from the Barrier Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_BARRIER_H +# error "Never use <rtems/rtems/barrier.inl> directly; include <rtems/rtems/barrier.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_BARRIER_INL +#define _RTEMS_RTEMS_BARRIER_INL + +/** + * @addtogroup ClassicBarrier + * @{ + */ + +/** + * @brief _Barrier_Allocate + * + * This function allocates a barrier control block from + * the inactive chain of free barrier control blocks. + */ +RTEMS_INLINE_ROUTINE Barrier_Control *_Barrier_Allocate( void ) +{ + return (Barrier_Control *) _Objects_Allocate( &_Barrier_Information ); +} + +/** + * @brief _Barrier_Free + * + * This routine frees a barrier control block to the + * inactive chain of free barrier control blocks. + */ +RTEMS_INLINE_ROUTINE void _Barrier_Free ( + Barrier_Control *the_barrier +) +{ + _Objects_Free( &_Barrier_Information, &the_barrier->Object ); +} + +/** + * @brief _Barrier_Get + * + * This function maps barrier IDs to barrier control blocks. + * If ID corresponds to a local barrier, then it returns + * the_barrier control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the barrier ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_barrier is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_barrier is undefined. + */ +RTEMS_INLINE_ROUTINE Barrier_Control *_Barrier_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Barrier_Control *) + _Objects_Get( &_Barrier_Information, id, location ); +} + +/** + * @brief _Barrier_Is_null + * + * This function returns TRUE if the_barrier is NULL and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Barrier_Is_null ( + Barrier_Control *the_barrier +) +{ + return ( the_barrier == NULL ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/dpmem.inl b/cpukit/rtems/inline/rtems/rtems/dpmem.inl new file mode 100644 index 0000000000..5b944484b5 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/dpmem.inl @@ -0,0 +1,90 @@ +/** + * @file rtems/rtems/dpmem.inl + * + * This include file contains the inline routine used in conjunction + * with the Dual Ported Memory Manager + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_DPMEM_H +# error "Never use <rtems/rtems/dpmem.inl> directly; include <rtems/rtems/dpmem.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_DPMEM_INL +#define _RTEMS_RTEMS_DPMEM_INL + +/** + * @addtogroup ClassicDPMEM + * @{ + */ + +/** + * @brief Dual_ported_memory_Allocate + * + * This routine allocates a port control block from the inactive chain + * of free port control blocks. + */ +RTEMS_INLINE_ROUTINE Dual_ported_memory_Control + *_Dual_ported_memory_Allocate ( void ) +{ + return (Dual_ported_memory_Control *) + _Objects_Allocate( &_Dual_ported_memory_Information ); +} + +/** + * @brief Dual_ported_memory_Free + * + * This routine frees a port control block to the inactive chain + * of free port control blocks. + */ +RTEMS_INLINE_ROUTINE void _Dual_ported_memory_Free ( + Dual_ported_memory_Control *the_port +) +{ + _Objects_Free( &_Dual_ported_memory_Information, &the_port->Object ); +} + +/** + * @brief Dual_ported_memory_Get + * + * This function maps port IDs to port control blocks. If ID + * corresponds to a local port, then it returns the_port control + * pointer which maps to ID and location is set to OBJECTS_LOCAL. + * Global ports are not supported, thus if ID does not map to a + * local port, location is set to OBJECTS_ERROR and the_port is + * undefined. + */ +RTEMS_INLINE_ROUTINE Dual_ported_memory_Control *_Dual_ported_memory_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Dual_ported_memory_Control *) + _Objects_Get( &_Dual_ported_memory_Information, id, location ); +} + +/** + * @brief Dual_ported_memory_Is_null + * + * This function returns true if the_port is NULL and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Dual_ported_memory_Is_null( + Dual_ported_memory_Control *the_port +) +{ + return ( the_port == NULL ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/event.inl b/cpukit/rtems/inline/rtems/rtems/event.inl new file mode 100644 index 0000000000..8ea83e2176 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/event.inl @@ -0,0 +1,33 @@ +/** + * @file rtems/rtems/event.inl + * + * This include file contains the static inline implementation of + * macros for the Event Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_EVENT_H +# error "Never use <rtems/rtems/event.inl> directly; include <rtems/rtems/event.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_EVENT_INL +#define _RTEMS_RTEMS_EVENT_INL + +/** + * @addtogroup ClassicEvent + * @{ + */ + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/eventset.inl b/cpukit/rtems/inline/rtems/rtems/eventset.inl new file mode 100644 index 0000000000..dbe869c85d --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/eventset.inl @@ -0,0 +1,94 @@ +/** + * @file rtems/rtems/eventset.inl + * + * This include file contains the information pertaining to event sets. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_EVENTSET_H +# error "Never use <rtems/rtems/eventset.inl> directly; include <rtems/rtems/eventset.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_EVENTSET_INL +#define _RTEMS_RTEMS_EVENTSET_INL + +#include <rtems/score/basedefs.h> /* RTEMS_INLINE_ROUTINE */ +#include <rtems/score/isr.h> /* ISR_Level */ + +/** + * @addtogroup ClassicEventSet + * @{ + */ + +/** + * @brief Event_sets_Is_empty + * + * This function returns TRUE if on events are posted in the event_set, + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Event_sets_Is_empty( + rtems_event_set the_event_set +) +{ + return ( the_event_set == 0 ); +} + +/** + * @brief Event_sets_Post + * + * This routine posts the given new_events into the event_set + * passed in. The result is returned to the user in event_set. + */ +RTEMS_INLINE_ROUTINE void _Event_sets_Post( + rtems_event_set the_new_events, + rtems_event_set *the_event_set +) +{ + ISR_Level level; + + _ISR_Disable( level ); + *the_event_set |= the_new_events; + _ISR_Enable( level ); +} + +/** + * @brief Event_sets_Get + * + * This function returns the events in event_condition which are + * set in event_set. + */ +RTEMS_INLINE_ROUTINE rtems_event_set _Event_sets_Get( + rtems_event_set the_event_set, + rtems_event_set the_event_condition +) +{ + return ( the_event_set & the_event_condition ); +} + +/** + * @brief Event_sets_Clear + * + * This function removes the events in mask from the event_set + * passed in. The result is returned to the user in event_set. + */ +RTEMS_INLINE_ROUTINE rtems_event_set _Event_sets_Clear( + rtems_event_set the_event_set, + rtems_event_set the_mask +) +{ + return ( the_event_set & ~(the_mask) ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/message.inl b/cpukit/rtems/inline/rtems/rtems/message.inl new file mode 100644 index 0000000000..dfaeb25fb3 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/message.inl @@ -0,0 +1,83 @@ +/** + * @file rtems/rtems/message.inl + * + * This include file contains the static inline implementation of all + * inlined routines in the Message Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_MESSAGE_H +# error "Never use <rtems/rtems/message.inl> directly; include <rtems/rtems/message.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_MESSAGE_INL +#define _RTEMS_RTEMS_MESSAGE_INL + +#include <rtems/score/wkspace.h> + +/** + * @addtogroup ClassicMessageQueue + * @{ + */ + +/** + * @brief Message_queue_Is_null + * + * This function places the_message at the rear of the outstanding + * messages on the_message_queue. + */ +RTEMS_INLINE_ROUTINE bool _Message_queue_Is_null ( + Message_queue_Control *the_message_queue +) +{ + return ( the_message_queue == NULL ); +} + + +/** + * @brief Message_queue_Free + * + * This routine deallocates a message queue control block into + * the inactive chain of free message queue control blocks. + */ +RTEMS_INLINE_ROUTINE void _Message_queue_Free ( + Message_queue_Control *the_message_queue +) +{ + _Objects_Free( &_Message_queue_Information, &the_message_queue->Object ); +} + +/** + * @brief Message_queue_Get + * + * This function maps message queue IDs to message queue control + * blocks. If ID corresponds to a local message queue, then it + * returns the_message_queue control pointer which maps to ID + * and location is set to OBJECTS_LOCAL. If the message queue ID is + * global and resides on a remote node, then location is set + * to OBJECTS_REMOTE, and the_message_queue is undefined. + * Otherwise, location is set to OBJECTS_ERROR and + * the_message_queue is undefined. + */ +RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Message_queue_Control *) + _Objects_Get( &_Message_queue_Information, id, location ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/modes.inl b/cpukit/rtems/inline/rtems/rtems/modes.inl new file mode 100644 index 0000000000..d0dfe4932b --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/modes.inl @@ -0,0 +1,136 @@ +/** + * @file rtems/rtems/modes.inl + * + * This include file contains the static inline implementation of the + * inlined routines in the Mode Handler + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_MODES_H +# error "Never use <rtems/rtems/modes.inl> directly; include <rtems/rtems/modes.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_MODES_INL +#define _RTEMS_RTEMS_MODES_INL + +/** + * @addtogroup ClassicModes + * @{ + */ + +/** + * @brief Modes_Mask_changed + * + * This function returns TRUE if any of the mode flags in mask + * are set in mode_set, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Modes_Mask_changed ( + Modes_Control mode_set, + Modes_Control masks +) +{ + return ( mode_set & masks ) ? true : false; +} + +/** + * @brief Modes_Is_asr_disabled + * + * This function returns TRUE if mode_set indicates that Asynchronous + * Signal Processing is disabled, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Modes_Is_asr_disabled ( + Modes_Control mode_set +) +{ + return (mode_set & RTEMS_ASR_MASK) == RTEMS_NO_ASR; +} + +/** + * @brief Modes_Is_preempt + * + * This function returns TRUE if mode_set indicates that preemption + * is enabled, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Modes_Is_preempt ( + Modes_Control mode_set +) +{ + return (mode_set & RTEMS_PREEMPT_MASK) == RTEMS_PREEMPT; +} + +/** + * @brief Modes_Is_timeslice + * + * This function returns TRUE if mode_set indicates that timeslicing + * is enabled, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Modes_Is_timeslice ( + Modes_Control mode_set +) +{ + return (mode_set & RTEMS_TIMESLICE_MASK) == RTEMS_TIMESLICE; +} + +/** + * @brief Modes_Get_interrupt_level + * + * This function returns the interrupt level portion of the mode_set. + */ +RTEMS_INLINE_ROUTINE ISR_Level _Modes_Get_interrupt_level ( + Modes_Control mode_set +) +{ + return ( mode_set & RTEMS_INTERRUPT_MASK ); +} + +/** + * @brief Modes_Set_interrupt_level + * + * This routine sets the current interrupt level to that specified + * in the mode_set. + */ +RTEMS_INLINE_ROUTINE void _Modes_Set_interrupt_level ( + Modes_Control mode_set +) +{ + _ISR_Set_level( _Modes_Get_interrupt_level( mode_set ) ); +} + +/** + * @brief Modes_Change + * + * This routine changes the modes in old_mode_set indicated by + * mask to the requested values in new_mode_set. The resulting + * mode set is returned in out_mode_set and the modes that changed + * is returned in changed. + */ +RTEMS_INLINE_ROUTINE void _Modes_Change ( + Modes_Control old_mode_set, + Modes_Control new_mode_set, + Modes_Control mask, + Modes_Control *out_mode_set, + Modes_Control *changed +) +{ + Modes_Control _out_mode; + + _out_mode = old_mode_set; + _out_mode &= ~mask; + _out_mode |= new_mode_set & mask; + *changed = _out_mode ^ old_mode_set; + *out_mode_set = _out_mode; +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/options.inl b/cpukit/rtems/inline/rtems/rtems/options.inl new file mode 100644 index 0000000000..8d2b406f33 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/options.inl @@ -0,0 +1,61 @@ +/** + * @file rtems/rtems/options.inl + * + * This file contains the static inline implementation of the inlined + * routines from the Options Handler. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_OPTIONS_H +# error "Never use <rtems/rtems/options.inl> directly; include <rtems/rtems/options.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_OPTIONS_INL +#define _RTEMS_RTEMS_OPTIONS_INL + +#include <rtems/score/basedefs.h> /* RTEMS_INLINE_ROUTINE */ + +/** + * @addtogroup ClassicOptions + * @{ + */ + +/** + * @brief Options_Is_no_wait + * + * This function returns TRUE if the RTEMS_NO_WAIT option is enabled in + * option_set, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Options_Is_no_wait ( + rtems_option option_set +) +{ + return (option_set & RTEMS_NO_WAIT) ? true : false; +} + +/** + * @brief Options_Is_any + * + * This function returns TRUE if the RTEMS_EVENT_ANY option is enabled in + * OPTION_SET, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Options_Is_any ( + rtems_option option_set +) +{ + return (option_set & RTEMS_EVENT_ANY) ? true : false; +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/part.inl b/cpukit/rtems/inline/rtems/rtems/part.inl new file mode 100644 index 0000000000..eb10dc4e58 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/part.inl @@ -0,0 +1,175 @@ +/** + * @file rtems/rtems/part.inl + * + * This file contains the macro implementation of all inlined routines + * in the Partition Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_PART_H +# error "Never use <rtems/rtems/part.inl> directly; include <rtems/rtems/part.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_PART_INL +#define _RTEMS_RTEMS_PART_INL + +/** + * @addtogroup ClassicPart + * @{ + */ + +/** + * @brief Partition_Allocate_buffer + * + * This function attempts to allocate a buffer from the_partition. + * If successful, it returns the address of the allocated buffer. + * Otherwise, it returns NULL. + */ +RTEMS_INLINE_ROUTINE void *_Partition_Allocate_buffer ( + Partition_Control *the_partition +) +{ + return _Chain_Get( &the_partition->Memory ); +} + +/** + * @brief Partition_Free_buffer + * + * This routine frees the_buffer to the_partition. + */ +RTEMS_INLINE_ROUTINE void _Partition_Free_buffer ( + Partition_Control *the_partition, + Chain_Node *the_buffer +) +{ + _Chain_Append( &the_partition->Memory, the_buffer ); +} + +/** + * @brief Partition_Is_buffer_on_boundary + * + * This function returns TRUE if the_buffer is on a valid buffer + * boundary for the_partition, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Partition_Is_buffer_on_boundary ( + void *the_buffer, + Partition_Control *the_partition +) +{ + uint32_t offset; + + offset = (uint32_t) _Addresses_Subtract( + the_buffer, + the_partition->starting_address + ); + + return ((offset % the_partition->buffer_size) == 0); +} + +/** + * @brief Partition_Is_buffer_valid + * + * This function returns TRUE if the_buffer is a valid buffer from + * the_partition, otherwise FALSE is returned. + */ +RTEMS_INLINE_ROUTINE bool _Partition_Is_buffer_valid ( + Chain_Node *the_buffer, + Partition_Control *the_partition +) +{ + void *starting; + void *ending; + + starting = the_partition->starting_address; + ending = _Addresses_Add_offset( starting, the_partition->length ); + + return ( + _Addresses_Is_in_range( the_buffer, starting, ending ) && + _Partition_Is_buffer_on_boundary( the_buffer, the_partition ) + ); +} + +/** + * @brief Partition_Is_buffer_size_aligned + * + * This function returns TRUE if the use of the specified buffer_size + * will result in the allocation of buffers whose first byte is + * properly aligned, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Partition_Is_buffer_size_aligned ( + uint32_t buffer_size +) +{ + return ((buffer_size % CPU_PARTITION_ALIGNMENT) == 0); +} + +/** + * @brief Partition_Allocate + * + * This function allocates a partition control block from + * the inactive chain of free partition control blocks. + */ +RTEMS_INLINE_ROUTINE Partition_Control *_Partition_Allocate ( void ) +{ + return (Partition_Control *) _Objects_Allocate( &_Partition_Information ); +} + +/** + * @brief Partition_Free + * + * This routine frees a partition control block to the + * inactive chain of free partition control blocks. + */ +RTEMS_INLINE_ROUTINE void _Partition_Free ( + Partition_Control *the_partition +) +{ + _Objects_Free( &_Partition_Information, &the_partition->Object ); +} + +/** + * @brief Partition_Get + * + * This function maps partition IDs to partition control blocks. + * If ID corresponds to a local partition, then it returns + * the_partition control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. If the partition ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_partition is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_partition is undefined. + */ +RTEMS_INLINE_ROUTINE Partition_Control *_Partition_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Partition_Control *) + _Objects_Get( &_Partition_Information, id, location ); +} + +/** + * @brief Partition_Is_null + * + * This function returns TRUE if the_partition is NULL + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Partition_Is_null ( + Partition_Control *the_partition +) +{ + return ( the_partition == NULL ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/ratemon.inl b/cpukit/rtems/inline/rtems/rtems/ratemon.inl new file mode 100644 index 0000000000..2e8964faa1 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/ratemon.inl @@ -0,0 +1,127 @@ +/** + * @file rtems/rtems/ratemon.inl + * + * This file contains the static inline implementation of the inlined + * routines in the Rate Monotonic Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_RATEMON_H +# error "Never use <rtems/rtems/ratemon.inl> directly; include <rtems/rtems/ratemon.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_RATEMON_INL +#define _RTEMS_RTEMS_RATEMON_INL + +/** + * @addtogroup ClassicRateMon + * @{ + */ + +/** + * @brief Rate_monotonic_Allocate + * + * This function allocates a period control block from + * the inactive chain of free period control blocks. + */ +RTEMS_INLINE_ROUTINE Rate_monotonic_Control *_Rate_monotonic_Allocate( void ) +{ + return (Rate_monotonic_Control *) + _Objects_Allocate( &_Rate_monotonic_Information ); +} + +/** + * @brief Rate_monotonic_Free + * + * This routine allocates a period control block from + * the inactive chain of free period control blocks. + */ +RTEMS_INLINE_ROUTINE void _Rate_monotonic_Free ( + Rate_monotonic_Control *the_period +) +{ + _Objects_Free( &_Rate_monotonic_Information, &the_period->Object ); +} + +/** + * @brief Rate_monotonic_Get + * + * This function maps period IDs to period control blocks. + * If ID corresponds to a local period, then it returns + * the_period control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. Otherwise, location is set + * to OBJECTS_ERROR and the_period is undefined. + */ +RTEMS_INLINE_ROUTINE Rate_monotonic_Control *_Rate_monotonic_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Rate_monotonic_Control *) + _Objects_Get( &_Rate_monotonic_Information, id, location ); +} + +/** + * @brief Rate_monotonic_Is_active + * + * This function returns TRUE if the_period is in the ACTIVE state, + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Rate_monotonic_Is_active ( + Rate_monotonic_Control *the_period +) +{ + return (the_period->state == RATE_MONOTONIC_ACTIVE); +} + +/** + * @brief Rate_monotonic_Is_inactive + * + * This function returns TRUE if the_period is in the ACTIVE state, + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Rate_monotonic_Is_inactive ( + Rate_monotonic_Control *the_period +) +{ + return (the_period->state == RATE_MONOTONIC_INACTIVE); +} + +/** + * @brief Rate_monotonic_Is_expired + * + * This function returns TRUE if the_period is in the EXPIRED state, + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Rate_monotonic_Is_expired ( + Rate_monotonic_Control *the_period +) +{ + return (the_period->state == RATE_MONOTONIC_EXPIRED); +} + +/** + * @brief Rate_monotonic_Is_null + * + * This function returns TRUE if the_period is NULL and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Rate_monotonic_Is_null ( + Rate_monotonic_Control *the_period +) +{ + return (the_period == NULL); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/region.inl b/cpukit/rtems/inline/rtems/rtems/region.inl new file mode 100644 index 0000000000..e70891378d --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/region.inl @@ -0,0 +1,115 @@ +/** + * @file rtems/rtems/region.inl + * + * This file contains the macro implementation of the inlined + * routines from the Region Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_REGION_H +# error "Never use <rtems/rtems/region.inl> directly; include <rtems/rtems/region.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_REGION_INL +#define _RTEMS_RTEMS_REGION_INL + +/** + * @addtogroup ClassicRegion + * @{ + */ + +/** + * @brief Region_Allocate + * + * This function allocates a region control block from + * the inactive chain of free region control blocks. + */ +RTEMS_INLINE_ROUTINE Region_Control *_Region_Allocate( void ) +{ + return (Region_Control *) _Objects_Allocate( &_Region_Information ); +} + +/** + * @brief Region_Free + * + * This routine frees a region control block to the + * inactive chain of free region control blocks. + */ +RTEMS_INLINE_ROUTINE void _Region_Free ( + Region_Control *the_region +) +{ + _Objects_Free( &_Region_Information, &the_region->Object ); +} + +/** + * @brief Region_Get + * + * This function maps region IDs to region control blocks. + * If ID corresponds to a local region, then it returns + * the_region control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. Otherwise, location is set + * to OBJECTS_ERROR and the_region is undefined. + */ +RTEMS_INLINE_ROUTINE Region_Control *_Region_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Region_Control *) + _Objects_Get_no_protection( &_Region_Information, id, location ); +} + +/** + * @brief Region_Allocate_segment + * + * This function attempts to allocate a segment from the_region. + * If successful, it returns the address of the allocated segment. + * Otherwise, it returns NULL. + */ +RTEMS_INLINE_ROUTINE void *_Region_Allocate_segment ( + Region_Control *the_region, + uintptr_t size +) +{ + return _Heap_Allocate( &the_region->Memory, size ); +} + +/** + * @brief Region_Free_segment + * + * This function frees the_segment to the_region. + */ +RTEMS_INLINE_ROUTINE bool _Region_Free_segment ( + Region_Control *the_region, + void *the_segment +) +{ + return _Heap_Free( &the_region->Memory, the_segment ); +} + +/** + * @brief Region_Is_null + * + * This function returns TRUE if the_region is NULL and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Region_Is_null ( + Region_Control *the_region +) +{ + return ( the_region == NULL ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/sem.inl b/cpukit/rtems/inline/rtems/rtems/sem.inl new file mode 100644 index 0000000000..de876d896a --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/sem.inl @@ -0,0 +1,110 @@ +/** + * @file rtems/rtems/sem.inl + * + * This file contains the static inlin implementation of the inlined + * routines from the Semaphore Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_SEM_H +# error "Never use <rtems/rtems/sem.inl> directly; include <rtems/rtems/sem.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_SEM_INL +#define _RTEMS_RTEMS_SEM_INL + +/** + * @addtogroup ClassicSem + * @{ + */ + +/** + * @brief Semaphore_Allocate + * + * This function allocates a semaphore control block from + * the inactive chain of free semaphore control blocks. + */ +RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Allocate( void ) +{ + return (Semaphore_Control *) _Objects_Allocate( &_Semaphore_Information ); +} + +/** + * @brief Semaphore_Free + * + * This routine frees a semaphore control block to the + * inactive chain of free semaphore control blocks. + */ +RTEMS_INLINE_ROUTINE void _Semaphore_Free ( + Semaphore_Control *the_semaphore +) +{ + _Objects_Free( &_Semaphore_Information, &the_semaphore->Object ); +} + +/** + * @brief Semaphore_Get + * + * This function maps semaphore IDs to semaphore control blocks. + * If ID corresponds to a local semaphore, then it returns + * the_semaphore control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the semaphore ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_semaphore is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_semaphore is undefined. + */ +RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Semaphore_Control *) + _Objects_Get( &_Semaphore_Information, id, location ); +} + +/** + * @brief Semaphore_Get (Interrupts disabled) + * + * This function maps semaphore IDs to semaphore control blocks. + * If ID corresponds to a local semaphore, then it returns + * the_semaphore control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the semaphore ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_semaphore is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_semaphore is undefined. + */ +RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Get_interrupt_disable ( + Objects_Id id, + Objects_Locations *location, + ISR_Level *level +) +{ + return (Semaphore_Control *) + _Objects_Get_isr_disable( &_Semaphore_Information, id, location, level ); +} + +/** + * @brief Semaphore_Is_null + * + * This function returns TRUE if the_semaphore is NULL and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Semaphore_Is_null ( + Semaphore_Control *the_semaphore +) +{ + return ( the_semaphore == NULL ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/status.inl b/cpukit/rtems/inline/rtems/rtems/status.inl new file mode 100644 index 0000000000..a518c102f3 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/status.inl @@ -0,0 +1,62 @@ +/** + * @file rtems/rtems/status.inl + * + * This include file contains the implementations of the inlined + * routines for the status package. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_STATUS_H +# error "Never use <rtems/rtems/status.inl> directly; include <rtems/rtems/status.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_STATUS_INL +#define _RTEMS_RTEMS_STATUS_INL + +#include <rtems/score/basedefs.h> + +/** + * @addtogroup ClassicStatus + * @{ + */ + +/** + * @brief rtems_is_status_successful + * + * This function returns TRUE if the status code is equal to RTEMS_SUCCESSFUL, + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_is_status_successful( + rtems_status_code code +) +{ + return (code == RTEMS_SUCCESSFUL); +} + +/** + * @brief rtems_are_statuses_equal + * + * This function returns TRUE if the status code1 is equal to code2, + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_are_statuses_equal( + rtems_status_code code1, + rtems_status_code code2 +) +{ + return (code1 == code2); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/support.inl b/cpukit/rtems/inline/rtems/rtems/support.inl new file mode 100644 index 0000000000..bd79300e8a --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/support.inl @@ -0,0 +1,63 @@ +/** + * @file + * + * @ingroup ClassicRTEMS + * + * @brief Classic API support. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_SUPPORT_H +# error "Never use <rtems/rtems/support.inl> directly; include <rtems/rtems/support.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_SUPPORT_INL +#define _RTEMS_RTEMS_SUPPORT_INL + +/** + * @addtogroup ClassicRTEMS + * + * @{ + */ + +/** + * @brief Returns @c true if the name is valid, and @c false otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_is_name_valid ( + rtems_name name +) +{ + return ( name != 0 ); +} + +/** + * @brief Breaks the object name into the four component characters @a c1, + * @a c2, @a c3, and @a c4. + */ +RTEMS_INLINE_ROUTINE void rtems_name_to_characters( + rtems_name name, + char *c1, + char *c2, + char *c3, + char *c4 +) +{ + *c1 = (char) ((name >> 24) & 0xff); + *c2 = (char) ((name >> 16) & 0xff); + *c3 = (char) ((name >> 8) & 0xff); + *c4 = (char) ( name & 0xff); +} + +/** @} */ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/tasks.inl b/cpukit/rtems/inline/rtems/rtems/tasks.inl new file mode 100644 index 0000000000..e0fe241d45 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/tasks.inl @@ -0,0 +1,86 @@ +/** + * @file rtems/rtems/tasks.inl + * + * This file contains the static inline implementation of all inlined + * routines in the with RTEMS Tasks Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_TASKS_H +# error "Never use <rtems/rtems/tasks.inl> directly; include <rtems/rtems/tasks.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_TASKS_INL +#define _RTEMS_RTEMS_TASKS_INL + +/** + * @addtogroup ClassicTasks + * @{ + */ + +/** + * @brief RTEMS_tasks_Allocate + * + * This function allocates a task control block from + * the inactive chain of free task control blocks. + */ +RTEMS_INLINE_ROUTINE Thread_Control *_RTEMS_tasks_Allocate( void ) +{ + return (Thread_Control *) _Objects_Allocate( &_RTEMS_tasks_Information ); +} + +/** + * @brief RTEMS_tasks_Free + * + * This routine frees a task control block to the + * inactive chain of free task control blocks. + */ +RTEMS_INLINE_ROUTINE void _RTEMS_tasks_Free ( + Thread_Control *the_task +) +{ + _Objects_Free( + _Objects_Get_information_id( the_task->Object.id ), + &the_task->Object + ); +} + +/** + * @brief RTEMS_tasks_Priority_to_Core + * + * This function converts an RTEMS API priority into a core priority. + */ +RTEMS_INLINE_ROUTINE Priority_Control _RTEMS_tasks_Priority_to_Core( + rtems_task_priority priority +) +{ + return (Priority_Control) priority; +} + +/** + * @brief RTEMS_tasks_Priority_is_valid + * + * This function returns TRUE if the_priority is a valid user task priority + * and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _RTEMS_tasks_Priority_is_valid ( + rtems_task_priority the_priority +) +{ + return ( ( the_priority >= RTEMS_MINIMUM_PRIORITY ) && + ( the_priority <= RTEMS_MAXIMUM_PRIORITY ) ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/timer.inl b/cpukit/rtems/inline/rtems/rtems/timer.inl new file mode 100644 index 0000000000..10cae3f67d --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/timer.inl @@ -0,0 +1,126 @@ +/** + * @file rtems/rtems/timer.inl + * + * This file contains the static inline implementation of the inlined routines + * from the Timer Manager. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_RTEMS_TIMER_H +# error "Never use <rtems/rtems/timer.inl> directly; include <rtems/rtems/timer.h> instead." +#endif + +#ifndef _RTEMS_RTEMS_TIMER_INL +#define _RTEMS_RTEMS_TIMER_INL + +/** + * @addtogroup ClassicTimer + * @{ + */ + +/** + * @brief Timer_Allocate + * + * This function allocates a timer control block from + * the inactive chain of free timer control blocks. + */ +RTEMS_INLINE_ROUTINE Timer_Control *_Timer_Allocate( void ) +{ + return (Timer_Control *) _Objects_Allocate( &_Timer_Information ); +} + +/** + * @brief Timer_Free + * + * This routine frees a timer control block to the + * inactive chain of free timer control blocks. + */ +RTEMS_INLINE_ROUTINE void _Timer_Free ( + Timer_Control *the_timer +) +{ + _Objects_Free( &_Timer_Information, &the_timer->Object ); +} + +/** + * @brief Timer_Get + * + * This function maps timer IDs to timer control blocks. + * If ID corresponds to a local timer, then it returns + * the timer control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. Otherwise, location is set + * to OBJECTS_ERROR and the returned value is undefined. + */ +RTEMS_INLINE_ROUTINE Timer_Control *_Timer_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Timer_Control *) + _Objects_Get( &_Timer_Information, id, location ); +} + +/** + * @brief Timer_Is_interval_class + * + * This function returns TRUE if the class is that of an INTERVAL + * timer, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Timer_Is_interval_class ( + Timer_Classes the_class +) +{ + return (the_class == TIMER_INTERVAL) || (the_class == TIMER_INTERVAL_ON_TASK); +} + +/** + * @brief Timer_Is_time_of_day_class + * + * This function returns TRUE if the class is that of an INTERVAL + * timer, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Timer_Is_timer_of_day_class ( + Timer_Classes the_class +) +{ + return ( the_class == TIMER_TIME_OF_DAY ); +} + +/** + * @brief Timer_Is_dormant_class + * + * This function returns TRUE if the class is that of a DORMANT + * timer, and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Timer_Is_dormant_class ( + Timer_Classes the_class +) +{ + return ( the_class == TIMER_DORMANT ); +} + +/** + * @brief Timer_Is_null + * + * This function returns TRUE if the_timer is NULL and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Timer_Is_null ( + Timer_Control *the_timer +) +{ + return ( the_timer == NULL ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/rtems/mainpage.h b/cpukit/rtems/mainpage.h new file mode 100644 index 0000000000..fe8f627c36 --- /dev/null +++ b/cpukit/rtems/mainpage.h @@ -0,0 +1,950 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +/** + * @mainpage + * + * The RTEMS real-time operating systems is a layered system with each of the + * public APIs implemented in terms of a common foundation layer called the + * SuperCore. This is the Doxygen generated documentation for the RTEMS CPU + * Kit including the Classic API, POSIX API and SuperCore. + */ + +/** + * @page RTEMSPreface RTEMS History and Introduction + * + * In recent years, the cost required to develop a software product has + * increased significantly while the target hardware costs have decreased. Now + * a larger portion of money is expended in developing, using, and maintaining + * software. The trend in computing costs is the complete dominance of software + * over hardware costs. Because of this, it is necessary that formal + * disciplines be established to increase the probability that software is + * characterized by a high degree of correctness, maintainability, and + * portability. In addition, these disciplines must promote practices that aid + * in the consistent and orderly development of a software system within + * schedule and budgetary constraints. To be effective, these disciplines must + * adopt standards which channel individual software efforts toward a common + * goal. + * + * The push for standards in the software development field has been met with + * various degrees of success. The Microprocessor Operating Systems Interfaces + * (MOSI) effort has experienced only limited success. As popular as the UNIX + * operating system has grown, the attempt to develop a standard interface + * definition to allow portable application development has only recently begun + * to produce the results needed in this area. Unfortunately, very little + * effort has been expended to provide standards addressing the needs of the + * real-time community. Several organizations have addressed this need during + * recent years. + * + * The Real Time Executive Interface Definition (RTEID) was developed by + * Motorola with technical input from Software Components Group. RTEID was + * adopted by the VMEbus International Trade Association (VITA) as a baseline + * draft for their proposed standard multiprocessor, real-time executive + * interface, Open Real-Time Kernel Interface Definition (ORKID). These two + * groups are currently working together with the IEEE P1003.4 committee to + * insure that the functionality of their proposed standards is adopted as the + * real-time extensions to POSIX. + * + * This emerging standard defines an interface for the development of real-time + * software to ease the writing of real-time application programs that are + * directly portable across multiple real-time executive implementations. This + * interface includes both the source code interfaces and run-time behavior as + * seen by a real-time application. It does not include the details of how a + * kernel implements these functions. The standard's goal is to serve as a + * complete definition of external interfaces so that application code that + * conforms to these interfaces will execute properly in all real-time + * executive environments. With the use of a standards compliant executive, + * routines that acquire memory blocks, create and manage message queues, + * establish and use semaphores, and send and receive signals need not be + * redeveloped for a different real-time environment as long as the new + * environment is compliant with the standard. Software developers need only + * concentrate on the hardware dependencies of the real-time system. + * Furthermore, most hardware dependencies for real-time applications can be + * localized to the device drivers. + * + * A compliant executive provides simple and flexible real-time + * multiprocessing. It easily lends itself to both tightly-coupled and + * loosely-coupled configurations (depending on the system hardware + * configuration). Objects such as tasks, queues, events, signals, semaphores, + * and memory blocks can be designated as global objects and accessed by any + * task regardless of which processor the object and the accessing task reside. + * + * The acceptance of a standard for real-time executives will produce the same + * advantages enjoyed from the push for UNIX standardization by AT&T's System V + * Interface Definition and IEEE's POSIX efforts. A compliant multiprocessing + * executive will allow close coupling between UNIX systems and real-time + * executives to provide the many benefits of the UNIX development environment + * to be applied to real-time software development. Together they provide the + * necessary laboratory environment to implement real-time, distributed, + * embedded systems using a wide variety of computer architectures. + * + * A study was completed in 1988, within the Research, Development, and + * Engineering Center, U.S. Army Missile Command, which compared the various + * aspects of the Ada programming language as they related to the application + * of Ada code in distributed and/or multiple processing systems. Several + * critical conclusions were derived from the study. These conclusions have a + * major impact on the way the Army develops application software for embedded + * applications. These impacts apply to both in-house software development and + * contractor developed software. + * + * A conclusion of the analysis, which has been previously recognized by other + * agencies attempting to utilize Ada in a distributed or multiprocessing + * environment, is that the Ada programming language does not adequately + * support multiprocessing. Ada does provide a mechanism for multi-tasking, + * however, this capability exists only for a single processor system. The + * language also does not have inherent capabilities to access global named + * variables, flags or program code. These critical features are essential in + * order for data to be shared between processors. However, these drawbacks do + * have workarounds which are sometimes awkward and defeat the intent of + * software maintainability and portability goals. + * + * Another conclusion drawn from the analysis, was that the run time executives + * being delivered with the Ada compilers were too slow and inefficient to be + * used in modern missile systems. A run time executive is the core part of the + * run time system code, or operating system code, that controls task + * scheduling, input/output management and memory management. Traditionally, + * whenever efficient executive (also known as kernel) code was required by the + * application, the user developed in-house software. This software was usually + * written in assembly language for optimization. + * + * Because of this shortcoming in the Ada programming language, software + * developers in research and development and contractors for project managed + * systems, are mandated by technology to purchase and utilize off-the-shelf + * third party kernel code. The contractor, and eventually the Government, must + * pay a licensing fee for every copy of the kernel code used in an embedded + * system. + * + * The main drawback to this development environment is that the Government + * does not own, nor has the right to modify code contained within the kernel. + * V&V techniques in this situation are more difficult than if the complete + * source code were available. Responsibility for system failures due to faulty + * software is yet another area to be resolved under this environment. + * + * The Guidance and Control Directorate began a software development effort to + * address these problems. A project to develop an experimental run time kernel + * was begun that will eliminate the major drawbacks of the Ada programming + * language mentioned above. The Real Time Executive for Multiprocessor Systems + * (RTEMS) provides full capabilities for management of tasks, interrupts, + * time, and multiple processors in addition to those features typical of + * generic operating systems. The code is Government owned, so no licensing + * fees are necessary. RTEMS has been implemented in both the Ada and C + * programming languages. It has been ported to the following processor + * families: + * + * - Altera NIOS II + * - Analog Devices Blackfin + * - ARM + * - Freescale (formerly Motorola) MC68xxx + * - Freescale (formerly Motorola) MC683xx + * - Freescale (formerly Motorola) ColdFire + * - Intel i386 and above + * - Lattice Semiconductor LM32 + * - MIPS + * - PowerPC + * - Renesas (formerly Hitachi) SuperH + * - Renesas (formerly Hitachi) H8/300 + * - SPARC + * - Texas Instruments C3x/C4x + * - UNIX + * + * Support for other processor families, including RISC, CISC, and DSP, is + * planned. Since almost all of RTEMS is written in a high level language, + * ports to additional processor families require minimal effort. + * + * RTEMS multiprocessor support is capable of handling either homogeneous or + * heterogeneous systems. The kernel automatically compensates for + * architectural differences (byte swapping, etc.) between processors. This + * allows a much easier transition from one processor family to another without + * a major system redesign. + * + * Since the proposed standards are still in draft form, RTEMS cannot and does + * not claim compliance. However, the status of the standard is being carefully + * monitored to guarantee that RTEMS provides the functionality specified in + * the standard. Once approved, RTEMS will be made compliant. + */ + +/** + * @page RTEMSOverview RTEMS Overview + * + * @section RTEMSOverviewSecIntroduction Introduction + * + * RTEMS, Real-Time Executive for Multiprocessor Systems, is a real-time + * executive (kernel) which provides a high performance environment for + * embedded military applications including the following features: + * + * - multitasking capabilities + * - homogeneous and heterogeneous multiprocessor systems + * - event-driven, priority-based, preemptive scheduling + * - optional rate monotonic scheduling + * - intertask communication and synchronization + * - priority inheritance + * - responsive interrupt management + * - dynamic memory allocation + * - high level of user configurability + * + * This manual describes the usage of RTEMS for applications written in the C + * programming language. Those implementation details that are processor + * dependent are provided in the Applications Supplement documents. A + * supplement document which addresses specific architectural issues that + * affect RTEMS is provided for each processor type that is supported. + * + * @section RTEMSOverviewSecRealtimeApplicationSystems Real-time Application Systems + * + * Real-time application systems are a special class of computer applications. + * They have a complex set of characteristics that distinguish them from other + * software problems. Generally, they must adhere to more rigorous + * requirements. The correctness of the system depends not only on the results + * of computations, but also on the time at which the results are produced. The + * most important and complex characteristic of real-time application systems + * is that they must receive and respond to a set of external stimuli within + * rigid and critical time constraints referred to as deadlines. Systems can be + * buried by an avalanche of interdependent, asynchronous or cyclical event + * streams. + * + * Deadlines can be further characterized as either hard or soft based upon the + * value of the results when produced after the deadline has passed. A deadline + * is hard if the results have no value or if their use will result in a + * catastrophic event. In contrast, results which are produced after a soft + * deadline may have some value. + * + * Another distinguishing requirement of real-time application systems is the + * ability to coordinate or manage a large number of concurrent activities. + * Since software is a synchronous entity, this presents special problems. One + * instruction follows another in a repeating synchronous cycle. Even though + * mechanisms have been developed to allow for the processing of external + * asynchronous events, the software design efforts required to process and + * manage these events and tasks are growing more complicated. + * + * The design process is complicated further by spreading this activity over a + * set of processors instead of a single processor. The challenges associated + * with designing and building real-time application systems become very + * complex when multiple processors are involved. New requirements such as + * interprocessor communication channels and global resources that must be + * shared between competing processors are introduced. The ramifications of + * multiple processors complicate each and every characteristic of a real-time + * system. + * + * @section RTEMSOverviewSecRealtimeExecutive Real-time Executive + * + * Fortunately, real-time operating systems or real-time executives serve as a + * cornerstone on which to build the application system. A real-time + * multitasking executive allows an application to be cast into a set of + * logical, autonomous processes or tasks which become quite manageable. Each + * task is internally synchronous, but different tasks execute independently, + * resulting in an asynchronous processing stream. Tasks can be dynamically + * paused for many reasons resulting in a different task being allowed to + * execute for a period of time. The executive also provides an interface to + * other system components such as interrupt handlers and device drivers. + * System components may request the executive to allocate and coordinate + * resources, and to wait for and trigger synchronizing conditions. The + * executive system calls effectively extend the CPU instruction set to support + * efficient multitasking. By causing tasks to travel through well-defined + * state transitions, system calls permit an application to demand-switch + * between tasks in response to real-time events. + * + * By proper grouping of responses to stimuli into separate tasks, a system can + * now asynchronously switch between independent streams of execution, directly + * responding to external stimuli as they occur. This allows the system design + * to meet critical performance specifications which are typically measured by + * guaranteed response time and transaction throughput. The multiprocessor + * extensions of RTEMS provide the features necessary to manage the extra + * requirements introduced by a system distributed across several processors. + * It removes the physical barriers of processor boundaries from the world of + * the system designer, enabling more critical aspects of the system to receive + * the required attention. Such a system, based on an efficient real-time, + * multiprocessor executive, is a more realistic model of the outside world or + * environment for which it is designed. As a result, the system will always be + * more logical, efficient, and reliable. + * + * By using the directives provided by RTEMS, the real-time applications + * developer is freed from the problem of controlling and synchronizing + * multiple tasks and processors. In addition, one need not develop, test, + * debug, and document routines to manage memory, pass messages, or provide + * mutual exclusion. The developer is then able to concentrate solely on the + * application. By using standard software components, the time and cost + * required to develop sophisticated real-time applications is significantly + * reduced. + * + * @section RTEMSOverviewSecApplicationArchitecture RTEMS Application Architecture + * + * One important design goal of RTEMS was to provide a bridge between two + * critical layers of typical real-time systems. As shown in the following + * figure, RTEMS serves as a buffer between the project dependent application + * code and the target hardware. Most hardware dependencies for real-time + * applications can be localized to the low level device drivers. + * + * @todo Image RTEMS Application Architecture + * + * The RTEMS I/O interface manager provides an efficient tool for incorporating + * these hardware dependencies into the system while simultaneously providing a + * general mechanism to the application code that accesses them. A well + * designed real-time system can benefit from this architecture by building a + * rich library of standard application components which can be used repeatedly + * in other real-time projects. + * + * @section RTEMSOverviewSecInternalArchitecture RTEMS Internal Architecture + * + * RTEMS can be viewed as a set of layered components that work in harmony to + * provide a set of services to a real-time application system. The executive + * interface presented to the application is formed by grouping directives into + * logical sets called resource managers. Functions utilized by multiple + * managers such as scheduling, dispatching, and object management are provided + * in the executive core. The executive core depends on a small set of CPU + * dependent routines. Together these components provide a powerful run time + * environment that promotes the development of efficient real-time application + * systems. The following figure illustrates this organization: + * + * @todo Image RTEMS Architecture + * + * Subsequent chapters present a detailed description of the capabilities + * provided by each of the following RTEMS managers: + * + * - initialization + * - task + * - interrupt + * - clock + * - timer + * - semaphore + * - message + * - event + * - signal + * - partition + * - region + * - dual ported memory + * - I/O + * - fatal error + * - rate monotonic + * - user extensions + * - multiprocessing + * + * @section RTEMSOverviewSecUserCustomization User Customization and Extensibility + * + * As 32-bit microprocessors have decreased in cost, they have become + * increasingly common in a variety of embedded systems. A wide range of custom + * and general-purpose processor boards are based on various 32-bit + * processors. RTEMS was designed to make no assumptions concerning the + * characteristics of individual microprocessor families or of specific support + * hardware. In addition, RTEMS allows the system developer a high degree of + * freedom in customizing and extending its features. + * + * RTEMS assumes the existence of a supported microprocessor and sufficient + * memory for both RTEMS and the real-time application. Board dependent + * components such as clocks, interrupt controllers, or I/O devices can be + * easily integrated with RTEMS. The customization and extensibility features + * allow RTEMS to efficiently support as many environments as possible. + * + * @section RTEMSOverviewSecPortability Portability + * + * The issue of portability was the major factor in the creation of RTEMS. + * Since RTEMS is designed to isolate the hardware dependencies in the specific + * board support packages, the real-time application should be easily ported to + * any other processor. The use of RTEMS allows the development of real-time + * applications which can be completely independent of a particular + * microprocessor architecture. + * + * @section RTEMSOverviewSecMemoryRequirements Memory Requirements + * + * Since memory is a critical resource in many real-time embedded systems, + * RTEMS was specifically designed to automatically leave out all services that + * are not required from the run-time environment. Features such as networking, + * various fileystems, and many other features are completely optional. This + * allows the application designer the flexibility to tailor RTEMS to most + * efficiently meet system requirements while still satisfying even the most + * stringent memory constraints. As a result, the size of the RTEMS executive + * is application dependent. + * + * RTEMS requires RAM to manage each instance of an RTEMS object that is + * created. Thus the more RTEMS objects an application needs, the more memory + * that must be reserved. See Configuring a System Determining Memory + * Requirements for more details. + * + * @todo Link to Configuring a SystemDetermining Memory Requirements + * + * RTEMS utilizes memory for both code and data space. Although RTEMS' data + * space must be in RAM, its code space can be located in either ROM or RAM. + * + * @section RTEMSOverviewSecAudience Audience + * + * This manual was written for experienced real-time software developers. + * Although some background is provided, it is assumed that the reader is + * familiar with the concepts of task management as well as intertask + * communication and synchronization. Since directives, user related data + * structures, and examples are presented in C, a basic understanding of the C + * programming language is required to fully understand the material presented. + * However, because of the similarity of the Ada and C RTEMS implementations, + * users will find that the use and behavior of the two implementations is very + * similar. A working knowledge of the target processor is helpful in + * understanding some of RTEMS' features. A thorough understanding of the + * executive cannot be obtained without studying the entire manual because many + * of RTEMS' concepts and features are interrelated. Experienced RTEMS users + * will find that the manual organization facilitates its use as a reference + * document. + * + */ + +/** + * @addtogroup ClassicRTEMS + * + * The facilities provided by RTEMS are built upon a foundation of very + * powerful concepts. These concepts must be understood before the application + * developer can efficiently utilize RTEMS. The purpose of this chapter is to + * familiarize one with these concepts. + * + * @section ClassicRTEMSSecObjects Objects + * + * RTEMS provides directives which can be used to dynamically create, delete, + * and manipulate a set of predefined object types. These types include tasks, + * message queues, semaphores, memory regions, memory partitions, timers, + * ports, and rate monotonic periods. The object-oriented nature of RTEMS + * encourages the creation of modular applications built upon re-usable + * "building block" routines. + * + * All objects are created on the local node as required by the application and + * have an RTEMS assigned ID. All objects have a user-assigned name. Although a + * relationship exists between an object's name and its RTEMS assigned ID, the + * name and ID are not identical. Object names are completely arbitrary and + * selected by the user as a meaningful "tag" which may commonly reflect the + * object's use in the application. Conversely, object IDs are designed to + * facilitate efficient object manipulation by the executive. + * + * @subsection ClassicRTEMSSubSecObjectNames Object Names + * + * An object name is an unsigned 32-bit entity associated with the + * object by the user. The data type @ref rtems_name is used to store object names. + * + * Although not required by RTEMS, object names are often composed of four + * ASCII characters which help identify that object. For example, a task which + * causes a light to blink might be called "LITE". The rtems_build_name() + * routine is provided to build an object name from four ASCII characters. The + * following example illustrates this: + * + * @code + * rtems_name my_name = rtems_build_name('L', 'I', 'T', 'E'); + * @endcode + * + * However, it is not required that the application use ASCII characters to + * build object names. For example, if an application requires one-hundred + * tasks, it would be difficult to assign meaningful ASCII names to each task. + * A more convenient approach would be to name them the binary values one + * through one-hundred, respectively. + * + * RTEMS provides a helper routine, rtems_object_get_name(), which can be used to + * obtain the name of any RTEMS object using just its ID. This routine attempts + * to convert the name into a printable string. + * + * @subsection ClassicRTEMSSubSecObjectIdentifiers Object Identifiers + * + * An object ID is a unique unsigned integer value which uniquely identifies an + * object instance. Object IDs are passed as arguments to many directives in + * RTEMS and RTEMS translates the ID to an internal object pointer. The + * efficient manipulation of object IDs is critical to the performance of RTEMS + * services. Because of this, there are two object ID formats defined. Each + * target architecture specifies which format it will use. There is a 32-bit + * format which is used for most of the supported architectures and supports + * multiprocessor configurations. There is also a simpler 16-bit format which + * is appropriate for smaller target architectures and does not support + * multiprocessor configurations. + * + * @subsubsection ClassicRTEMSSubSec32BitObjectIdentifierFormat 32-Bit Object Identifier Format + * + * The 32-bit format for an object ID is composed of four parts: API, + * object class, node, and index. The data type @ref rtems_id is used to store + * object IDs. + * + * <table> + * <tr> + * <th>Bits</th> + * <td>31</td><td>30</td><td>29</td><td>28</td><td>27</td><td>26</td><td>25</td><td>24</td> + * <td>23</td><td>22</td><td>21</td><td>20</td><td>19</td><td>18</td><td>17</td><td>16</td> + * <td>15</td><td>14</td><td>13</td><td>12</td><td>11</td><td>10</td><td>09</td><td>08</td> + * <td>07</td><td>06</td><td>05</td><td>04</td><td>03</td><td>02</td><td>01</td><td>00</td> + * </tr> + * <tr> + * <th>Contents</th> + * <td colspan=5>Class</td><td colspan=3>API</td><td colspan=8>Node</td><td colspan=16>Object Index</td> + * </tr> + * </table> + * + * The most significant five bits are the object class. The next three bits + * indicate the API to which the object class belongs. The next eight bits + * (16 .. 23) are the number of the node on which this object was created. The + * node number is always one (1) in a single processor system. The least + * significant 16-bits form an identifier within a particular object type. + * This identifier, called the object index, ranges in value from one to the + * maximum number of objects configured for this object type. + * + * @subsubsection ClassicRTEMSSubSec16BitObjectIdentifierFormat 16-Bit Object Identifier Format + * + * The 16-bit format for an object ID is composed of three parts: API, object + * class, and index. The data type @ref rtems_id is used to store object IDs. + * + * <table> + * <tr> + * <th>Bits</th> + * <td>15</td><td>14</td><td>13</td><td>12</td><td>11</td><td>10</td><td>09</td><td>08</td> + * <td>07</td><td>06</td><td>05</td><td>04</td><td>03</td><td>02</td><td>01</td><td>00</td> + * </tr> + * <tr> + * <th>Contents</th> + * <td colspan=5>Class</td><td colspan=3>API</td><td colspan=8>Object Index</td> + * </tr> + * </table> + * + * The 16-bit format is designed to be as similar as possible to the 32-bit + * format. The differences are limited to the eliminatation of the node field + * and reduction of the index field from 16-bits to 8-bits. Thus the 16-bit + * format only supports up to 255 object instances per API/Class combination + * and single processor systems. As this format is typically utilized by 16-bit + * processors with limited address space, this is more than enough object + * instances. + * + * @subsection ClassicRTEMSSubSecObjectIdentiferDescription Object Identifer Description + * + * The components of an object ID make it possible to quickly locate any object + * in even the most complicated multiprocessor system. Object ID's are + * associated with an object by RTEMS when the object is created and the + * corresponding ID is returned by the appropriate object create directive. The + * object ID is required as input to all directives involving objects, except + * those which create an object or obtain the ID of an object. + * + * The object identification directives can be used to dynamically obtain a + * particular object's ID given its name. This mapping is accomplished by + * searching the name table associated with this object type. If the name is + * non-unique, then the ID associated with the first occurrence of the name + * will be returned to the application. Since object IDs are returned when the + * object is created, the object identification directives are not necessary in + * a properly designed single processor application. + * + * In addition, services are provided to portably examine the subcomponents of + * an RTEMS ID. These services are described in detail later in this manual but + * are prototyped as follows: + * + * - rtems_object_id_get_api() + * - rtems_object_id_get_class() + * - rtems_object_id_get_node() + * - rtems_object_id_get_index() + * + * An object control block is a data structure defined by RTEMS which contains + * the information necessary to manage a particular object type. For efficiency + * reasons, the format of each object type's control block is different. + * However, many of the fields are similar in function. The number of each type + * of control block is application dependent and determined by the values + * specified in the user's Configuration Table. An object control block is + * allocated at object create time and freed when the object is deleted. With + * the exception of user extension routines, object control blocks are not + * directly manipulated by user applications. + * + * @section ClassicRTEMSSecComSync Communication and Synchronization + * + * In real-time multitasking applications, the ability for cooperating + * execution threads to communicate and synchronize with each other is + * imperative. A real-time executive should provide an application with the + * following capabilities + * + * - data transfer between cooperating tasks, + * - data transfer between tasks and ISRs, + * - synchronization of cooperating tasks, and + * - synchronization of tasks and ISRs. + * + * Most RTEMS managers can be used to provide some form of communication and/or + * synchronization. However, managers dedicated specifically to communication + * and synchronization provide well established mechanisms which directly map + * to the application's varying needs. This level of flexibility allows the + * application designer to match the features of a particular manager with the + * complexity of communication and synchronization required. The following + * managers were specifically designed for communication and synchronization: + * + * - @ref ClassicSem + * - @ref ClassicMessageQueue + * - @ref ClassicEvent + * - @ref ClassicSignal + * + * The semaphore manager supports mutual exclusion involving the + * synchronization of access to one or more shared user resources. Binary + * semaphores may utilize the optional priority inheritance algorithm to avoid + * the problem of priority inversion. The message manager supports both + * communication and synchronization, while the event manager primarily + * provides a high performance synchronization mechanism. The signal manager + * supports only asynchronous communication and is typically used for exception + * handling. + * + * @section ClassicRTEMSSecTime Time + * + * The development of responsive real-time applications requires an + * understanding of how RTEMS maintains and supports time-related operations. + * The basic unit of time in RTEMS is known as a tick. The frequency of clock + * ticks is completely application dependent and determines the granularity and + * accuracy of all interval and calendar time operations. + * + * By tracking time in units of ticks, RTEMS is capable of supporting interval + * timing functions such as task delays, timeouts, timeslicing, the delayed + * execution of timer service routines, and the rate monotonic scheduling of + * tasks. An interval is defined as a number of ticks relative to the current + * time. For example, when a task delays for an interval of ten ticks, it is + * implied that the task will not execute until ten clock ticks have occurred. + * All intervals are specified using data type @ref rtems_interval. + * + * A characteristic of interval timing is that the actual interval period may + * be a fraction of a tick less than the interval requested. This occurs + * because the time at which the delay timer is set up occurs at some time + * between two clock ticks. Therefore, the first countdown tick occurs in less + * than the complete time interval for a tick. This can be a problem if the + * clock granularity is large. + * + * The rate monotonic scheduling algorithm is a hard real-time scheduling + * methodology. This methodology provides rules which allows one to guarantee + * that a set of independent periodic tasks will always meet their deadlines -- + * even under transient overload conditions. The rate monotonic manager + * provides directives built upon the Clock Manager's interval timer support + * routines. + * + * Interval timing is not sufficient for the many applications which require + * that time be kept in wall time or true calendar form. Consequently, RTEMS + * maintains the current date and time. This allows selected time operations to + * be scheduled at an actual calendar date and time. For example, a task could + * request to delay until midnight on New Year's Eve before lowering the ball + * at Times Square. The data type @ref rtems_time_of_day is used to specify + * calendar time in RTEMS services. See Clock Manager Time and Date Data + * Structures. + * + * @todo Link to Clock Manager Time and Date Data Structures + * + * Obviously, the directives which use intervals or wall time cannot operate + * without some external mechanism which provides a periodic clock tick. This + * clock tick is typically provided by a real time clock or counter/timer + * device. + * + * @section ClassicRTEMSSecMemoryManagement Memory Management + * + * RTEMS memory management facilities can be grouped into two classes: dynamic + * memory allocation and address translation. Dynamic memory allocation is + * required by applications whose memory requirements vary through the + * application's course of execution. Address translation is needed by + * applications which share memory with another CPU or an intelligent + * Input/Output processor. The following RTEMS managers provide facilities to + * manage memory: + * + * - @ref ClassicRegion + * - @ref ClassicPart + * - @ref ClassicDPMEM + * + * RTEMS memory management features allow an application to create simple + * memory pools of fixed size buffers and/or more complex memory pools of + * variable size segments. The partition manager provides directives to manage + * and maintain pools of fixed size entities such as resource control blocks. + * Alternatively, the region manager provides a more general purpose memory + * allocation scheme that supports variable size blocks of memory which are + * dynamically obtained and freed by the application. The dual-ported memory + * manager provides executive support for address translation between internal + * and external dual-ported RAM address space. + */ + +/** + * @addtogroup ClassicTasks + * + * @section ClassicTasksSecTaskDefinition Task Definition + * + * Many definitions of a task have been proposed in computer literature. + * Unfortunately, none of these definitions encompasses all facets of the + * concept in a manner which is operating system independent. Several of the + * more common definitions are provided to enable each user to select a + * definition which best matches their own experience and understanding of the + * task concept: + * + * - a "dispatchable" unit. + * - an entity to which the processor is allocated. + * - an atomic unit of a real-time, multiprocessor system. + * - single threads of execution which concurrently compete for resources. + * - a sequence of closely related computations which can execute concurrently + * with other computational sequences. + * + * From RTEMS' perspective, a task is the smallest thread of execution which + * can compete on its own for system resources. A task is manifested by the + * existence of a task control block (TCB). + * + * @section ClassicTasksSecTaskControlBlock Task Control Block + * + * The Task Control Block (TCB) is an RTEMS defined data structure which + * contains all the information that is pertinent to the execution of a task. + * During system initialization, RTEMS reserves a TCB for each task configured. + * A TCB is allocated upon creation of the task and is returned to the TCB free + * list upon deletion of the task. + * + * The TCB's elements are modified as a result of system calls made by the + * application in response to external and internal stimuli. TCBs are the only + * RTEMS internal data structure that can be accessed by an application via + * user extension routines. The TCB contains a task's name, ID, current + * priority, current and starting states, execution mode, set of notepad + * locations, TCB user extension pointer, scheduling control structures, as + * well as data required by a blocked task. + * + * A task's context is stored in the TCB when a task switch occurs. When the + * task regains control of the processor, its context is restored from the TCB. + * When a task is restarted, the initial state of the task is restored from the + * starting context area in the task's TCB. + * + * @section ClassicTasksSecTaskStates Task States + * + * A task may exist in one of the following five states: + * + * - executing - Currently scheduled to the CPU + * - ready - May be scheduled to the CPU + * - blocked - Unable to be scheduled to the CPU + * - dormant - Created task that is not started + * - non-existent - Uncreated or deleted task + * + * An active task may occupy the executing, ready, blocked or dormant state, + * otherwise the task is considered non-existent. One or more tasks may be + * active in the system simultaneously. Multiple tasks communicate, + * synchronize, and compete for system resources with each other via system + * calls. The multiple tasks appear to execute in parallel, but actually each + * is dispatched to the CPU for periods of time determined by the RTEMS + * scheduling algorithm. The scheduling of a task is based on its current state + * and priority. + * + * @section ClassicTasksSecTaskPriority Task Priority + * + * A task's priority determines its importance in relation to the other tasks + * executing on the same processor. RTEMS supports 255 levels of priority + * ranging from 1 to 255. The data type rtems_task_priority() is used to store + * task priorities. + * + * Tasks of numerically smaller priority values are more important tasks than + * tasks of numerically larger priority values. For example, a task at priority + * level 5 is of higher privilege than a task at priority level 10. There is no + * limit to the number of tasks assigned to the same priority. + * + * Each task has a priority associated with it at all times. The initial value + * of this priority is assigned at task creation time. The priority of a task + * may be changed at any subsequent time. + * + * Priorities are used by the scheduler to determine which ready task will be + * allowed to execute. In general, the higher the logical priority of a task, + * the more likely it is to receive processor execution time. + * + * @section ClassicTasksSecTaskMode Task Mode + * + * A task's execution mode is a combination of the following four components: + * + * - preemption + * - ASR processing + * - timeslicing + * - interrupt level + * + * It is used to modify RTEMS' scheduling process and to alter the execution + * environment of the task. The data type rtems_task_mode() is used to manage + * the task execution mode. + * + * The preemption component allows a task to determine when control of the + * processor is relinquished. If preemption is disabled (@c + * RTEMS_NO_PREEMPT), the task will retain control of the + * processor as long as it is in the executing state -- even if a higher + * priority task is made ready. If preemption is enabled (@c RTEMS_PREEMPT) + * and a higher priority task is made ready, then the processor will be + * taken away from the current task immediately and given to the higher + * priority task. + * + * The timeslicing component is used by the RTEMS scheduler to determine how + * the processor is allocated to tasks of equal priority. If timeslicing is + * enabled (@c RTEMS_TIMESLICE), then RTEMS will limit the amount of time the + * task can execute before the processor is allocated to another ready task of + * equal priority. The length of the timeslice is application dependent and + * specified in the Configuration Table. If timeslicing is disabled (@c + * RTEMS_NO_TIMESLICE), then the task will be allowed to + * execute until a task of higher priority is made ready. If @c + * RTEMS_NO_PREEMPT is selected, then the timeslicing component is ignored by + * the scheduler. + * + * The asynchronous signal processing component is used to determine when + * received signals are to be processed by the task. If signal processing is + * enabled (@c RTEMS_ASR), then signals sent to the task will be processed + * the next time the task executes. If signal processing is disabled (@c + * RTEMS_NO_ASR), then all signals received by the task will + * remain posted until signal processing is enabled. This component affects + * only tasks which have established a routine to process asynchronous signals. + * + * The interrupt level component is used to determine which interrupts will be + * enabled when the task is executing. @c RTEMS_INTERRUPT_LEVEL(n) specifies + * that the task will execute at interrupt level n. + * + * - @ref RTEMS_PREEMPT - enable preemption (default) + * - @ref RTEMS_NO_PREEMPT - disable preemption + * - @ref RTEMS_NO_TIMESLICE - disable timeslicing (default) + * - @ref RTEMS_TIMESLICE - enable timeslicing + * - @ref RTEMS_ASR - enable ASR processing (default) + * - @ref RTEMS_NO_ASR - disable ASR processing + * - @ref RTEMS_INTERRUPT_LEVEL(0) - enable all interrupts (default) + * - @ref RTEMS_INTERRUPT_LEVEL(n) - execute at interrupt level n + * + * The set of default modes may be selected by specifying the @ref + * RTEMS_DEFAULT_MODES constant. + * + * @section ClassicTasksSecAccessingTaskArguments Accessing Task Arguments + * + * All RTEMS tasks are invoked with a single argument which is specified when + * they are started or restarted. The argument is commonly used to communicate + * startup information to the task. The simplest manner in which to define a + * task which accesses it argument is: + * + * @code + * rtems_task user_task( + * rtems_task_argument argument + * ); + * @endcode + * + * Application tasks requiring more information may view this single argument + * as an index into an array of parameter blocks. + * + * @section ClassicTasksSecFloatingPointConsiderations Floating Point Considerations + * + * Creating a task with the @ref RTEMS_FLOATING_POINT attribute flag results in + * additional memory being allocated for the TCB to store the state of the + * numeric coprocessor during task switches. This additional memory is NOT + * allocated for @ref RTEMS_NO_FLOATING_POINT tasks. Saving and restoring the + * context of a @c RTEMS_FLOATING_POINT task takes longer than that of a @c + * RTEMS_NO_FLOATING_POINT task because of the relatively large amount of time + * required for the numeric coprocessor to save or restore its computational + * state. + * + * Since RTEMS was designed specifically for embedded military applications + * which are floating point intensive, the executive is optimized to avoid + * unnecessarily saving and restoring the state of the numeric coprocessor. The + * state of the numeric coprocessor is only saved when a @c + * RTEMS_FLOATING_POINT task is dispatched and that task was not the last task + * to utilize the coprocessor. In a system with only one @c + * RTEMS_FLOATING_POINT task, the state of the numeric coprocessor will never + * be saved or restored. + * + * Although the overhead imposed by @c RTEMS_FLOATING_POINT tasks is minimal, + * some applications may wish to completely avoid the overhead associated with + * @c RTEMS_FLOATING_POINT tasks and still utilize a numeric coprocessor. By + * preventing a task from being preempted while performing a sequence of + * floating point operations, a @c RTEMS_NO_FLOATING_POINT task can utilize + * the numeric coprocessor without incurring the overhead of a @c + * RTEMS_FLOATING_POINT context switch. This approach also avoids the + * allocation of a floating point context area. However, if this approach is + * taken by the application designer, NO tasks should be created as @c + * RTEMS_FLOATING_POINT tasks. Otherwise, the floating point context will not + * be correctly maintained because RTEMS assumes that the state of the numeric + * coprocessor will not be altered by @c RTEMS_NO_FLOATING_POINT tasks. + * + * If the supported processor type does not have hardware floating capabilities + * or a standard numeric coprocessor, RTEMS will not provide built-in support + * for hardware floating point on that processor. In this case, all tasks are + * considered @c RTEMS_NO_FLOATING_POINT whether created as @c + * RTEMS_FLOATING_POINT or @c RTEMS_NO_FLOATING_POINT tasks. A floating point + * emulation software library must be utilized for floating point operations. + * + * On some processors, it is possible to disable the floating point unit + * dynamically. If this capability is supported by the target processor, then + * RTEMS will utilize this capability to enable the floating point unit only + * for tasks which are created with the @c RTEMS_FLOATING_POINT attribute. + * The consequence of a @c RTEMS_NO_FLOATING_POINT task attempting to access + * the floating point unit is CPU dependent but will generally result in an + * exception condition. + * + * @section ClassicTasksSecPerTaskVariables Per Task Variables + * + * Per task variables are used to support global variables whose value may be + * unique to a task. After indicating that a variable should be treated as + * private (i.e. per-task) the task can access and modify the variable, but the + * modifications will not appear to other tasks, and other tasks' modifications + * to that variable will not affect the value seen by the task. This is + * accomplished by saving and restoring the variable's value each time a task + * switch occurs to or from the calling task. + * + * The value seen by other tasks, including those which have not added the + * variable to their set and are thus accessing the variable as a common + * location shared among tasks, can not be affected by a task once it has added + * a variable to its local set. Changes made to the variable by other tasks + * will not affect the value seen by a task which has added the variable to its + * private set. + * + * This feature can be used when a routine is to be spawned repeatedly as + * several independent tasks. Although each task will have its own stack, and + * thus separate stack variables, they will all share the same static and + * global variables. To make a variable not shareable (i.e. a "global" variable + * that is specific to a single task), the tasks can call + * rtems_task_variable_add() to make a separate copy of the variable for each + * task, but all at the same physical address. + * + * Task variables increase the context switch time to and from the tasks that + * own them so it is desirable to minimize the number of task variables. One + * efficient method is to have a single task variable that is a pointer to a + * dynamically allocated structure containing the task's private "global" data. + * + * A critical point with per-task variables is that each task must separately + * request that the same global variable is per-task private. + * + * @section ClassicTasksSecBuildingTaskAttributeSet Building a Task Attribute Set + * + * In general, an attribute set is built by a bitwise OR of the desired + * components. The set of valid task attribute components is listed below: + * + * - @ref RTEMS_NO_FLOATING_POINT - does not use coprocessor (default) + * - @ref RTEMS_FLOATING_POINT - uses numeric coprocessor + * - @ref RTEMS_LOCAL - local task (default) + * - @ref RTEMS_GLOBAL - global task + * + * Attribute values are specifically designed to be mutually exclusive, + * therefore bitwise OR and addition operations are equivalent as long as each + * attribute appears exactly once in the component list. A component listed as + * a default is not required to appear in the component list, although it is a + * good programming practice to specify default components. If all defaults are + * desired, then @ref RTEMS_DEFAULT_ATTRIBUTES should be used. This example + * demonstrates the attribute_set parameter needed to create a local task which + * utilizes the numeric coprocessor. The attribute_set parameter could be @c + * RTEMS_FLOATING_POINT or @c RTEMS_LOCAL | @c RTEMS_FLOATING_POINT. The + * attribute_set parameter can be set to @c RTEMS_FLOATING_POINT because @c + * RTEMS_LOCAL is the default for all created tasks. If the task were global + * and used the numeric coprocessor, then the attribute_set parameter would be + * @c RTEMS_GLOBAL | @c RTEMS_FLOATING_POINT. + * + * @section ClassicTasksSecBuildingModeAndMask Building a Mode and Mask + * + * In general, a mode and its corresponding mask is built by a bitwise OR of + * the desired components. The set of valid mode constants and each mode's + * corresponding mask constant is listed below: + * + * <table> + * <tr><th>Mode Constant</th><th>Mask Constant</th><th>Description</th></tr> + * <tr><td>@ref RTEMS_PREEMPT</td><td>@ref RTEMS_PREEMPT_MASK</td><td>enables preemption</td></tr> + * <tr><td>@ref RTEMS_NO_PREEMPT</td><td>@ref RTEMS_PREEMPT_MASK</td><td>disables preemption</td></tr> + * <tr><td>@ref RTEMS_NO_TIMESLICE</td><td>@ref RTEMS_TIMESLICE_MASK</td><td>disables timeslicing</td></tr> + * <tr><td>@ref RTEMS_TIMESLICE</td><td>@ref RTEMS_TIMESLICE_MASK</td><td>enables timeslicing</td></tr> + * <tr><td>@ref RTEMS_ASR</td><td>@ref RTEMS_ASR_MASK</td><td>enables ASR processing</td></tr> + * <tr><td>@ref RTEMS_NO_ASR</td><td>@ref RTEMS_ASR_MASK</td><td>disables ASR processing</td></tr> + * <tr><td>@ref RTEMS_INTERRUPT_LEVEL(0)</td><td>@ref RTEMS_INTERRUPT_MASK</td><td>enables all interrupts</td></tr> + * <tr><td>@ref RTEMS_INTERRUPT_LEVEL(n)</td><td>@ref RTEMS_INTERRUPT_MASK</td><td>sets interrupts level n</td></tr> + * </table> + * + * Mode values are specifically designed to be mutually exclusive, therefore + * bitwise OR and addition operations are equivalent as long as each mode + * appears exactly once in the component list. A mode component listed as a + * default is not required to appear in the mode component list, although it is + * a good programming practice to specify default components. If all defaults + * are desired, the mode @ref RTEMS_DEFAULT_MODES and the mask @ref + * RTEMS_ALL_MODE_MASKS should be used. + * + * The following example demonstrates the mode and mask parameters used with + * the rtems_task_mode() directive to place a task at interrupt level 3 and + * make it non-preemptible. The mode should be set to @c + * RTEMS_INTERRUPT_LEVEL(3) | @c RTEMS_NO_PREEMPT to indicate the desired + * preemption mode and interrupt level, while the mask parameter should be set + * to @c RTEMS_INTERRUPT_MASK | @c RTEMS_PREEMPT_MASK to indicate that + * the calling task's interrupt level and preemption mode are being altered. + */ + + /** + * @defgroup LocalPackages Local Packages + * + * @brief Local packages. + */ diff --git a/cpukit/rtems/preinstall.am b/cpukit/rtems/preinstall.am new file mode 100644 index 0000000000..5d32ad7413 --- /dev/null +++ b/cpukit/rtems/preinstall.am @@ -0,0 +1,234 @@ +## Automatically generated by ampolish3 - Do not edit + +if AMPOLISH3 +$(srcdir)/preinstall.am: Makefile.am + $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am +endif + +PREINSTALL_DIRS = +DISTCLEANFILES = $(PREINSTALL_DIRS) + +all-am: $(PREINSTALL_FILES) + +PREINSTALL_FILES = +CLEANFILES = $(PREINSTALL_FILES) + +$(PROJECT_INCLUDE)/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE) + @: > $(PROJECT_INCLUDE)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp) + +$(PROJECT_INCLUDE)/rtems.h: include/rtems.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems.h + +$(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/rtems/rtems + @: > $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + +$(PROJECT_INCLUDE)/rtems/rtems/asr.h: include/rtems/rtems/asr.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/asr.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/asr.h + +$(PROJECT_INCLUDE)/rtems/rtems/attr.h: include/rtems/rtems/attr.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/attr.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/attr.h + +$(PROJECT_INCLUDE)/rtems/rtems/barrier.h: include/rtems/rtems/barrier.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/barrier.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/barrier.h + +$(PROJECT_INCLUDE)/rtems/rtems/cache.h: include/rtems/rtems/cache.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/cache.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/cache.h + +$(PROJECT_INCLUDE)/rtems/rtems/clock.h: include/rtems/rtems/clock.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/clock.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/clock.h + +$(PROJECT_INCLUDE)/rtems/rtems/config.h: include/rtems/rtems/config.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/config.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/config.h + +$(PROJECT_INCLUDE)/rtems/rtems/dpmem.h: include/rtems/rtems/dpmem.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/dpmem.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/dpmem.h + +$(PROJECT_INCLUDE)/rtems/rtems/event.h: include/rtems/rtems/event.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/event.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/event.h + +$(PROJECT_INCLUDE)/rtems/rtems/eventset.h: include/rtems/rtems/eventset.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/eventset.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/eventset.h + +$(PROJECT_INCLUDE)/rtems/rtems/intr.h: include/rtems/rtems/intr.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/intr.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/intr.h + +$(PROJECT_INCLUDE)/rtems/rtems/message.h: include/rtems/rtems/message.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/message.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/message.h + +$(PROJECT_INCLUDE)/rtems/rtems/modes.h: include/rtems/rtems/modes.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/modes.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/modes.h + +$(PROJECT_INCLUDE)/rtems/rtems/object.h: include/rtems/rtems/object.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/object.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/object.h + +$(PROJECT_INCLUDE)/rtems/rtems/options.h: include/rtems/rtems/options.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/options.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/options.h + +$(PROJECT_INCLUDE)/rtems/rtems/part.h: include/rtems/rtems/part.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/part.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/part.h + +$(PROJECT_INCLUDE)/rtems/rtems/ratemon.h: include/rtems/rtems/ratemon.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/ratemon.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/ratemon.h + +$(PROJECT_INCLUDE)/rtems/rtems/region.h: include/rtems/rtems/region.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/region.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/region.h + +$(PROJECT_INCLUDE)/rtems/rtems/rtemsapi.h: include/rtems/rtems/rtemsapi.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/rtemsapi.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/rtemsapi.h + +$(PROJECT_INCLUDE)/rtems/rtems/sem.h: include/rtems/rtems/sem.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/sem.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/sem.h + +$(PROJECT_INCLUDE)/rtems/rtems/signal.h: include/rtems/rtems/signal.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/signal.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/signal.h + +$(PROJECT_INCLUDE)/rtems/rtems/status.h: include/rtems/rtems/status.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/status.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/status.h + +$(PROJECT_INCLUDE)/rtems/rtems/support.h: include/rtems/rtems/support.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/support.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/support.h + +$(PROJECT_INCLUDE)/rtems/rtems/tasks.h: include/rtems/rtems/tasks.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/tasks.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/tasks.h + +$(PROJECT_INCLUDE)/rtems/rtems/timer.h: include/rtems/rtems/timer.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/timer.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/timer.h + +$(PROJECT_INCLUDE)/rtems/rtems/types.h: include/rtems/rtems/types.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/types.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/types.h + +$(PROJECT_INCLUDE)/rtems/rtems/mainpage.h: mainpage.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/mainpage.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/mainpage.h + +if HAS_MP +$(PROJECT_INCLUDE)/rtems/rtems/eventmp.h: include/rtems/rtems/eventmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/eventmp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/eventmp.h + +$(PROJECT_INCLUDE)/rtems/rtems/mp.h: include/rtems/rtems/mp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/mp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/mp.h + +$(PROJECT_INCLUDE)/rtems/rtems/msgmp.h: include/rtems/rtems/msgmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/msgmp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/msgmp.h + +$(PROJECT_INCLUDE)/rtems/rtems/partmp.h: include/rtems/rtems/partmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/partmp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/partmp.h + +$(PROJECT_INCLUDE)/rtems/rtems/regionmp.h: include/rtems/rtems/regionmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/regionmp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/regionmp.h + +$(PROJECT_INCLUDE)/rtems/rtems/semmp.h: include/rtems/rtems/semmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/semmp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/semmp.h + +$(PROJECT_INCLUDE)/rtems/rtems/signalmp.h: include/rtems/rtems/signalmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/signalmp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/signalmp.h + +$(PROJECT_INCLUDE)/rtems/rtems/taskmp.h: include/rtems/rtems/taskmp.h $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/taskmp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/taskmp.h +endif +$(PROJECT_INCLUDE)/rtems/rtems/asr.inl: inline/rtems/rtems/asr.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/asr.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/asr.inl + +$(PROJECT_INCLUDE)/rtems/rtems/attr.inl: inline/rtems/rtems/attr.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/attr.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/attr.inl + +$(PROJECT_INCLUDE)/rtems/rtems/barrier.inl: inline/rtems/rtems/barrier.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/barrier.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/barrier.inl + +$(PROJECT_INCLUDE)/rtems/rtems/dpmem.inl: inline/rtems/rtems/dpmem.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/dpmem.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/dpmem.inl + +$(PROJECT_INCLUDE)/rtems/rtems/event.inl: inline/rtems/rtems/event.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/event.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/event.inl + +$(PROJECT_INCLUDE)/rtems/rtems/eventset.inl: inline/rtems/rtems/eventset.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/eventset.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/eventset.inl + +$(PROJECT_INCLUDE)/rtems/rtems/message.inl: inline/rtems/rtems/message.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/message.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/message.inl + +$(PROJECT_INCLUDE)/rtems/rtems/modes.inl: inline/rtems/rtems/modes.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/modes.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/modes.inl + +$(PROJECT_INCLUDE)/rtems/rtems/options.inl: inline/rtems/rtems/options.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/options.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/options.inl + +$(PROJECT_INCLUDE)/rtems/rtems/part.inl: inline/rtems/rtems/part.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/part.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/part.inl + +$(PROJECT_INCLUDE)/rtems/rtems/ratemon.inl: inline/rtems/rtems/ratemon.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/ratemon.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/ratemon.inl + +$(PROJECT_INCLUDE)/rtems/rtems/region.inl: inline/rtems/rtems/region.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/region.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/region.inl + +$(PROJECT_INCLUDE)/rtems/rtems/sem.inl: inline/rtems/rtems/sem.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/sem.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/sem.inl + +$(PROJECT_INCLUDE)/rtems/rtems/status.inl: inline/rtems/rtems/status.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/status.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/status.inl + +$(PROJECT_INCLUDE)/rtems/rtems/support.inl: inline/rtems/rtems/support.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/support.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/support.inl + +$(PROJECT_INCLUDE)/rtems/rtems/tasks.inl: inline/rtems/rtems/tasks.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/tasks.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/tasks.inl + +$(PROJECT_INCLUDE)/rtems/rtems/timer.inl: inline/rtems/rtems/timer.inl $(PROJECT_INCLUDE)/rtems/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems/timer.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems/timer.inl + diff --git a/cpukit/rtems/src/attr.c b/cpukit/rtems/src/attr.c new file mode 100644 index 0000000000..2312d36bb5 --- /dev/null +++ b/cpukit/rtems/src/attr.c @@ -0,0 +1,31 @@ +/* + * Body for Attribute Routines + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/stack.h> +#include <rtems/rtems/modes.h> + +uint32_t rtems_interrupt_mask = RTEMS_INTERRUPT_MASK; + +rtems_attribute rtems_interrupt_level_attribute( + uint32_t level +) +{ + return RTEMS_INTERRUPT_LEVEL(level); +} diff --git a/cpukit/rtems/src/barrier.c b/cpukit/rtems/src/barrier.c new file mode 100644 index 0000000000..b35b5e3415 --- /dev/null +++ b/cpukit/rtems/src/barrier.c @@ -0,0 +1,65 @@ +/* + * Barrier Manager + * + * DESCRIPTION: + * + * This package is the implementation of the Barrier Manager. + * + * Directives provided are: + * + * + create a barrier + * + get an ID of a barrier + * + delete a barrier + * + acquire a barrier + * + release a barrier + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/barrier.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif + +/** + * @brief _Barrier_Manager_initialization + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Barrier_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_Barrier_Information, /* object information table */ + OBJECTS_CLASSIC_API, /* object API */ + OBJECTS_RTEMS_BARRIERS, /* object class */ + Configuration_RTEMS_API.maximum_barriers, + /* maximum objects of this class */ + sizeof( Barrier_Control ), /* size of this object's control block */ + false, /* true if the name is a string */ + RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/rtems/src/barriercreate.c b/cpukit/rtems/src/barriercreate.c new file mode 100644 index 0000000000..89c4b55ec9 --- /dev/null +++ b/cpukit/rtems/src/barriercreate.c @@ -0,0 +1,92 @@ +/* + * Barrier Manager -- Create a Barrier Instance + * + * COPYRIGHT (c) 1989-2006. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/barrier.h> + +/* + * rtems_barrier_create + * + * This directive creates a barrier. A barrier id is returned. + * + * Input parameters: + * name - user defined barrier name + * attribute_set - barrier attributes + * maximum_waiters - number of threads before automatic release + * priority_ceiling - barrier's ceiling priority + * id - pointer to barrier id + * + * Output parameters: + * id - barrier id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_barrier_create( + rtems_name name, + rtems_attribute attribute_set, + uint32_t maximum_waiters, + rtems_id *id +) +{ + Barrier_Control *the_barrier; + CORE_barrier_Attributes the_attributes; + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + + /* Initialize core barrier attributes */ + if ( _Attributes_Is_barrier_automatic( attribute_set ) ) { + the_attributes.discipline = CORE_BARRIER_AUTOMATIC_RELEASE; + if ( maximum_waiters == 0 ) + return RTEMS_INVALID_NUMBER; + } else + the_attributes.discipline = CORE_BARRIER_MANUAL_RELEASE; + the_attributes.maximum_count = maximum_waiters; + + _Thread_Disable_dispatch(); /* prevents deletion */ + + the_barrier = _Barrier_Allocate(); + + if ( !the_barrier ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + + the_barrier->attribute_set = attribute_set; + + _CORE_barrier_Initialize( &the_barrier->Barrier, &the_attributes ); + + _Objects_Open( + &_Barrier_Information, + &the_barrier->Object, + (Objects_Name) name + ); + + *id = the_barrier->Object.id; + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/barrierdata.c b/cpukit/rtems/src/barrierdata.c new file mode 100644 index 0000000000..6e4af5a4c8 --- /dev/null +++ b/cpukit/rtems/src/barrierdata.c @@ -0,0 +1,23 @@ +/* + * Barrier Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate barrier data */ +#define RTEMS_BARRIER_EXTERN + +#include <rtems/system.h> +#include <rtems/rtems/barrier.h> + diff --git a/cpukit/rtems/src/barrierdelete.c b/cpukit/rtems/src/barrierdelete.c new file mode 100644 index 0000000000..6843a1bc00 --- /dev/null +++ b/cpukit/rtems/src/barrierdelete.c @@ -0,0 +1,73 @@ +/* + * Barrier Manager -- Delete a Barrier + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/barrier.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> + +/* + * rtems_barrier_delete + * + * This directive allows a thread to delete a barrier specified by + * the barrier id. The barrier is freed back to the inactive + * barrier chain. + * + * Input parameters: + * id - barrier id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_barrier_delete( + rtems_id id +) +{ + Barrier_Control *the_barrier; + Objects_Locations location; + + the_barrier = _Barrier_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _CORE_barrier_Flush( + &the_barrier->Barrier, + NULL, + CORE_BARRIER_WAS_DELETED + ); + + _Objects_Close( &_Barrier_Information, &the_barrier->Object ); + + _Barrier_Free( the_barrier ); + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/barrierident.c b/cpukit/rtems/src/barrierident.c new file mode 100644 index 0000000000..6b90dacf70 --- /dev/null +++ b/cpukit/rtems/src/barrierident.c @@ -0,0 +1,56 @@ +/* + * Barrier Manager Name to ID + * + * COPYRIGHT (c) 1989-2006. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/barrier.h> + +/* + * rtems_barrier_ident + * + * This directive returns the system ID associated with + * the barrier name. + * + * Input parameters: + * name - user defined barrier name + * id - pointer to barrier id + * + * Output parameters: + * *id - barrier id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_barrier_ident( + rtems_name name, + rtems_id *id +) +{ + Objects_Name_or_id_lookup_errors status; + + status = _Objects_Name_to_id_u32( + &_Barrier_Information, + name, + OBJECTS_SEARCH_LOCAL_NODE, + id + ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/barrierrelease.c b/cpukit/rtems/src/barrierrelease.c new file mode 100644 index 0000000000..8bb53b8664 --- /dev/null +++ b/cpukit/rtems/src/barrierrelease.c @@ -0,0 +1,67 @@ +/* + * Barrier Manager -- Release Tasks Waitng at a Barrier + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/barrier.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> + +/* + * rtems_barrier_release + * + * This directive releases all threads waiting at a barrier. + * + * Input parameters: + * id - barrier id + * released - pointer to number of threads unblocked + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + * *released - number of threads unblocked + */ + +rtems_status_code rtems_barrier_release( + rtems_id id, + uint32_t *released +) +{ + Barrier_Control *the_barrier; + Objects_Locations location; + + if ( !released ) + return RTEMS_INVALID_ADDRESS; + + the_barrier = _Barrier_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + *released = _CORE_barrier_Release( &the_barrier->Barrier, id, NULL ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/barriertranslatereturncode.c b/cpukit/rtems/src/barriertranslatereturncode.c new file mode 100644 index 0000000000..97d7feb911 --- /dev/null +++ b/cpukit/rtems/src/barriertranslatereturncode.c @@ -0,0 +1,53 @@ +/* + * Barrier Manager -- Translate SuperCore Status + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/barrier.h> + +/* + * _Barrier_Translate_core_barrier_return_code + * + * Input parameters: + * the_barrier_status - barrier status code to translate + * + * Output parameters: + * rtems status code - translated RTEMS status code + * + */ + +rtems_status_code _Barrier_Translate_core_barrier_return_code_[] = { + RTEMS_SUCCESSFUL, /* CORE_BARRIER_STATUS_SUCCESSFUL */ + RTEMS_SUCCESSFUL, /* CORE_BARRIER_STATUS_AUTOMATICALLY_RELEASED */ + RTEMS_OBJECT_WAS_DELETED, /* CORE_BARRIER_WAS_DELETED */ + RTEMS_TIMEOUT /* CORE_BARRIER_TIMEOUT */ +}; + +rtems_status_code _Barrier_Translate_core_barrier_return_code ( + CORE_barrier_Status the_barrier_status +) +{ + /* + * Internal consistency check for bad status from SuperCore + */ + #if defined(RTEMS_DEBUG) + if ( the_barrier_status > CORE_BARRIER_STATUS_LAST ) + return RTEMS_INTERNAL_ERROR; + #endif + return _Barrier_Translate_core_barrier_return_code_[the_barrier_status]; +} diff --git a/cpukit/rtems/src/barrierwait.c b/cpukit/rtems/src/barrierwait.c new file mode 100644 index 0000000000..04b2389051 --- /dev/null +++ b/cpukit/rtems/src/barrierwait.c @@ -0,0 +1,70 @@ +/* + * Barrier Manager -- Wait at a Barrier + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/barrier.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> + +/* + * rtems_barrier_wait + * + * This directive allows a thread to wait at a barrier. + * + * Input parameters: + * id - barrier id + * timeout - number of ticks to wait (0 means wait forever) + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_barrier_wait( + rtems_id id, + rtems_interval timeout +) +{ + Barrier_Control *the_barrier; + Objects_Locations location; + + the_barrier = _Barrier_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _CORE_barrier_Wait( + &the_barrier->Barrier, + id, + true, + timeout, + NULL + ); + _Thread_Enable_dispatch(); + return _Barrier_Translate_core_barrier_return_code( + _Thread_Executing->Wait.return_code ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/clockget.c b/cpukit/rtems/src/clockget.c new file mode 100644 index 0000000000..03d8ec453f --- /dev/null +++ b/cpukit/rtems/src/clockget.c @@ -0,0 +1,76 @@ +/* + * Clock Manager + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/* + * rtems_clock_get + * + * This directive returns the current date and time. If the time has + * not been set by a tm_set then an error is returned. + * + * Input parameters: + * option - which value to return + * time_buffer - pointer to output buffer (a time and date structure + * or an interval) + * + * Output parameters: + * time_buffer - output filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_clock_get( + rtems_clock_get_options option, + void *time_buffer +) +{ + if ( !time_buffer ) + return RTEMS_INVALID_ADDRESS; + + if ( option == RTEMS_CLOCK_GET_TOD ) + return rtems_clock_get_tod( (rtems_time_of_day *)time_buffer ); + + if ( option == RTEMS_CLOCK_GET_SECONDS_SINCE_EPOCH ) + return rtems_clock_get_seconds_since_epoch((rtems_interval *)time_buffer); + + if ( option == RTEMS_CLOCK_GET_TICKS_SINCE_BOOT ) { + rtems_interval *interval = (rtems_interval *)time_buffer; + + *interval = rtems_clock_get_ticks_since_boot(); + return RTEMS_SUCCESSFUL; + } + + if ( option == RTEMS_CLOCK_GET_TICKS_PER_SECOND ) { + rtems_interval *interval = (rtems_interval *)time_buffer; + + *interval = rtems_clock_get_ticks_per_second(); + return RTEMS_SUCCESSFUL; + } + + if ( option == RTEMS_CLOCK_GET_TIME_VALUE ) + return rtems_clock_get_tod_timeval( (struct timeval *)time_buffer ); + + return RTEMS_INVALID_NUMBER; + +} diff --git a/cpukit/rtems/src/clockgetsecondssinceepoch.c b/cpukit/rtems/src/clockgetsecondssinceepoch.c new file mode 100644 index 0000000000..c8fcdc3183 --- /dev/null +++ b/cpukit/rtems/src/clockgetsecondssinceepoch.c @@ -0,0 +1,38 @@ +/* + * Clock Manager - Get Seconds Since Epoch + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +rtems_status_code rtems_clock_get_seconds_since_epoch( + rtems_interval *the_interval +) +{ + if ( !the_interval ) + return RTEMS_INVALID_ADDRESS; + + if ( !_TOD_Is_set ) + return RTEMS_NOT_DEFINED; + + *the_interval = _TOD_Seconds_since_epoch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/clockgettickspersecond.c b/cpukit/rtems/src/clockgettickspersecond.c new file mode 100644 index 0000000000..23e2dd7c39 --- /dev/null +++ b/cpukit/rtems/src/clockgettickspersecond.c @@ -0,0 +1,31 @@ +/* + * Clock Manager - Get Ticks Per Second + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +rtems_interval rtems_clock_get_ticks_per_second(void) +{ + return TOD_MICROSECONDS_PER_SECOND / + rtems_configuration_get_microseconds_per_tick(); +} diff --git a/cpukit/rtems/src/clockgettickssinceboot.c b/cpukit/rtems/src/clockgettickssinceboot.c new file mode 100644 index 0000000000..a97e40106e --- /dev/null +++ b/cpukit/rtems/src/clockgettickssinceboot.c @@ -0,0 +1,29 @@ +/* + * Clock Manager - Get Ticks Since Boot + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +rtems_interval rtems_clock_get_ticks_since_boot(void) +{ + return _Watchdog_Ticks_since_boot; +} diff --git a/cpukit/rtems/src/clockgettod.c b/cpukit/rtems/src/clockgettod.c new file mode 100644 index 0000000000..4c4e77c2ae --- /dev/null +++ b/cpukit/rtems/src/clockgettod.c @@ -0,0 +1,58 @@ +/* + * Clock Manager - rtems_clock_get_tod + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +rtems_status_code rtems_clock_get_tod( + rtems_time_of_day *time_buffer +) +{ + rtems_time_of_day *tmbuf = time_buffer; + struct tm time; + struct timeval now; + + if ( !time_buffer ) + return RTEMS_INVALID_ADDRESS; + + if ( !_TOD_Is_set ) + return RTEMS_NOT_DEFINED; + + /* Obtain the current time */ + _TOD_Get_timeval( &now ); + + /* Split it into a closer format */ + gmtime_r( &now.tv_sec, &time ); + + /* Now adjust it to the RTEMS format */ + tmbuf->year = time.tm_year + 1900; + tmbuf->month = time.tm_mon + 1; + tmbuf->day = time.tm_mday; + tmbuf->hour = time.tm_hour; + tmbuf->minute = time.tm_min; + tmbuf->second = time.tm_sec; + tmbuf->ticks = now.tv_usec / + rtems_configuration_get_microseconds_per_tick(); + + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/clockgettodtimeval.c b/cpukit/rtems/src/clockgettodtimeval.c new file mode 100644 index 0000000000..71e53ffd24 --- /dev/null +++ b/cpukit/rtems/src/clockgettodtimeval.c @@ -0,0 +1,39 @@ +/* + * Clock Manager - Get TOD in Time Value Format + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +rtems_status_code rtems_clock_get_tod_timeval( + struct timeval *time +) +{ + if ( !time ) + return RTEMS_INVALID_ADDRESS; + + if ( !_TOD_Is_set ) + return RTEMS_NOT_DEFINED; + + _TOD_Get_timeval( time ); + + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/clockgetuptime.c b/cpukit/rtems/src/clockgetuptime.c new file mode 100644 index 0000000000..b6ea0e5448 --- /dev/null +++ b/cpukit/rtems/src/clockgetuptime.c @@ -0,0 +1,51 @@ +/* + * Clock Manager - get uptime + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/timestamp.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_clock_get_uptime + * + * This directive obtains the system uptime. A timestamp is the seconds + * and nanoseconds since boot. + * + * Input parameters: + * timestamp - pointer to the timestamp + * + * Output parameters: + * *uptime - filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ +rtems_status_code rtems_clock_get_uptime( + struct timespec *uptime +) +{ + if ( !uptime ) + return RTEMS_INVALID_ADDRESS; + + _TOD_Get_uptime_as_timespec( uptime ); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/clockset.c b/cpukit/rtems/src/clockset.c new file mode 100644 index 0000000000..bb27697829 --- /dev/null +++ b/cpukit/rtems/src/clockset.c @@ -0,0 +1,61 @@ +/* + * Clock Manager + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_clock_set + * + * This directive sets the date and time for this node. + * + * Input parameters: + * time_buffer - pointer to the time and date structure + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_clock_set( + rtems_time_of_day *time_buffer +) +{ + struct timespec newtime; + + if ( !time_buffer ) + return RTEMS_INVALID_ADDRESS; + + if ( _TOD_Validate( time_buffer ) ) { + newtime.tv_sec = _TOD_To_seconds( time_buffer ); + newtime.tv_nsec = time_buffer->ticks * + rtems_configuration_get_nanoseconds_per_tick(); + + _Thread_Disable_dispatch(); + _TOD_Set( &newtime ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + return RTEMS_INVALID_CLOCK; +} diff --git a/cpukit/rtems/src/clocksetnsecshandler.c b/cpukit/rtems/src/clocksetnsecshandler.c new file mode 100644 index 0000000000..8e4d0b113e --- /dev/null +++ b/cpukit/rtems/src/clocksetnsecshandler.c @@ -0,0 +1,49 @@ +/* + * Clock Manager + * + * COPYRIGHT (c) 1989-2006. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_clock_set_nanoseconds_extension + * + * This directive sets the BSP provided nanoseconds since last tick + * extension. + * + * Input parameters: + * routine - pointer to the extension routine + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ +rtems_status_code rtems_clock_set_nanoseconds_extension( + rtems_nanoseconds_extension_routine routine +) +{ + if ( !routine ) + return RTEMS_INVALID_ADDRESS; + + _Watchdog_Nanoseconds_since_tick_handler = routine; + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/clocktick.c b/cpukit/rtems/src/clocktick.c new file mode 100644 index 0000000000..f02f48fb45 --- /dev/null +++ b/cpukit/rtems/src/clocktick.c @@ -0,0 +1,55 @@ +/* + * Clock Manager + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_clock_tick + * + * This directive notifies the executve that a tick has occurred. + * When the tick occurs the time manager updates and maintains + * the calendar time, timeslicing, and any timeout delays. + * + * Input parameters: NONE + * + * Output parameters: + * RTEMS_SUCCESSFUL - always succeeds + * + * NOTE: This routine only works for leap-years through 2099. + */ + +rtems_status_code rtems_clock_tick( void ) +{ + _TOD_Tickle_ticks(); + + _Watchdog_Tickle_ticks(); + + _Thread_Tickle_timeslice(); + + if ( _Thread_Is_context_switch_necessary() && + _Thread_Is_dispatching_enabled() ) + _Thread_Dispatch(); + + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/clocktodtoseconds.c b/cpukit/rtems/src/clocktodtoseconds.c new file mode 100644 index 0000000000..c5093e180d --- /dev/null +++ b/cpukit/rtems/src/clocktodtoseconds.c @@ -0,0 +1,85 @@ +/* + * Time of Day (TOD) Handler - Classic TOD to Seconds + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/clock.h> + +/* + * The following array contains the number of days in all months + * up to the month indicated by the index of the second dimension. + * The first dimension should be 1 for leap years, and 0 otherwise. + */ +const uint16_t _TOD_Days_to_date[2][13] = { + { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, + { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } +}; + +/* + * The following array contains the number of days in the years + * since the last leap year. The index should be 0 for leap + * years, and the number of years since the beginning of a leap + * year otherwise. + */ +const uint16_t _TOD_Days_since_last_leap_year[4] = { 0, 366, 731, 1096 }; + + + +/*PAGE + * + * _TOD_To_seconds + * + * This routine returns the seconds from the epoch until the + * current date and time. + * + * Input parameters: + * the_tod - pointer to the time and date structure + * + * Output parameters: + * returns - seconds since epoch until the_tod + */ + +uint32_t _TOD_To_seconds( + const rtems_time_of_day *the_tod +) +{ + uint32_t time; + uint32_t year_mod_4; + + time = the_tod->day - 1; + year_mod_4 = the_tod->year & 3; + + if ( year_mod_4 == 0 ) + time += _TOD_Days_to_date[ 1 ][ the_tod->month ]; + else + time += _TOD_Days_to_date[ 0 ][ the_tod->month ]; + + time += ( (the_tod->year - TOD_BASE_YEAR) / 4 ) * + ( (TOD_DAYS_PER_YEAR * 4) + 1); + + time += _TOD_Days_since_last_leap_year[ year_mod_4 ]; + + time *= TOD_SECONDS_PER_DAY; + + time += ((the_tod->hour * TOD_MINUTES_PER_HOUR) + the_tod->minute) + * TOD_SECONDS_PER_MINUTE; + + time += the_tod->second; + + time += TOD_SECONDS_1970_THROUGH_1988; + + return( time ); +} diff --git a/cpukit/rtems/src/clocktodvalidate.c b/cpukit/rtems/src/clocktodvalidate.c new file mode 100644 index 0000000000..1dac1dc6b1 --- /dev/null +++ b/cpukit/rtems/src/clocktodvalidate.c @@ -0,0 +1,79 @@ +/* + * Time of Day (TOD) Handler -- Validate Classic TOD + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/clock.h> + +/* + * The following array contains the number of days in all months. + * The first dimension should be 1 for leap years, and 0 otherwise. + * The second dimension should range from 1 to 12 for January to + * February, respectively. + */ +const uint32_t _TOD_Days_per_month[ 2 ][ 13 ] = { + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +/*PAGE + * + * _TOD_Validate + * + * This kernel routine checks the validity of a date and time structure. + * + * Input parameters: + * the_tod - pointer to a time and date structure + * + * Output parameters: + * true - if the date, time, and tick are valid + * false - if the the_tod is invalid + * + * NOTE: This routine only works for leap-years through 2099. + */ + +bool _TOD_Validate( + const rtems_time_of_day *the_tod +) +{ + uint32_t days_in_month; + uint32_t ticks_per_second; + + ticks_per_second = TOD_MICROSECONDS_PER_SECOND / + rtems_configuration_get_microseconds_per_tick(); + if ((!the_tod) || + (the_tod->ticks >= ticks_per_second) || + (the_tod->second >= TOD_SECONDS_PER_MINUTE) || + (the_tod->minute >= TOD_MINUTES_PER_HOUR) || + (the_tod->hour >= TOD_HOURS_PER_DAY) || + (the_tod->month == 0) || + (the_tod->month > TOD_MONTHS_PER_YEAR) || + (the_tod->year < TOD_BASE_YEAR) || + (the_tod->day == 0) ) + return false; + + if ( (the_tod->year % 4) == 0 ) + days_in_month = _TOD_Days_per_month[ 1 ][ the_tod->month ]; + else + days_in_month = _TOD_Days_per_month[ 0 ][ the_tod->month ]; + + if ( the_tod->day > days_in_month ) + return false; + + return true; +} diff --git a/cpukit/rtems/src/dpmem.c b/cpukit/rtems/src/dpmem.c new file mode 100644 index 0000000000..9cc58914b8 --- /dev/null +++ b/cpukit/rtems/src/dpmem.c @@ -0,0 +1,57 @@ +/* + * Dual Port Memory Manager + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/rtems/dpmem.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * _Dual_ported_memory_Manager_initialization + * + * This routine initializes all dual-ported memory manager related + * data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Dual_ported_memory_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_Dual_ported_memory_Information, /* object information table */ + OBJECTS_CLASSIC_API, /* object API */ + OBJECTS_RTEMS_PORTS, /* object class */ + Configuration_RTEMS_API.maximum_ports, + /* maximum objects of this class */ + sizeof( Dual_ported_memory_Control ), + /* size of this object's control block */ + false, /* true if names of this object are strings */ + RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/rtems/src/dpmemcreate.c b/cpukit/rtems/src/dpmemcreate.c new file mode 100644 index 0000000000..69df430dd8 --- /dev/null +++ b/cpukit/rtems/src/dpmemcreate.c @@ -0,0 +1,88 @@ +/* + * Dual Port Memory Manager + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/rtems/dpmem.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/dpmem.h> + +/*PAGE + * + * rtems_port_create + * + * This directive creates a port into a dual-ported memory area. + * + * Input parameters: + * name - user defined port name + * internal_start - internal start address of port + * external_start - external start address of port + * length - physical length in bytes + * id - address of port id to set + * + * Output parameters: + * id - port id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_port_create( + rtems_name name, + void *internal_start, + void *external_start, + uint32_t length, + rtems_id *id +) +{ + register Dual_ported_memory_Control *the_port; + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + + if ( !_Addresses_Is_aligned( internal_start ) || + !_Addresses_Is_aligned( external_start ) ) + return RTEMS_INVALID_ADDRESS; + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_port = _Dual_ported_memory_Allocate(); + + if ( !the_port ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + + the_port->internal_base = internal_start; + the_port->external_base = external_start; + the_port->length = length - 1; + + _Objects_Open( + &_Dual_ported_memory_Information, + &the_port->Object, + (Objects_Name) name + ); + + *id = the_port->Object.id; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/dpmemdata.c b/cpukit/rtems/src/dpmemdata.c new file mode 100644 index 0000000000..cc2285c1f6 --- /dev/null +++ b/cpukit/rtems/src/dpmemdata.c @@ -0,0 +1,22 @@ +/* + * Dual Port Memory Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate semaphore data */ +#define RTEMS_DPMEM_EXTERN + +#include <rtems/system.h> +#include <rtems/rtems/dpmem.h> diff --git a/cpukit/rtems/src/dpmemdelete.c b/cpukit/rtems/src/dpmemdelete.c new file mode 100644 index 0000000000..003c27fecb --- /dev/null +++ b/cpukit/rtems/src/dpmemdelete.c @@ -0,0 +1,66 @@ +/* + * Dual Port Memory Manager + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/rtems/dpmem.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/dpmem.h> + +/*PAGE + * + * rtems_port_delete + * + * This directive allows a thread to delete a dual-ported memory area + * specified by the dual-ported memory identifier. + * + * Input parameters: + * id - dual-ported memory area id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_port_delete( + rtems_id id +) +{ + register Dual_ported_memory_Control *the_port; + Objects_Locations location; + + the_port = _Dual_ported_memory_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object ); + _Dual_ported_memory_Free( the_port ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/dpmemexternal2internal.c b/cpukit/rtems/src/dpmemexternal2internal.c new file mode 100644 index 0000000000..45c8344588 --- /dev/null +++ b/cpukit/rtems/src/dpmemexternal2internal.c @@ -0,0 +1,79 @@ +/* + * Dual Port Memory Manager + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/rtems/dpmem.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/dpmem.h> + +/*PAGE + * + * rtems_port_external_to_internal + * + * This directive converts an external dual-ported memory address to an + * internal dual-ported memory address. If the given external address + * is an invalid dual-ported address, then the internal address is set + * to the given external address. + * + * Input parameters: + * id - id of dp memory object + * external - external address + * internal - pointer of internal address to set + * + * Output parameters: + * internal - internal address + * RTEMS_SUCCESSFUL - always succeeds + */ + +rtems_status_code rtems_port_external_to_internal( + rtems_id id, + void *external, + void **internal +) +{ + register Dual_ported_memory_Control *the_port; + Objects_Locations location; + uint32_t ending; + + if ( !internal ) + return RTEMS_INVALID_ADDRESS; + + the_port = _Dual_ported_memory_Get( id, &location ); + switch ( location ) { + case OBJECTS_LOCAL: + ending = _Addresses_Subtract( external, the_port->external_base ); + if ( ending > the_port->length ) + *internal = external; + else + *internal = _Addresses_Add_offset( the_port->internal_base, + ending ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/dpmemident.c b/cpukit/rtems/src/dpmemident.c new file mode 100644 index 0000000000..f41aef293b --- /dev/null +++ b/cpukit/rtems/src/dpmemident.c @@ -0,0 +1,59 @@ +/* + * Dual Port Memory Manager + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/rtems/dpmem.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/dpmem.h> + +/*PAGE + * + * rtems_port_ident + * + * This directive returns the system ID associated with + * the port name. + * + * Input parameters: + * name - user defined port name + * id - pointer to port id + * + * Output parameters: + * *id - port id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_port_ident( + rtems_name name, + rtems_id *id +) +{ + Objects_Name_or_id_lookup_errors status; + + status = _Objects_Name_to_id_u32( + &_Dual_ported_memory_Information, + name, + OBJECTS_SEARCH_ALL_NODES, + id + ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/dpmeminternal2external.c b/cpukit/rtems/src/dpmeminternal2external.c new file mode 100644 index 0000000000..5bf4d4fe93 --- /dev/null +++ b/cpukit/rtems/src/dpmeminternal2external.c @@ -0,0 +1,80 @@ +/* + * Dual Port Memory Manager + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/rtems/dpmem.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/dpmem.h> + +/*PAGE + * + * rtems_port_internal_to_external + * + * This directive converts an internal dual-ported memory address to an + * external dual-ported memory address. If the given internal address + * is an invalid dual-ported address, then the external address is set + * to the given internal address. + * + * Input parameters: + * id - id of dual-ported memory object + * internal - internal address to set + * external - pointer to external address + * + * Output parameters: + * external - external address + * RTEMS_SUCCESSFUL - always succeeds + */ + +rtems_status_code rtems_port_internal_to_external( + rtems_id id, + void *internal, + void **external +) +{ + register Dual_ported_memory_Control *the_port; + Objects_Locations location; + uint32_t ending; + + if ( !external ) + return RTEMS_INVALID_ADDRESS; + + the_port = _Dual_ported_memory_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + ending = _Addresses_Subtract( internal, the_port->internal_base ); + if ( ending > the_port->length ) + *external = internal; + else + *external = _Addresses_Add_offset( the_port->external_base, + ending ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/event.c b/cpukit/rtems/src/event.c new file mode 100644 index 0000000000..85d35829c2 --- /dev/null +++ b/cpukit/rtems/src/event.c @@ -0,0 +1,48 @@ +/* + * Event Manager + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/event.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/tasks.h> + +/*PAGE + * + * _Event_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Event_Manager_initialization( void ) +{ + _Event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; + + /* + * Register the MP Process Packet routine. + */ + +#if defined(RTEMS_MULTIPROCESSING) + _MPCI_Register_packet_processor( MP_PACKET_EVENT, _Event_MP_Process_packet ); +#endif +} diff --git a/cpukit/rtems/src/eventdata.c b/cpukit/rtems/src/eventdata.c new file mode 100644 index 0000000000..bc7eb466c1 --- /dev/null +++ b/cpukit/rtems/src/eventdata.c @@ -0,0 +1,22 @@ +/* + * Event Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate RTEMS event data */ +#define RTEMS_EVENT_EXTERN + +#include <rtems/system.h> +#include <rtems/rtems/event.h> diff --git a/cpukit/rtems/src/eventmp.c b/cpukit/rtems/src/eventmp.c new file mode 100644 index 0000000000..552d283994 --- /dev/null +++ b/cpukit/rtems/src/eventmp.c @@ -0,0 +1,193 @@ +/* + * Multiprocessing Support for the Event Manager + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/event.h> +#include <rtems/score/mpci.h> +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * _Event_MP_Send_process_packet + * + * This subprogram is not needed since there are no process + * packets to be sent by this manager. + * + */ + +/*PAGE + * + * _Event_MP_Send_request_packet + * + */ + +rtems_status_code _Event_MP_Send_request_packet ( + Event_MP_Remote_operations operation, + Objects_Id event_id, + rtems_event_set event_in +) +{ + Event_MP_Packet *the_packet; + + switch ( operation ) { + + case EVENT_MP_SEND_REQUEST: + + the_packet = _Event_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_EVENT; + the_packet->Prefix.length = sizeof ( Event_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Event_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = event_id; + the_packet->event_in = event_in; + + return (rtems_status_code) + _MPCI_Send_request_packet( + _Objects_Get_node( event_id ), + &the_packet->Prefix, + STATES_READY + ); + + break; + + case EVENT_MP_SEND_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _Event_MP_Send_response_packet + * + */ + +void _Event_MP_Send_response_packet ( + Event_MP_Remote_operations operation, + Thread_Control *the_thread +) +{ + Event_MP_Packet *the_packet; + + switch ( operation ) { + + case EVENT_MP_SEND_RESPONSE: + + the_packet = ( Event_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + _Objects_Get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case EVENT_MP_SEND_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Event_MP_Process_packet + * + */ + +void _Event_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Event_MP_Packet *the_packet; + Thread_Control *the_thread; + + the_packet = (Event_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case EVENT_MP_SEND_REQUEST: + + the_packet->Prefix.return_code = rtems_event_send( + the_packet->Prefix.id, + the_packet->event_in + ); + + _Event_MP_Send_response_packet( + EVENT_MP_SEND_RESPONSE, + _Thread_Executing + ); + break; + + case EVENT_MP_SEND_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + + break; + + } +} + +/*PAGE + * + * _Event_MP_Send_object_was_deleted + * + * This subprogram is not needed since there are no objects + * deleted by this manager. + * + */ + +/*PAGE + * + * _Event_MP_Send_extract_proxy + * + * This subprogram is not needed since there are no objects + * deleted by this manager. + * + */ + +/*PAGE + * + * _Event_MP_Get_packet + * + */ + +Event_MP_Packet *_Event_MP_Get_packet ( void ) +{ + return ( (Event_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/eventreceive.c b/cpukit/rtems/src/eventreceive.c new file mode 100644 index 0000000000..54bb7ef54c --- /dev/null +++ b/cpukit/rtems/src/eventreceive.c @@ -0,0 +1,69 @@ +/* + * Event Manager + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/event.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/tasks.h> + +/*PAGE + * + * rtems_event_receive + * + * This directive allows a thread to receive a set of events. + * + * Input parameters: + * event_in - input event condition + * option_set - options + * ticks - number of ticks to wait (0 means wait forever) + * event_out - pointer to output event set + * + * Output parameters: + * event out - event set + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_event_receive( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +) +{ + RTEMS_API_Control *api; + + if ( !event_out ) + return RTEMS_INVALID_ADDRESS; + + api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; + + if ( _Event_sets_Is_empty( event_in ) ) { + *event_out = api->pending_events; + return RTEMS_SUCCESSFUL; + } + + _Thread_Disable_dispatch(); + _Event_Seize( event_in, option_set, ticks, event_out ); + _Thread_Enable_dispatch(); + return( _Thread_Executing->Wait.return_code ); +} diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c new file mode 100644 index 0000000000..0b6bf2d623 --- /dev/null +++ b/cpukit/rtems/src/eventseize.c @@ -0,0 +1,133 @@ +/* + * Event Manager + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/event.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/tasks.h> + +/*PAGE + * + * _Event_Seize + * + * This routine attempts to satisfy the requested event condition + * for the running thread. + * + * Input parameters: + * event_in - the event condition to satisfy + * option_set - acquire event options + * ticks - interval to wait + * event_out - pointer to event set output area + * + * Output parameters: NONE + * *event_out - event set output area filled in + * + * INTERRUPT LATENCY: + * available + * wait + * check sync + */ + +void _Event_Seize( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +) +{ + Thread_Control *executing; + rtems_event_set seized_events; + rtems_event_set pending_events; + ISR_Level level; + RTEMS_API_Control *api; + Thread_blocking_operation_States sync_state; + + executing = _Thread_Executing; + executing->Wait.return_code = RTEMS_SUCCESSFUL; + + api = executing->API_Extensions[ THREAD_API_RTEMS ]; + + _ISR_Disable( level ); + pending_events = api->pending_events; + seized_events = _Event_sets_Get( pending_events, event_in ); + + if ( !_Event_sets_Is_empty( seized_events ) && + (seized_events == event_in || _Options_Is_any( option_set )) ) { + api->pending_events = + _Event_sets_Clear( pending_events, seized_events ); + _ISR_Enable( level ); + *event_out = seized_events; + return; + } + + if ( _Options_Is_no_wait( option_set ) ) { + _ISR_Enable( level ); + executing->Wait.return_code = RTEMS_UNSATISFIED; + *event_out = seized_events; + return; + } + + /* + * Note what we are waiting for BEFORE we enter the critical section. + * The interrupt critical section management code needs this to be + * set properly when we are marked as in the event critical section. + * + * NOTE: Since interrupts are disabled, this isn't that much of an + * issue but better safe than sorry. + */ + executing->Wait.option = (uint32_t) option_set; + executing->Wait.count = (uint32_t) event_in; + executing->Wait.return_argument = event_out; + + _Event_Sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; + + _ISR_Enable( level ); + + if ( ticks ) { + _Watchdog_Initialize( + &executing->Timer, + _Event_Timeout, + executing->Object.id, + NULL + ); + _Watchdog_Insert_ticks( &executing->Timer, ticks ); + } + + _Thread_Set_state( executing, STATES_WAITING_FOR_EVENT ); + + _ISR_Disable( level ); + + sync_state = _Event_Sync_state; + _Event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; + if ( sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) { + _ISR_Enable( level ); + return; + } + + /* + * An interrupt completed the thread's blocking request. + * The blocking thread was satisfied by an ISR or timed out. + * + * WARNING! Returning with interrupts disabled! + */ + _Thread_blocking_operation_Cancel( sync_state, executing, level ); +} diff --git a/cpukit/rtems/src/eventsend.c b/cpukit/rtems/src/eventsend.c new file mode 100644 index 0000000000..412d52a7f1 --- /dev/null +++ b/cpukit/rtems/src/eventsend.c @@ -0,0 +1,78 @@ +/* + * Event Manager + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/event.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/tasks.h> + +/*PAGE + * + * rtems_event_send + * + * This directive allows a thread send an event set to another thread. + * + * Input parameters: + * id - thread id + * event - event set + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_event_send( + rtems_id id, + rtems_event_set event_in +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + RTEMS_API_Control *api; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + _Event_sets_Post( event_in, &api->pending_events ); + _Event_Surrender( the_thread ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return( + _Event_MP_Send_request_packet( + EVENT_MP_SEND_REQUEST, + id, + event_in + ) + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c new file mode 100644 index 0000000000..179727f523 --- /dev/null +++ b/cpukit/rtems/src/eventsurrender.c @@ -0,0 +1,116 @@ +/* + * Event Manager + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/event.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/tasks.h> + +/*PAGE + * + * _Event_Surrender + * + * This routines remove a thread from the specified threadq. + * + * Input parameters: + * the_thread - pointer to thread to be dequeued + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * before flash + * after flash + * check sync + */ + +void _Event_Surrender( + Thread_Control *the_thread +) +{ + ISR_Level level; + rtems_event_set pending_events; + rtems_event_set event_condition; + rtems_event_set seized_events; + rtems_option option_set; + RTEMS_API_Control *api; + + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + + option_set = (rtems_option) the_thread->Wait.option; + + _ISR_Disable( level ); + pending_events = api->pending_events; + event_condition = (rtems_event_set) the_thread->Wait.count; + + seized_events = _Event_sets_Get( pending_events, event_condition ); + + /* + * No events were seized in this operation + */ + if ( _Event_sets_Is_empty( seized_events ) ) { + _ISR_Enable( level ); + return; + } + + /* + * If we are in an ISR and sending to the current thread, then + * we have a critical section issue to deal with. + */ + if ( _ISR_Is_in_progress() && + _Thread_Is_executing( the_thread ) && + ((_Event_Sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT) || + (_Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED)) ) { + if ( seized_events == event_condition || _Options_Is_any(option_set) ) { + api->pending_events = _Event_sets_Clear( pending_events,seized_events ); + the_thread->Wait.count = 0; + *(rtems_event_set *)the_thread->Wait.return_argument = seized_events; + _Event_Sync_state = THREAD_BLOCKING_OPERATION_SATISFIED; + } + _ISR_Enable( level ); + return; + } + + /* + * Otherwise, this is a normal send to another thread + */ + if ( _States_Is_waiting_for_event( the_thread->current_state ) ) { + if ( seized_events == event_condition || _Options_Is_any( option_set ) ) { + api->pending_events = _Event_sets_Clear( pending_events, seized_events ); + the_thread->Wait.count = 0; + *(rtems_event_set *)the_thread->Wait.return_argument = seized_events; + + _ISR_Flash( level ); + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + return; + } + } + _ISR_Enable( level ); +} diff --git a/cpukit/rtems/src/eventtimeout.c b/cpukit/rtems/src/eventtimeout.c new file mode 100644 index 0000000000..c1eef71f9e --- /dev/null +++ b/cpukit/rtems/src/eventtimeout.c @@ -0,0 +1,93 @@ +/* + * Event Manager + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/event.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/tasks.h> + +/*PAGE + * + * _Event_Timeout + * + * This routine processes a thread which timeouts while waiting to + * receive an event_set. It is called by the watchdog handler. + * + * Input parameters: + * id - thread id + * + * Output parameters: NONE + */ + +void _Event_Timeout( + Objects_Id id, + void *ignored +) +{ + Thread_Control *the_thread; + Objects_Locations location; + ISR_Level level; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + /* + * If the event manager is not synchronized, then it is either + * "nothing happened", "timeout", or "satisfied". If the_thread + * is the executing thread, then it is in the process of blocking + * and it is the thread which is responsible for the synchronization + * process. + * + * If it is not satisfied, then it is "nothing happened" and + * this is the "timeout" transition. After a request is satisfied, + * a timeout is not allowed to occur. + */ + _ISR_Disable( level ); + #if defined(RTEMS_DEBUG) + if ( !the_thread->Wait.count ) { /* verify thread is waiting */ + _Thread_Unnest_dispatch(); + _ISR_Enable( level ); + return; + } + #endif + + the_thread->Wait.count = 0; + if ( _Thread_Is_executing( the_thread ) ) { + if ( _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) + _Event_Sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT; + } + + the_thread->Wait.return_code = RTEMS_TIMEOUT; + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + _Thread_Unnest_dispatch(); + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* impossible */ +#endif + case OBJECTS_ERROR: + break; + } +} diff --git a/cpukit/rtems/src/intrbody.c b/cpukit/rtems/src/intrbody.c new file mode 100644 index 0000000000..aac994229d --- /dev/null +++ b/cpukit/rtems/src/intrbody.c @@ -0,0 +1,74 @@ +/* + * Bodies for Inlined Interrupt Manager Routines + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/score/isr.h> +#include <rtems/rtems/intr.h> + +/* + * Real body for rtems_interrupt_disable + */ + +#undef rtems_interrupt_disable + +rtems_interrupt_level rtems_interrupt_disable( void ) +{ + rtems_interrupt_level previous_level; + + _ISR_Disable( previous_level ); + + return previous_level; +} + +/* + * Real body for rtems_interrupt_enable + */ + +#undef rtems_interrupt_enable + +void rtems_interrupt_enable( + rtems_interrupt_level previous_level +) +{ + _ISR_Enable( previous_level ); +} + +/* + * Real body for rtems_interrupt_flash + */ + +#undef rtems_interrupt_flash + +void rtems_interrupt_flash( + rtems_interrupt_level previous_level +) +{ + _ISR_Flash( previous_level ); +} + +/* + * Real body for rtems_interrupt_is_in_progress + */ + +#undef rtems_interrupt_is_in_progress + +bool rtems_interrupt_is_in_progress( void ) +{ + return _ISR_Is_in_progress(); +} diff --git a/cpukit/rtems/src/intrcatch.c b/cpukit/rtems/src/intrcatch.c new file mode 100644 index 0000000000..dc3f1d4684 --- /dev/null +++ b/cpukit/rtems/src/intrcatch.c @@ -0,0 +1,61 @@ +/* + * Interrupt Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/score/isr.h> +#include <rtems/rtems/intr.h> + +#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE) + +/* rtems_interrupt_catch + * + * This directive allows a thread to specify what action to take when + * catching signals. + * + * Input parameters: + * new_isr_handler - address of interrupt service routine (isr) + * vector - interrupt vector number + * old_isr_handler - address at which to store previous ISR address + * + * Output parameters: + * RTEMS_SUCCESSFUL - always succeeds + * *old_isr_handler - previous ISR address + */ + +rtems_status_code rtems_interrupt_catch( + rtems_isr_entry new_isr_handler, + rtems_vector_number vector, + rtems_isr_entry *old_isr_handler +) +{ + if ( !_ISR_Is_vector_number_valid( vector ) ) + return RTEMS_INVALID_NUMBER; + + if ( !_ISR_Is_valid_user_handler( (void *) new_isr_handler ) ) + return RTEMS_INVALID_ADDRESS; + + if ( !_ISR_Is_valid_user_handler( (void *) old_isr_handler ) ) + return RTEMS_INVALID_ADDRESS; + + _ISR_Install_vector( + vector, (proc_ptr)new_isr_handler, (proc_ptr *)old_isr_handler ); + + return RTEMS_SUCCESSFUL; +} +#endif diff --git a/cpukit/rtems/src/mp.c b/cpukit/rtems/src/mp.c new file mode 100644 index 0000000000..5749dddb4a --- /dev/null +++ b/cpukit/rtems/src/mp.c @@ -0,0 +1,45 @@ +/* + * Multiprocessing Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/mp.h> +#include <rtems/score/mpci.h> + +/*PAGE + * + * _Multiprocessing_Manager_initialization + * + */ + +void _Multiprocessing_Manager_initialization ( void ) +{ +} + +/*PAGE + * + * rtems_multiprocessing_announce + * + */ + +void rtems_multiprocessing_announce ( void ) +{ + _MPCI_Announce(); +} + +/* end of file */ diff --git a/cpukit/rtems/src/msg.c b/cpukit/rtems/src/msg.c new file mode 100644 index 0000000000..25e65aaaa5 --- /dev/null +++ b/cpukit/rtems/src/msg.c @@ -0,0 +1,81 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * _Message_queue_Manager_initialization + * + * This routine initializes all message queue manager related + * data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Message_queue_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_Message_queue_Information, /* object information table */ + OBJECTS_CLASSIC_API, /* object API */ + OBJECTS_RTEMS_MESSAGE_QUEUES, /* object class */ + Configuration_RTEMS_API.maximum_message_queues, + /* maximum objects of this class */ + sizeof( Message_queue_Control ), + /* size of this object's control block */ + false, /* true if names of this object are strings */ + RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + true, /* true if this is a global object class */ + _Message_queue_MP_Send_extract_proxy + /* Proxy extraction support callout */ +#endif + ); + + /* + * Register the MP Process Packet routine. + */ + +#if defined(RTEMS_MULTIPROCESSING) + _MPCI_Register_packet_processor( + MP_PACKET_MESSAGE_QUEUE, + _Message_queue_MP_Process_packet + ); +#endif + +} diff --git a/cpukit/rtems/src/msgdata.c b/cpukit/rtems/src/msgdata.c new file mode 100644 index 0000000000..70baa35723 --- /dev/null +++ b/cpukit/rtems/src/msgdata.c @@ -0,0 +1,23 @@ +/* + * Barrier Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate message queue data */ +#define RTEMS_MESSAGE_EXTERN + +#include <rtems/system.h> +#include <rtems/rtems/message.h> + diff --git a/cpukit/rtems/src/msgmp.c b/cpukit/rtems/src/msgmp.c new file mode 100644 index 0000000000..9f033a8bbb --- /dev/null +++ b/cpukit/rtems/src/msgmp.c @@ -0,0 +1,510 @@ +/* + * Multiprocessing Support for the Message Queue Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/message.h> +#include <rtems/score/mpci.h> +#include <rtems/rtems/msgmp.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * _Message_queue_MP_Send_process_packet + * + */ + +void _Message_queue_MP_Send_process_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + rtems_name name, + Objects_Id proxy_id +) +{ + Message_queue_MP_Packet *the_packet; + uint32_t node; + + switch ( operation ) { + + case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE: + case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE: + case MESSAGE_QUEUE_MP_EXTRACT_PROXY: + + the_packet = _Message_queue_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_MESSAGE_QUEUE; + the_packet->Prefix.length = sizeof ( Message_queue_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Message_queue_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = message_queue_id; + the_packet->name = name; + the_packet->proxy_id = proxy_id; + + if ( operation == MESSAGE_QUEUE_MP_EXTRACT_PROXY ) + node = _Objects_Get_node( message_queue_id ); + else + node = MPCI_ALL_NODES; + + _MPCI_Send_process_packet( node, &the_packet->Prefix ); + break; + + case MESSAGE_QUEUE_MP_RECEIVE_REQUEST: + case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE: + case MESSAGE_QUEUE_MP_SEND_REQUEST: + case MESSAGE_QUEUE_MP_SEND_RESPONSE: + case MESSAGE_QUEUE_MP_URGENT_REQUEST: + case MESSAGE_QUEUE_MP_URGENT_RESPONSE: + case MESSAGE_QUEUE_MP_BROADCAST_REQUEST: + case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE: + case MESSAGE_QUEUE_MP_FLUSH_REQUEST: + case MESSAGE_QUEUE_MP_FLUSH_RESPONSE: + case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST: + case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE: + break; + + } +} + +/*PAGE + * + * _Message_queue_MP_Send_request_packet + * + */ + +rtems_status_code _Message_queue_MP_Send_request_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + const void *buffer, + size_t *size_p, + rtems_option option_set, + rtems_interval timeout +) +{ + Message_queue_MP_Packet *the_packet; + + switch ( operation ) { + + case MESSAGE_QUEUE_MP_SEND_REQUEST: + case MESSAGE_QUEUE_MP_URGENT_REQUEST: + case MESSAGE_QUEUE_MP_BROADCAST_REQUEST: + case MESSAGE_QUEUE_MP_FLUSH_REQUEST: + case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST: + + the_packet = _Message_queue_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_MESSAGE_QUEUE; + the_packet->Prefix.length = sizeof(Message_queue_MP_Packet); + if ( size_p ) + the_packet->Prefix.length += *size_p; + the_packet->Prefix.to_convert = sizeof(Message_queue_MP_Packet); + + /* + * make sure message is not too big for our MPCI driver + * We have to check it here instead of waiting for MPCI because + * we are about to slam in the payload + */ + + if (the_packet->Prefix.length > _MPCI_table->maximum_packet_size) { + _Thread_Enable_dispatch(); + return RTEMS_INVALID_SIZE; + } + + if (! _Options_Is_no_wait(option_set)) + the_packet->Prefix.timeout = timeout; + + the_packet->operation = operation; + the_packet->Prefix.id = message_queue_id; + the_packet->option_set = option_set; + + /* + * Copy the data into place if needed + */ + + if (buffer) { + the_packet->Buffer.size = *size_p; + _CORE_message_queue_Copy_buffer( + buffer, + the_packet->Buffer.buffer, + *size_p + ); + } + + return (rtems_status_code) _MPCI_Send_request_packet( + _Objects_Get_node(message_queue_id), + &the_packet->Prefix, + STATES_WAITING_FOR_MESSAGE + ); + break; + + case MESSAGE_QUEUE_MP_RECEIVE_REQUEST: + + the_packet = _Message_queue_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_MESSAGE_QUEUE; + the_packet->Prefix.length = sizeof(Message_queue_MP_Packet); + the_packet->Prefix.to_convert = sizeof(Message_queue_MP_Packet); + + if (! _Options_Is_no_wait(option_set)) + the_packet->Prefix.timeout = timeout; + + the_packet->operation = MESSAGE_QUEUE_MP_RECEIVE_REQUEST; + the_packet->Prefix.id = message_queue_id; + the_packet->option_set = option_set; + the_packet->size = 0; /* just in case of an error */ + + _Thread_Executing->Wait.return_argument_second.immutable_object = buffer; + _Thread_Executing->Wait.return_argument = size_p; + + return (rtems_status_code) _MPCI_Send_request_packet( + _Objects_Get_node(message_queue_id), + &the_packet->Prefix, + STATES_WAITING_FOR_MESSAGE + ); + break; + + case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE: + case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE: + case MESSAGE_QUEUE_MP_EXTRACT_PROXY: + case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE: + case MESSAGE_QUEUE_MP_SEND_RESPONSE: + case MESSAGE_QUEUE_MP_URGENT_RESPONSE: + case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE: + case MESSAGE_QUEUE_MP_FLUSH_RESPONSE: + case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE: + break; + } + + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _Message_queue_MP_Send_response_packet + * + */ + +void _Message_queue_MP_Send_response_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + Thread_Control *the_thread +) +{ + Message_queue_MP_Packet *the_packet; + + switch ( operation ) { + + case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE: + case MESSAGE_QUEUE_MP_SEND_RESPONSE: + case MESSAGE_QUEUE_MP_URGENT_RESPONSE: + case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE: + case MESSAGE_QUEUE_MP_FLUSH_RESPONSE: + case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE: + + the_packet = ( Message_queue_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + * + * Exception: MESSAGE_QUEUE_MP_RECEIVE_RESPONSE needs payload length + * added to 'length' + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + if (operation == MESSAGE_QUEUE_MP_RECEIVE_RESPONSE) + the_packet->Prefix.length += the_packet->size; + + _MPCI_Send_response_packet( + _Objects_Get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE: + case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE: + case MESSAGE_QUEUE_MP_EXTRACT_PROXY: + case MESSAGE_QUEUE_MP_RECEIVE_REQUEST: + case MESSAGE_QUEUE_MP_SEND_REQUEST: + case MESSAGE_QUEUE_MP_URGENT_REQUEST: + case MESSAGE_QUEUE_MP_BROADCAST_REQUEST: + case MESSAGE_QUEUE_MP_FLUSH_REQUEST: + case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Message_queue_MP_Process_packet + * + */ + +void _Message_queue_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Message_queue_MP_Packet *the_packet; + Thread_Control *the_thread; + bool ignored; + + the_packet = (Message_queue_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE: + + ignored = _Objects_MP_Allocate_and_open( + &_Message_queue_Information, + the_packet->name, + the_packet->Prefix.id, + true + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE: + + _Objects_MP_Close( &_Message_queue_Information, the_packet->Prefix.id ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_EXTRACT_PROXY: + + the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); + + if (! _Thread_Is_null( the_thread ) ) + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_RECEIVE_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_receive( + the_packet->Prefix.id, + the_packet->Buffer.buffer, + &the_packet->size, + the_packet->option_set, + the_packet->Prefix.timeout + ); + + if ( the_packet->Prefix.return_code != RTEMS_PROXY_BLOCKING ) + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_RECEIVE_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + if (the_packet->Prefix.return_code == RTEMS_SUCCESSFUL) { + *(size_t *) the_thread->Wait.return_argument = + the_packet->size; + + _CORE_message_queue_Copy_buffer( + the_packet->Buffer.buffer, + the_thread->Wait.return_argument_second.mutable_object, + the_packet->size + ); + } + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_SEND_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_send( + the_packet->Prefix.id, + the_packet->Buffer.buffer, + the_packet->Buffer.size + ); + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_SEND_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case MESSAGE_QUEUE_MP_SEND_RESPONSE: + case MESSAGE_QUEUE_MP_URGENT_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_URGENT_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_urgent( + the_packet->Prefix.id, + the_packet->Buffer.buffer, + the_packet->Buffer.size + ); + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_URGENT_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case MESSAGE_QUEUE_MP_BROADCAST_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_broadcast( + the_packet->Prefix.id, + the_packet->Buffer.buffer, + the_packet->Buffer.size, + &the_packet->count + ); + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_BROADCAST_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE: + case MESSAGE_QUEUE_MP_FLUSH_RESPONSE: + case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + *(uint32_t *) the_thread->Wait.return_argument = the_packet->count; + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_FLUSH_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_flush( + the_packet->Prefix.id, + &the_packet->count + ); + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_FLUSH_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_get_number_pending( + the_packet->Prefix.id, + &the_packet->count + ); + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + } +} + +/*PAGE + * + * _Message_queue_MP_Send_object_was_deleted + * + */ + +void _Message_queue_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +) +{ + the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED; + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_RECEIVE_RESPONSE, + the_proxy->Wait.id, + the_proxy + ); +} + +/*PAGE + * + * _Message_queue_MP_Send_extract_proxy + * + */ + +void _Message_queue_MP_Send_extract_proxy ( + void *argument +) +{ + Thread_Control *the_thread = (Thread_Control *)argument; + + _Message_queue_MP_Send_process_packet( + MESSAGE_QUEUE_MP_EXTRACT_PROXY, + the_thread->Wait.id, + (rtems_name) 0, + the_thread->Object.id + ); +} + +/*PAGE + * + * _Message_queue_MP_Get_packet + * + */ + +Message_queue_MP_Packet *_Message_queue_MP_Get_packet ( void ) +{ + return ( (Message_queue_MP_Packet *) _MPCI_Get_packet() ); +} + + +/*PAGE + * + * _Message_queue_Core_message_queue_mp_support + * + * Input parameters: + * the_thread - the remote thread the message was submitted to + * id - id of the message queue + * + * Output parameters: NONE + */ + +void _Message_queue_Core_message_queue_mp_support ( + Thread_Control *the_thread, + Objects_Id id +) +{ + the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL; + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_RECEIVE_RESPONSE, + id, + the_thread + ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/msgqallocate.c b/cpukit/rtems/src/msgqallocate.c new file mode 100644 index 0000000000..e5603dd9d8 --- /dev/null +++ b/cpukit/rtems/src/msgqallocate.c @@ -0,0 +1,56 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * _Message_queue_Allocate + * + * Allocate a message queue and the space for its messages + * + * Input parameters: + * the_message_queue - the message queue to allocate message buffers + * count - maximum message and reserved buffer count + * max_message_size - maximum size of each message + * + * Output parameters: + * the_message_queue - set if successful, NULL otherwise + */ + +Message_queue_Control *_Message_queue_Allocate(void) +{ + return (Message_queue_Control *) + _Objects_Allocate(&_Message_queue_Information); +} diff --git a/cpukit/rtems/src/msgqbroadcast.c b/cpukit/rtems/src/msgqbroadcast.c new file mode 100644 index 0000000000..96389b8d23 --- /dev/null +++ b/cpukit/rtems/src/msgqbroadcast.c @@ -0,0 +1,113 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * rtems_message_queue_broadcast + * + * This directive sends a message for every thread waiting on the queue + * designated by id. + * + * Input parameters: + * id - pointer to message queue + * buffer - pointer to message buffer + * size - size of message to broadcast + * count - pointer to area to store number of threads made ready + * + * Output parameters: + * count - number of threads made ready + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_broadcast( + rtems_id id, + const void *buffer, + size_t size, + uint32_t *count +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + CORE_message_queue_Status core_status; + + if ( !buffer ) + return RTEMS_INVALID_ADDRESS; + + if ( !count ) + return RTEMS_INVALID_ADDRESS; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + core_status = _CORE_message_queue_Broadcast( + &the_message_queue->message_queue, + buffer, + size, + id, + #if defined(RTEMS_MULTIPROCESSING) + _Message_queue_Core_message_queue_mp_support, + #else + NULL, + #endif + count + ); + + _Thread_Enable_dispatch(); + return + _Message_queue_Translate_core_message_queue_return_code( core_status ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = count; + + return + _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_BROADCAST_REQUEST, + id, + buffer, + &size, + 0, /* option_set not used */ + MPCI_DEFAULT_TIMEOUT + ); +#endif + + case OBJECTS_ERROR: + break; + } + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/msgqcreate.c b/cpukit/rtems/src/msgqcreate.c new file mode 100644 index 0000000000..77af8eac95 --- /dev/null +++ b/cpukit/rtems/src/msgqcreate.c @@ -0,0 +1,165 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * rtems_message_queue_create + * + * This directive creates a message queue by allocating and initializing + * a message queue data structure. + * + * Input parameters: + * name - user defined queue name + * count - maximum message and reserved buffer count + * max_message_size - maximum size of each message + * attribute_set - process method + * id - pointer to queue + * + * Output parameters: + * id - queue id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_create( + rtems_name name, + uint32_t count, + size_t max_message_size, + rtems_attribute attribute_set, + rtems_id *id +) +{ + register Message_queue_Control *the_message_queue; + CORE_message_queue_Attributes the_msgq_attributes; +#if defined(RTEMS_MULTIPROCESSING) + bool is_global; +#endif + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + +#if defined(RTEMS_MULTIPROCESSING) + if ( (is_global = _Attributes_Is_global( attribute_set ) ) && + !_System_state_Is_multiprocessing ) + return RTEMS_MP_NOT_CONFIGURED; +#endif + + if ( count == 0 ) + return RTEMS_INVALID_NUMBER; + + if ( max_message_size == 0 ) + return RTEMS_INVALID_SIZE; + +#if defined(RTEMS_MULTIPROCESSING) +#if 1 + /* + * I am not 100% sure this should be an error. + * It seems reasonable to create a que with a large max size, + * and then just send smaller msgs from remote (or all) nodes. + */ + + if ( is_global && (_MPCI_table->maximum_packet_size < max_message_size) ) + return RTEMS_INVALID_SIZE; +#endif +#endif + + _Thread_Disable_dispatch(); /* protects object pointer */ + + the_message_queue = _Message_queue_Allocate(); + + if ( !the_message_queue ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global && + !( _Objects_MP_Allocate_and_open( &_Message_queue_Information, + name, the_message_queue->Object.id, false ) ) ) { + _Message_queue_Free( the_message_queue ); + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } +#endif + + the_message_queue->attribute_set = attribute_set; + + if (_Attributes_Is_priority( attribute_set ) ) + the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY; + else + the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO; + + if ( ! _CORE_message_queue_Initialize( + &the_message_queue->message_queue, + &the_msgq_attributes, + count, + max_message_size + ) ) { +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global ) + _Objects_MP_Close( + &_Message_queue_Information, the_message_queue->Object.id); +#endif + + _Message_queue_Free( the_message_queue ); + _Thread_Enable_dispatch(); + return RTEMS_UNSATISFIED; + } + + _Objects_Open( + &_Message_queue_Information, + &the_message_queue->Object, + (Objects_Name) name + ); + + *id = the_message_queue->Object.id; + +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global ) + _Message_queue_MP_Send_process_packet( + MESSAGE_QUEUE_MP_ANNOUNCE_CREATE, + the_message_queue->Object.id, + name, + 0 + ); +#endif + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/msgqdelete.c b/cpukit/rtems/src/msgqdelete.c new file mode 100644 index 0000000000..8834886e38 --- /dev/null +++ b/cpukit/rtems/src/msgqdelete.c @@ -0,0 +1,107 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * rtems_message_queue_delete + * + * This directive allows a thread to delete the message queue specified + * by the given queue identifier. + * + * Input parameters: + * id - queue id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_delete( + rtems_id id +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _Objects_Close( &_Message_queue_Information, + &the_message_queue->Object ); + + _CORE_message_queue_Close( + &the_message_queue->message_queue, + #if defined(RTEMS_MULTIPROCESSING) + _Message_queue_MP_Send_object_was_deleted, + #else + NULL, + #endif + CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED + ); + + _Message_queue_Free( the_message_queue ); + +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( the_message_queue->attribute_set ) ) { + _Objects_MP_Close( + &_Message_queue_Information, + the_message_queue->Object.id + ); + + _Message_queue_MP_Send_process_packet( + MESSAGE_QUEUE_MP_ANNOUNCE_DELETE, + the_message_queue->Object.id, + 0, /* Not used */ + 0 + ); + } +#endif + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/msgqflush.c b/cpukit/rtems/src/msgqflush.c new file mode 100644 index 0000000000..deee3b80ae --- /dev/null +++ b/cpukit/rtems/src/msgqflush.c @@ -0,0 +1,94 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * rtems_message_queue_flush + * + * This directive removes all pending messages from a queue and returns + * the number of messages removed. If no messages were present then + * a count of zero is returned. + * + * Input parameters: + * id - queue id + * count - return area for count + * + * Output parameters: + * count - number of messages removed ( 0 = empty queue ) + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_flush( + rtems_id id, + uint32_t *count +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + + if ( !count ) + return RTEMS_INVALID_ADDRESS; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + *count = _CORE_message_queue_Flush( &the_message_queue->message_queue ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = count; + + return + _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_FLUSH_REQUEST, + id, + 0, /* buffer not used */ + 0, /* size */ + 0, /* option_set not used */ + MPCI_DEFAULT_TIMEOUT + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/msgqgetnumberpending.c b/cpukit/rtems/src/msgqgetnumberpending.c new file mode 100644 index 0000000000..cedb2b23d3 --- /dev/null +++ b/cpukit/rtems/src/msgqgetnumberpending.c @@ -0,0 +1,91 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * rtems_message_queue_get_number_pending + * + * This directive returns the number of messages pending. + * + * Input parameters: + * id - queue id + * count - return area for count + * + * Output parameters: + * count - number of messages removed ( 0 = empty queue ) + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_get_number_pending( + rtems_id id, + uint32_t *count +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + + if ( !count ) + return RTEMS_INVALID_ADDRESS; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + *count = the_message_queue->message_queue.number_of_pending_messages; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = count; + + return _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST, + id, + 0, /* buffer not used */ + 0, /* size */ + 0, /* option_set not used */ + MPCI_DEFAULT_TIMEOUT + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/msgqident.c b/cpukit/rtems/src/msgqident.c new file mode 100644 index 0000000000..9030d5df3f --- /dev/null +++ b/cpukit/rtems/src/msgqident.c @@ -0,0 +1,71 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * rtems_message_queue_ident + * + * This directive returns the system ID associated with + * the message queue name. + * + * Input parameters: + * name - user defined message queue name + * node - node(s) to be searched + * id - pointer to message queue id + * + * Output parameters: + * *id - message queue id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_ident( + rtems_name name, + uint32_t node, + rtems_id *id +) +{ + Objects_Name_or_id_lookup_errors status; + + status = _Objects_Name_to_id_u32( + &_Message_queue_Information, + name, + node, + id + ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/msgqreceive.c b/cpukit/rtems/src/msgqreceive.c new file mode 100644 index 0000000000..f7f0db1605 --- /dev/null +++ b/cpukit/rtems/src/msgqreceive.c @@ -0,0 +1,113 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * rtems_message_queue_receive + * + * This directive dequeues a message from the designated message queue + * and copies it into the requesting thread's buffer. + * + * Input parameters: + * id - queue id + * buffer - pointer to message buffer + * size - size of message receive + * option_set - options on receive + * timeout - number of ticks to wait + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_receive( + rtems_id id, + void *buffer, + size_t *size, + rtems_option option_set, + rtems_interval timeout +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + bool wait; + + if ( !buffer ) + return RTEMS_INVALID_ADDRESS; + + if ( !size ) + return RTEMS_INVALID_ADDRESS; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( _Options_Is_no_wait( option_set ) ) + wait = false; + else + wait = true; + + _CORE_message_queue_Seize( + &the_message_queue->message_queue, + the_message_queue->Object.id, + buffer, + size, + wait, + timeout + ); + _Thread_Enable_dispatch(); + return _Message_queue_Translate_core_message_queue_return_code( + _Thread_Executing->Wait.return_code + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_RECEIVE_REQUEST, + id, + buffer, + size, + option_set, + timeout + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/msgqsend.c b/cpukit/rtems/src/msgqsend.c new file mode 100644 index 0000000000..9c2c251cfd --- /dev/null +++ b/cpukit/rtems/src/msgqsend.c @@ -0,0 +1,112 @@ +/* + * Message Queue Manager - rtems_message_queue_send + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/* + * + * rtems_message_queue_send + * + * This routine implements the directive rtems_message_queue_send. It sends a + * message to the specified message queue. + * + * Input parameters: + * id - pointer to message queue + * buffer - pointer to message buffer + * size - size of message to send + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +#if defined(RTEMS_MULTIPROCESSING) +#define MESSAGE_QUEUE_MP_HANDLER _Message_queue_Core_message_queue_mp_support +#else +#define MESSAGE_QUEUE_MP_HANDLER NULL +#endif + +rtems_status_code rtems_message_queue_send( + rtems_id id, + const void *buffer, + size_t size +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + CORE_message_queue_Status status; + + if ( !buffer ) + return RTEMS_INVALID_ADDRESS; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + status = _CORE_message_queue_Send( + &the_message_queue->message_queue, + buffer, + size, + id, + MESSAGE_QUEUE_MP_HANDLER, + false, /* sender does not block */ + 0 /* no timeout */ + ); + + _Thread_Enable_dispatch(); + + /* + * Since this API does not allow for blocking sends, we can directly + * return the returned status. + */ + + return _Message_queue_Translate_core_message_queue_return_code(status); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_SEND_REQUEST, + id, + buffer, + &size, + 0, /* option_set */ + MPCI_DEFAULT_TIMEOUT + ); + break; +#endif + + case OBJECTS_ERROR: + break; + } + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/msgqtranslatereturncode.c b/cpukit/rtems/src/msgqtranslatereturncode.c new file mode 100644 index 0000000000..8a554cb7cc --- /dev/null +++ b/cpukit/rtems/src/msgqtranslatereturncode.c @@ -0,0 +1,81 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * _Message_queue_Translate_core_message_queue_return_code + * + * Input parameters: + * the_message_queue_status - message_queue status code to translate + * + * Output parameters: + * rtems status code - translated RTEMS status code + * + */ + +rtems_status_code _Message_queue_Translate_core_return_code_[] = { + RTEMS_SUCCESSFUL, /* CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL */ + RTEMS_INVALID_SIZE, /* CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE */ + RTEMS_TOO_MANY, /* CORE_MESSAGE_QUEUE_STATUS_TOO_MANY */ + RTEMS_UNSATISFIED, /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED */ + RTEMS_UNSATISFIED, /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT */ + RTEMS_OBJECT_WAS_DELETED, /* CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED */ + RTEMS_TIMEOUT /* CORE_MESSAGE_QUEUE_STATUS_TIMEOUT */ +}; + +rtems_status_code _Message_queue_Translate_core_message_queue_return_code ( + uint32_t status +) +{ + /* + * Check for proxy blocking first since it is out of range + * from the external status codes. + */ + #if defined(RTEMS_MULTIPROCESSING) + if ( _Thread_Is_proxy_blocking(status) ) + return RTEMS_PROXY_BLOCKING; + #endif + + /* + * Internal consistency check for bad status from SuperCore + */ + #if defined(RTEMS_DEBUG) + if ( status > CORE_MESSAGE_QUEUE_STATUS_TIMEOUT ) + return RTEMS_INTERNAL_ERROR; + #endif + + return _Message_queue_Translate_core_return_code_[status]; +} diff --git a/cpukit/rtems/src/msgqurgent.c b/cpukit/rtems/src/msgqurgent.c new file mode 100644 index 0000000000..ddb66a8488 --- /dev/null +++ b/cpukit/rtems/src/msgqurgent.c @@ -0,0 +1,111 @@ +/* + * Message Queue Manager - rtems_message_queue_urgent + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/rtems/status.h> +#include <rtems/rtems/attr.h> +#include <rtems/rtems/message.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * rtems_message_queue_urgent + * + * This routine implements the directives rtems_message_queue_urgent. It + * prepends a message to the specified message queue. + * + * Input parameters: + * id - pointer to message queue + * buffer - pointer to message buffer + * size - size of message to send urgently + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +#if defined(RTEMS_MULTIPROCESSING) +#define MESSAGE_QUEUE_MP_HANDLER _Message_queue_Core_message_queue_mp_support +#else +#define MESSAGE_QUEUE_MP_HANDLER NULL +#endif + +rtems_status_code rtems_message_queue_urgent( + rtems_id id, + const void *buffer, + size_t size +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + CORE_message_queue_Status status; + + if ( !buffer ) + return RTEMS_INVALID_ADDRESS; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + status = _CORE_message_queue_Urgent( + &the_message_queue->message_queue, + buffer, + size, + id, + MESSAGE_QUEUE_MP_HANDLER, + false, /* sender does not block */ + 0 /* no timeout */ + ); + _Thread_Enable_dispatch(); + + /* + * Since this API does not allow for blocking sends, we can directly + * return the returned status. + */ + + return _Message_queue_Translate_core_message_queue_return_code(status); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_URGENT_REQUEST, + id, + buffer, + &size, + 0, /* option_set */ + MPCI_DEFAULT_TIMEOUT + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/part.c b/cpukit/rtems/src/part.c new file mode 100644 index 0000000000..a5c12e5fb9 --- /dev/null +++ b/cpukit/rtems/src/part.c @@ -0,0 +1,69 @@ +/* + * Partition Manager + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/score/object.h> +#include <rtems/rtems/part.h> +#include <rtems/score/thread.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * _Partition_Manager_initialization + * + * This routine initializes all partition manager related + * data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Partition_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_Partition_Information, /* object information table */ + OBJECTS_CLASSIC_API, /* object API */ + OBJECTS_RTEMS_PARTITIONS, /* object class */ + Configuration_RTEMS_API.maximum_partitions, + /* maximum objects of this class */ + sizeof( Partition_Control ), /* size of this object's control block */ + false, /* true if the name is a string */ + RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */ +#if defined(RTEMS_MULTIPROCESSING) + , + true, /* true if this is a global object class */ + _Partition_MP_Send_extract_proxy /* Proxy extraction support callout */ +#endif + ); + + /* + * Register the MP Process Packet routine. + */ + +#if defined(RTEMS_MULTIPROCESSING) + _MPCI_Register_packet_processor( + MP_PACKET_PARTITION, + _Partition_MP_Process_packet + ); +#endif + +} diff --git a/cpukit/rtems/src/partcreate.c b/cpukit/rtems/src/partcreate.c new file mode 100644 index 0000000000..6b3d819ea5 --- /dev/null +++ b/cpukit/rtems/src/partcreate.c @@ -0,0 +1,129 @@ +/* + * Partition Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/score/object.h> +#include <rtems/rtems/part.h> +#include <rtems/score/thread.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_partition_create + * + * This directive creates a partiton of fixed sized buffers from the + * given contiguous memory area. + * + * Input parameters: + * name - user defined partition name + * starting_address - physical start address of partition + * length - physical length in bytes + * buffer_size - size of buffers in bytes + * attribute_set - partition attributes + * id - pointer to partition id + * + * Output parameters: + * id - partition id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_partition_create( + rtems_name name, + void *starting_address, + uint32_t length, + uint32_t buffer_size, + rtems_attribute attribute_set, + rtems_id *id +) +{ + register Partition_Control *the_partition; + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + if ( !starting_address ) + return RTEMS_INVALID_ADDRESS; + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + + if ( length == 0 || buffer_size == 0 || length < buffer_size || + !_Partition_Is_buffer_size_aligned( buffer_size ) ) + return RTEMS_INVALID_SIZE; + + if ( !_Addresses_Is_aligned( starting_address ) ) + return RTEMS_INVALID_ADDRESS; + +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( attribute_set ) && + !_System_state_Is_multiprocessing ) + return RTEMS_MP_NOT_CONFIGURED; +#endif + + _Thread_Disable_dispatch(); /* prevents deletion */ + + the_partition = _Partition_Allocate(); + + if ( !the_partition ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( attribute_set ) && + !( _Objects_MP_Allocate_and_open( &_Partition_Information, name, + the_partition->Object.id, false ) ) ) { + _Partition_Free( the_partition ); + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } +#endif + + the_partition->starting_address = starting_address; + the_partition->length = length; + the_partition->buffer_size = buffer_size; + the_partition->attribute_set = attribute_set; + the_partition->number_of_used_blocks = 0; + + _Chain_Initialize( &the_partition->Memory, starting_address, + length / buffer_size, buffer_size ); + + _Objects_Open( + &_Partition_Information, + &the_partition->Object, + (Objects_Name) name + ); + + *id = the_partition->Object.id; +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( attribute_set ) ) + _Partition_MP_Send_process_packet( + PARTITION_MP_ANNOUNCE_CREATE, + the_partition->Object.id, + name, + 0 /* Not used */ + ); +#endif + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/partdata.c b/cpukit/rtems/src/partdata.c new file mode 100644 index 0000000000..8f6c5b4531 --- /dev/null +++ b/cpukit/rtems/src/partdata.c @@ -0,0 +1,22 @@ +/* + * Partition Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate RTEMS partition data */ +#define RTEMS_PART_EXTERN + +#include <rtems/system.h> +#include <rtems/rtems/part.h> diff --git a/cpukit/rtems/src/partdelete.c b/cpukit/rtems/src/partdelete.c new file mode 100644 index 0000000000..871e198f3f --- /dev/null +++ b/cpukit/rtems/src/partdelete.c @@ -0,0 +1,92 @@ +/* + * Partition Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/score/object.h> +#include <rtems/rtems/part.h> +#include <rtems/score/thread.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_partition_delete + * + * This directive allows a thread to delete a partition specified by + * the partition identifier, provided that none of its buffers are + * still allocated. + * + * Input parameters: + * id - partition id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_partition_delete( + rtems_id id +) +{ + register Partition_Control *the_partition; + Objects_Locations location; + + the_partition = _Partition_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( the_partition->number_of_used_blocks == 0 ) { + _Objects_Close( &_Partition_Information, &the_partition->Object ); + _Partition_Free( the_partition ); +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( the_partition->attribute_set ) ) { + + _Objects_MP_Close( + &_Partition_Information, + the_partition->Object.id + ); + + _Partition_MP_Send_process_packet( + PARTITION_MP_ANNOUNCE_DELETE, + the_partition->Object.id, + 0, /* Not used */ + 0 /* Not used */ + ); + } +#endif + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_RESOURCE_IN_USE; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/partgetbuffer.c b/cpukit/rtems/src/partgetbuffer.c new file mode 100644 index 0000000000..56d58a1103 --- /dev/null +++ b/cpukit/rtems/src/partgetbuffer.c @@ -0,0 +1,87 @@ +/* + * Partition Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/score/object.h> +#include <rtems/rtems/part.h> +#include <rtems/score/thread.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_partition_get_buffer + * + * This directive will obtain a buffer from a buffer partition. + * + * Input parameters: + * id - partition id + * buffer - pointer to buffer address + * + * Output parameters: + * buffer - pointer to buffer address filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_partition_get_buffer( + rtems_id id, + void **buffer +) +{ + register Partition_Control *the_partition; + Objects_Locations location; + void *the_buffer; + + if ( !buffer ) + return RTEMS_INVALID_ADDRESS; + + the_partition = _Partition_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + the_buffer = _Partition_Allocate_buffer( the_partition ); + if ( the_buffer ) { + the_partition->number_of_used_blocks += 1; + _Thread_Enable_dispatch(); + *buffer = the_buffer; + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_UNSATISFIED; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = buffer; + return( + _Partition_MP_Send_request_packet( + PARTITION_MP_GET_BUFFER_REQUEST, + id, + 0 /* Not used */ + ) + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/partident.c b/cpukit/rtems/src/partident.c new file mode 100644 index 0000000000..8f9004ea8e --- /dev/null +++ b/cpukit/rtems/src/partident.c @@ -0,0 +1,57 @@ +/* + * Partition Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/score/object.h> +#include <rtems/rtems/part.h> +#include <rtems/score/thread.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_partition_ident + * + * This directive returns the system ID associated with + * the partition name. + * + * Input parameters: + * name - user defined partition name + * node - node(s) to be searched + * id - pointer to partition id + * + * Output parameters: + * *id - partition id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_partition_ident( + rtems_name name, + uint32_t node, + rtems_id *id +) +{ + Objects_Name_or_id_lookup_errors status; + + status = _Objects_Name_to_id_u32( &_Partition_Information, name, node, id ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/partmp.c b/cpukit/rtems/src/partmp.c new file mode 100644 index 0000000000..da6e2ca8d6 --- /dev/null +++ b/cpukit/rtems/src/partmp.c @@ -0,0 +1,307 @@ +/* + * Multiprocessing Support for the Partition Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/score/mpci.h> +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/part.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * _Partition_MP_Send_process_packet + * + */ + +void _Partition_MP_Send_process_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + rtems_name name, + Objects_Id proxy_id +) +{ + Partition_MP_Packet *the_packet; + uint32_t node; + + switch ( operation ) { + + case PARTITION_MP_ANNOUNCE_CREATE: + case PARTITION_MP_ANNOUNCE_DELETE: + case PARTITION_MP_EXTRACT_PROXY: + + the_packet = _Partition_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_PARTITION; + the_packet->Prefix.length = sizeof ( Partition_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Partition_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = partition_id; + the_packet->name = name; + the_packet->proxy_id = proxy_id; + + if ( operation == PARTITION_MP_EXTRACT_PROXY ) + node = _Objects_Get_node( partition_id ); + else + node = MPCI_ALL_NODES; + + _MPCI_Send_process_packet( node, &the_packet->Prefix ); + break; + + case PARTITION_MP_GET_BUFFER_REQUEST: + case PARTITION_MP_GET_BUFFER_RESPONSE: + case PARTITION_MP_RETURN_BUFFER_REQUEST: + case PARTITION_MP_RETURN_BUFFER_RESPONSE: + break; + } +} + +/*PAGE + * + * _Partition_MP_Send_request_packet + * + */ + +rtems_status_code _Partition_MP_Send_request_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + void *buffer +) +{ + Partition_MP_Packet *the_packet; + + switch ( operation ) { + + case PARTITION_MP_GET_BUFFER_REQUEST: + case PARTITION_MP_RETURN_BUFFER_REQUEST: + + the_packet = _Partition_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_PARTITION; + the_packet->Prefix.length = sizeof ( Partition_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Partition_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = partition_id; + the_packet->buffer = buffer; + + return + _MPCI_Send_request_packet( + _Objects_Get_node( partition_id ), + &the_packet->Prefix, + STATES_READY /* Not used */ + ); + + break; + + case PARTITION_MP_ANNOUNCE_CREATE: + case PARTITION_MP_ANNOUNCE_DELETE: + case PARTITION_MP_EXTRACT_PROXY: + case PARTITION_MP_GET_BUFFER_RESPONSE: + case PARTITION_MP_RETURN_BUFFER_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _Partition_MP_Send_response_packet + * + */ + +void _Partition_MP_Send_response_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + Thread_Control *the_thread +) +{ + Partition_MP_Packet *the_packet; + + switch ( operation ) { + + case PARTITION_MP_GET_BUFFER_RESPONSE: + case PARTITION_MP_RETURN_BUFFER_RESPONSE: + + the_packet = ( Partition_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + _Objects_Get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case PARTITION_MP_ANNOUNCE_CREATE: + case PARTITION_MP_ANNOUNCE_DELETE: + case PARTITION_MP_EXTRACT_PROXY: + case PARTITION_MP_GET_BUFFER_REQUEST: + case PARTITION_MP_RETURN_BUFFER_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Partition_MP_Process_packet + * + */ + +void _Partition_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Partition_MP_Packet *the_packet; + Thread_Control *the_thread; + bool ignored; + + the_packet = (Partition_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case PARTITION_MP_ANNOUNCE_CREATE: + + ignored = _Objects_MP_Allocate_and_open( + &_Partition_Information, + the_packet->name, + the_packet->Prefix.id, + true + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case PARTITION_MP_ANNOUNCE_DELETE: + + _Objects_MP_Close( &_Partition_Information, the_packet->Prefix.id ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case PARTITION_MP_EXTRACT_PROXY: + + the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); + + if ( ! _Thread_Is_null( the_thread ) ) + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case PARTITION_MP_GET_BUFFER_REQUEST: + + the_packet->Prefix.return_code = rtems_partition_get_buffer( + the_packet->Prefix.id, + &the_packet->buffer + ); + + _Partition_MP_Send_response_packet( + PARTITION_MP_GET_BUFFER_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case PARTITION_MP_GET_BUFFER_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + *(void **)the_thread->Wait.return_argument = the_packet->buffer; + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case PARTITION_MP_RETURN_BUFFER_REQUEST: + + the_packet->Prefix.return_code = rtems_partition_return_buffer( + the_packet->Prefix.id, + the_packet->buffer + ); + + _Partition_MP_Send_response_packet( + PARTITION_MP_RETURN_BUFFER_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case PARTITION_MP_RETURN_BUFFER_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + } +} + +/*PAGE + * + * _Partition_MP_Send_object_was_deleted + * + * This routine is not needed by the Partition since a partition + * cannot be deleted when buffers are in use. + * + */ + +/*PAGE + * + * _Partition_MP_Send_extract_proxy + * + */ + +void _Partition_MP_Send_extract_proxy ( + void *argument +) +{ + Thread_Control *the_thread = (Thread_Control *)argument; + + _Partition_MP_Send_process_packet( + PARTITION_MP_EXTRACT_PROXY, + the_thread->Wait.id, + (rtems_name) 0, + the_thread->Object.id + ); + +} + +/*PAGE + * + * _Partition_MP_Get_packet + * + */ + +Partition_MP_Packet *_Partition_MP_Get_packet ( void ) +{ + return ( (Partition_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/partreturnbuffer.c b/cpukit/rtems/src/partreturnbuffer.c new file mode 100644 index 0000000000..8b83ab3cec --- /dev/null +++ b/cpukit/rtems/src/partreturnbuffer.c @@ -0,0 +1,79 @@ +/* + * Partition Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/address.h> +#include <rtems/score/object.h> +#include <rtems/rtems/part.h> +#include <rtems/score/thread.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_partition_return_buffer + * + * This directive will return the given buffer to the specified + * buffer partition. + * + * Input parameters: + * id - partition id + * buffer - pointer to buffer address + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_partition_return_buffer( + rtems_id id, + void *buffer +) +{ + register Partition_Control *the_partition; + Objects_Locations location; + + the_partition = _Partition_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( _Partition_Is_buffer_valid( buffer, the_partition ) ) { + _Partition_Free_buffer( the_partition, buffer ); + the_partition->number_of_used_blocks -= 1; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INVALID_ADDRESS; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return _Partition_MP_Send_request_packet( + PARTITION_MP_RETURN_BUFFER_REQUEST, + id, + buffer + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/ratemon.c b/cpukit/rtems/src/ratemon.c new file mode 100644 index 0000000000..9f17a777b8 --- /dev/null +++ b/cpukit/rtems/src/ratemon.c @@ -0,0 +1,60 @@ +/* + * Rate Monotonic Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * _Rate_monotonic_Manager_initialization + * + * This routine initializes all Rate Monotonic Manager related + * data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: The Rate Monotonic Manager is built on top of the Watchdog + * Handler. + */ + +void _Rate_monotonic_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_Rate_monotonic_Information, /* object information table */ + OBJECTS_CLASSIC_API, /* object API */ + OBJECTS_RTEMS_PERIODS, /* object class */ + Configuration_RTEMS_API.maximum_periods, + /* maximum objects of this class */ + sizeof( Rate_monotonic_Control ),/* size of this object's control block */ + false, /* true if the name is a string */ + RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/rtems/src/ratemoncancel.c b/cpukit/rtems/src/ratemoncancel.c new file mode 100644 index 0000000000..7950fe58d1 --- /dev/null +++ b/cpukit/rtems/src/ratemoncancel.c @@ -0,0 +1,68 @@ +/* + * Rate Monotonic Manager -- Cancel a Period + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * rtems_rate_monotonic_cancel + * + * This directive allows a thread to cancel a rate monotonic timer. + * + * Input parameters: + * id - rate monotonic id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful and caller is not the owning thread + * error code - if unsuccessful + */ + +rtems_status_code rtems_rate_monotonic_cancel( + rtems_id id +) +{ + Rate_monotonic_Control *the_period; + Objects_Locations location; + + the_period = _Rate_monotonic_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( !_Thread_Is_executing( the_period->owner ) ) { + _Thread_Enable_dispatch(); + return RTEMS_NOT_OWNER_OF_RESOURCE; + } + (void) _Watchdog_Remove( &the_period->Timer ); + the_period->state = RATE_MONOTONIC_INACTIVE; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/ratemoncreate.c b/cpukit/rtems/src/ratemoncreate.c new file mode 100644 index 0000000000..9fb16aa56c --- /dev/null +++ b/cpukit/rtems/src/ratemoncreate.c @@ -0,0 +1,81 @@ +/* + * Rate Monotonic Manager -- Create a Period + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * rtems_rate_monotonic_create + * + * This directive creates a rate monotonic timer and performs + * some initialization. + * + * Input parameters: + * name - name of period + * id - pointer to rate monotonic id + * + * Output parameters: + * id - rate monotonic id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_rate_monotonic_create( + rtems_name name, + rtems_id *id +) +{ + Rate_monotonic_Control *the_period; + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_period = _Rate_monotonic_Allocate(); + + if ( !the_period ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + + the_period->owner = _Thread_Executing; + the_period->state = RATE_MONOTONIC_INACTIVE; + + _Watchdog_Initialize( &the_period->Timer, NULL, 0, NULL ); + + _Rate_monotonic_Reset_statistics( the_period ); + + _Objects_Open( + &_Rate_monotonic_Information, + &the_period->Object, + (Objects_Name) name + ); + + *id = the_period->Object.id; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/ratemondata.c b/cpukit/rtems/src/ratemondata.c new file mode 100644 index 0000000000..efd461fa02 --- /dev/null +++ b/cpukit/rtems/src/ratemondata.c @@ -0,0 +1,22 @@ +/* + * Rate Monotonic Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate RTEMS period data */ +#define RTEMS_RATEMON_EXTERN + +#include <rtems/system.h> +#include <rtems/rtems/ratemon.h> diff --git a/cpukit/rtems/src/ratemondelete.c b/cpukit/rtems/src/ratemondelete.c new file mode 100644 index 0000000000..8149233079 --- /dev/null +++ b/cpukit/rtems/src/ratemondelete.c @@ -0,0 +1,66 @@ +/* + * Rate Monotonic Manager -- Delete a Period + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * rtems_rate_monotonic_delete + * + * This directive allows a thread to delete a rate monotonic timer. + * + * Input parameters: + * id - rate monotonic id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_rate_monotonic_delete( + rtems_id id +) +{ + Rate_monotonic_Control *the_period; + Objects_Locations location; + + the_period = _Rate_monotonic_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _Objects_Close( &_Rate_monotonic_Information, &the_period->Object ); + (void) _Watchdog_Remove( &the_period->Timer ); + the_period->state = RATE_MONOTONIC_INACTIVE; + _Rate_monotonic_Free( the_period ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/ratemongetstatistics.c b/cpukit/rtems/src/ratemongetstatistics.c new file mode 100644 index 0000000000..0ecd5515f1 --- /dev/null +++ b/cpukit/rtems/src/ratemongetstatistics.c @@ -0,0 +1,91 @@ +/* + * Rate Monotonic Manager -- Get Statistics + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * rtems_rate_monotonic_get_statistics + * + * This directive allows a thread to obtain statistics information on a + * period. + * + * Input parameters: + * id - rate monotonic id + * statistics - pointer to statistics control block + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + * + */ + +rtems_status_code rtems_rate_monotonic_get_statistics( + rtems_id id, + rtems_rate_monotonic_period_statistics *statistics +) +{ + Objects_Locations location; + Rate_monotonic_Control *the_period; + rtems_rate_monotonic_period_statistics *dst; + Rate_monotonic_Statistics *src; + + if ( !statistics ) + return RTEMS_INVALID_ADDRESS; + + the_period = _Rate_monotonic_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + dst = statistics; + src = &the_period->Statistics; + dst->count = src->count; + dst->missed_count = src->missed_count; + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + _Timestamp_To_timespec( &src->min_cpu_time, &dst->min_cpu_time ); + _Timestamp_To_timespec( &src->max_cpu_time, &dst->max_cpu_time ); + _Timestamp_To_timespec( &src->total_cpu_time, &dst->total_cpu_time ); + _Timestamp_To_timespec( &src->min_wall_time, &dst->min_wall_time ); + _Timestamp_To_timespec( &src->max_wall_time, &dst->max_wall_time ); + _Timestamp_To_timespec( &src->total_wall_time, &dst->total_wall_time ); + #else + dst->min_cpu_time = src->min_cpu_time; + dst->max_cpu_time = src->max_cpu_time; + dst->total_cpu_time = src->total_cpu_time; + dst->min_wall_time = src->min_wall_time; + dst->max_wall_time = src->max_wall_time; + dst->total_wall_time = src->total_wall_time; + #endif + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/ratemongetstatus.c b/cpukit/rtems/src/ratemongetstatus.c new file mode 100644 index 0000000000..c18b5b57ba --- /dev/null +++ b/cpukit/rtems/src/ratemongetstatus.c @@ -0,0 +1,118 @@ +/* + * Rate Monotonic Manager -- Get Status + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + #include <rtems/score/timespec.h> +#endif + +/*PAGE + * + * rtems_rate_monotonic_get_status + * + * This directive allows a thread to obtain status information on a + * period. + * + * Input parameters: + * id - rate monotonic id + * status - pointer to status control block + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + * + */ + +rtems_status_code rtems_rate_monotonic_get_status( + rtems_id id, + rtems_rate_monotonic_period_status *status +) +{ + Thread_CPU_usage_t executed; + Objects_Locations location; + Rate_monotonic_Period_time_t since_last_period; + Rate_monotonic_Control *the_period; + bool valid_status; + + if ( !status ) + return RTEMS_INVALID_ADDRESS; + + the_period = _Rate_monotonic_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + status->owner = the_period->owner->Object.id; + status->state = the_period->state; + + /* + * If the period is inactive, there is no information. + */ + if ( status->state == RATE_MONOTONIC_INACTIVE ) { + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + _Timespec_Set_to_zero( &status->since_last_period ); + _Timespec_Set_to_zero( &status->executed_since_last_period ); + #else + status->since_last_period = 0; + status->executed_since_last_period = 0; + #endif + + } else { + + /* + * Grab the current status. + */ + valid_status = + _Rate_monotonic_Get_status( + the_period, &since_last_period, &executed + ); + if (!valid_status) { + _Thread_Enable_dispatch(); + return RTEMS_NOT_DEFINED; + } + + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + _Timestamp_To_timespec( + &since_last_period, &status->since_last_period + ); + _Timestamp_To_timespec( + &executed, &status->executed_since_last_period + ); + #else + status->since_last_period = since_last_period; + status->executed_since_last_period = executed; + #endif + } + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/ratemonident.c b/cpukit/rtems/src/ratemonident.c new file mode 100644 index 0000000000..68df076cbb --- /dev/null +++ b/cpukit/rtems/src/ratemonident.c @@ -0,0 +1,58 @@ +/* + * Rate Monotonic Manager -- Name to Id Lookup + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * rtems_rate_monotonic_ident + * + * This directive returns the system ID associated with + * the rate monotonic period name. + * + * Input parameters: + * name - user defined period name + * id - pointer to period id + * + * Output parameters: + * *id - region id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_rate_monotonic_ident( + rtems_name name, + rtems_id *id +) +{ + Objects_Name_or_id_lookup_errors status; + + status = _Objects_Name_to_id_u32( + &_Rate_monotonic_Information, + name, + OBJECTS_SEARCH_LOCAL_NODE, + id + ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/ratemonperiod.c b/cpukit/rtems/src/ratemonperiod.c new file mode 100644 index 0000000000..e244fd5778 --- /dev/null +++ b/cpukit/rtems/src/ratemonperiod.c @@ -0,0 +1,374 @@ +/* + * Rate Monotonic Manager - Period Blocking and Status + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +bool _Rate_monotonic_Get_status( + Rate_monotonic_Control *the_period, + Rate_monotonic_Period_time_t *wall_since_last_period, + Thread_CPU_usage_t *cpu_since_last_period +) +{ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + Timestamp_Control uptime; + #endif + Thread_Control *owning_thread = the_period->owner; + Thread_CPU_usage_t used; + + /* + * Determine elapsed wall time since period initiated. + */ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + _TOD_Get_uptime( &uptime ); + _Timestamp_Subtract( + &the_period->time_period_initiated, &uptime, wall_since_last_period + ); + #else + *wall_since_last_period = + _Watchdog_Ticks_since_boot - the_period->time_period_initiated; + #endif + + /* + * Determine cpu usage since period initiated. + */ + used = owning_thread->cpu_time_used; + + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + if (owning_thread == _Thread_Executing) { + + Thread_CPU_usage_t ran; + + /* How much time time since last context switch */ + _Timestamp_Subtract( + &_Thread_Time_of_last_context_switch, &uptime, &ran + ); + + /* cpu usage += ran */ + _Timestamp_Add_to( &used, &ran ); + + /* + * The cpu usage info was reset while executing. Can't + * determine a status. + */ + if (_Timestamp_Less_than(&used, &the_period->cpu_usage_period_initiated)) + return false; + + /* used = current cpu usage - cpu usage at start of period */ + _Timestamp_Subtract( + &the_period->cpu_usage_period_initiated, + &used, + cpu_since_last_period + ); + } + #else + /* + * The cpu usage info was reset while executing. Can't + * determine a status. + */ + if (used < the_period->cpu_usage_period_initiated) + return false; + + *cpu_since_last_period = used - the_period->cpu_usage_period_initiated; + #endif + return true; +} + +void _Rate_monotonic_Initiate_statistics( + Rate_monotonic_Control *the_period +) +{ + Thread_Control *owning_thread = the_period->owner; + + /* + * If using nanosecond statistics, we need to obtain the uptime. + */ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + Timestamp_Control uptime; + + _TOD_Get_uptime( &uptime ); + #endif + + /* + * Set the starting point and the CPU time used for the statistics. + */ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + the_period->time_period_initiated = uptime; + #else + the_period->time_period_initiated = _Watchdog_Ticks_since_boot; + #endif + + the_period->cpu_usage_period_initiated = owning_thread->cpu_time_used; + + /* + * If using nanosecond statistics and the period's thread is currently + * executing, then we need to take into account how much time the + * executing thread has run since the last context switch. When this + * routine is invoked from rtems_rate_monotonic_period, the owner will + * be the executing thread. When this routine is invoked from + * _Rate_monotonic_Timeout, it will not. + */ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + if (owning_thread == _Thread_Executing) { + + rtems_thread_cpu_usage_t ran; + + /* + * Adjust the CPU time used to account for the time since last + * context switch. + */ + _Timespec_Subtract( + &_Thread_Time_of_last_context_switch, &uptime, &ran + ); + + _Timespec_Add_to( &the_period->cpu_usage_period_initiated, &ran ); + } + #endif +} + +void _Rate_monotonic_Update_statistics( + Rate_monotonic_Control *the_period +) +{ + Thread_CPU_usage_t executed; + Rate_monotonic_Period_time_t since_last_period; + Rate_monotonic_Statistics *stats; + bool valid_status; + + /* + * Assume we are only called in states where it is appropriate + * to update the statistics. This should only be RATE_MONOTONIC_ACTIVE + * and RATE_MONOTONIC_EXPIRED. + */ + + /* + * Update the counts. + */ + stats = &the_period->Statistics; + stats->count++; + + if ( the_period->state == RATE_MONOTONIC_EXPIRED ) + stats->missed_count++; + + /* + * Grab status for time statistics. + */ + valid_status = + _Rate_monotonic_Get_status( the_period, &since_last_period, &executed ); + if (!valid_status) + return; + + /* + * Update CPU time + */ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + _Timestamp_Add_to( &stats->total_cpu_time, &executed ); + + if ( _Timestamp_Less_than( &executed, &stats->min_cpu_time ) ) + stats->min_cpu_time = executed; + + if ( _Timestamp_Greater_than( &executed, &stats->max_cpu_time ) ) + stats->max_cpu_time = executed; + #else + stats->total_cpu_time += executed; + + if ( executed < stats->min_cpu_time ) + stats->min_cpu_time = executed; + + if ( executed > stats->max_cpu_time ) + stats->max_cpu_time = executed; + #endif + + /* + * Update Wall time + */ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + _Timestamp_Add_to( &stats->total_wall_time, &since_last_period ); + + if ( _Timestamp_Less_than( &since_last_period, &stats->min_wall_time ) ) + stats->min_wall_time = since_last_period; + + if ( _Timestamp_Greater_than( &since_last_period, &stats->max_wall_time ) ) + stats->max_wall_time = since_last_period; + #else + + /* Sanity check wall time */ + if ( since_last_period < executed ) + since_last_period = executed; + + stats->total_wall_time += since_last_period; + + if ( since_last_period < stats->min_wall_time ) + stats->min_wall_time = since_last_period; + + if ( since_last_period > stats->max_wall_time ) + stats->max_wall_time = since_last_period; + #endif +} + + +/*PAGE + * + * rtems_rate_monotonic_period + * + * This directive allows a thread to manipulate a rate monotonic timer. + * + * Input parameters: + * id - rate monotonic id + * length - length of period (in ticks) + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_rate_monotonic_period( + rtems_id id, + rtems_interval length +) +{ + Rate_monotonic_Control *the_period; + Objects_Locations location; + rtems_status_code return_value; + rtems_rate_monotonic_period_states local_state; + ISR_Level level; + + the_period = _Rate_monotonic_Get( id, &location ); + + switch ( location ) { + case OBJECTS_LOCAL: + if ( !_Thread_Is_executing( the_period->owner ) ) { + _Thread_Enable_dispatch(); + return RTEMS_NOT_OWNER_OF_RESOURCE; + } + + if ( length == RTEMS_PERIOD_STATUS ) { + switch ( the_period->state ) { + case RATE_MONOTONIC_INACTIVE: + return_value = RTEMS_NOT_DEFINED; + break; + case RATE_MONOTONIC_EXPIRED: + case RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING: + return_value = RTEMS_TIMEOUT; + break; + case RATE_MONOTONIC_ACTIVE: + default: /* unreached -- only to remove warnings */ + return_value = RTEMS_SUCCESSFUL; + break; + } + _Thread_Enable_dispatch(); + return( return_value ); + } + + _ISR_Disable( level ); + if ( the_period->state == RATE_MONOTONIC_INACTIVE ) { + _ISR_Enable( level ); + + /* + * Baseline statistics information for the beginning of a period. + */ + _Rate_monotonic_Initiate_statistics( the_period ); + + the_period->state = RATE_MONOTONIC_ACTIVE; + _Watchdog_Initialize( + &the_period->Timer, + _Rate_monotonic_Timeout, + id, + NULL + ); + + the_period->next_length = length; + + _Watchdog_Insert_ticks( &the_period->Timer, length ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + if ( the_period->state == RATE_MONOTONIC_ACTIVE ) { + /* + * Update statistics from the concluding period. + */ + _Rate_monotonic_Update_statistics( the_period ); + + /* + * This tells the _Rate_monotonic_Timeout that this task is + * in the process of blocking on the period and that we + * may be changing the length of the next period. + */ + the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING; + the_period->next_length = length; + + _ISR_Enable( level ); + + _Thread_Executing->Wait.id = the_period->Object.id; + _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD ); + + /* + * Did the watchdog timer expire while we were actually blocking + * on it? + */ + _ISR_Disable( level ); + local_state = the_period->state; + the_period->state = RATE_MONOTONIC_ACTIVE; + _ISR_Enable( level ); + + /* + * If it did, then we want to unblock ourself and continue as + * if nothing happen. The period was reset in the timeout routine. + */ + if ( local_state == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING ) + _Thread_Clear_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD ); + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + if ( the_period->state == RATE_MONOTONIC_EXPIRED ) { + /* + * Update statistics from the concluding period + */ + _Rate_monotonic_Update_statistics( the_period ); + + _ISR_Enable( level ); + + the_period->state = RATE_MONOTONIC_ACTIVE; + the_period->next_length = length; + + _Watchdog_Insert_ticks( &the_period->Timer, length ); + _Thread_Enable_dispatch(); + return RTEMS_TIMEOUT; + } + + /* + * These should never happen so just return invalid Id. + * - RATE_MONOTONIC_OWNER_IS_BLOCKING: + * - RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING: + */ +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/ratemonreportstatistics.c b/cpukit/rtems/src/ratemonreportstatistics.c new file mode 100644 index 0000000000..fe65151d04 --- /dev/null +++ b/cpukit/rtems/src/ratemonreportstatistics.c @@ -0,0 +1,209 @@ +/* + * Rate Monotonic Manager -- Report Statistics for All Periods + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <stdlib.h> +#include <ctype.h> +#include <inttypes.h> + +#include <rtems/bspIo.h> +#include <rtems/score/timespec.h> + +#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + /* We print to 1/10's of milliseconds */ + #define NANOSECONDS_DIVIDER 1000 + #define PERCENT_FMT "%04" PRId32 + #define NANOSECONDS_FMT "%06" PRId32 +#endif + +/* + * This directive allows a thread to print the statistics information + * on ALL period instances which have non-zero counts using printk. + * + * The implementation of this directive straddles the fence between + * inside and outside of RTEMS. It is presented as part of the Manager + * but actually uses other services of the Manager. + */ +void rtems_rate_monotonic_report_statistics_with_plugin( + void *context, + rtems_printk_plugin_t print +) +{ + rtems_status_code status; + rtems_id id; + rtems_rate_monotonic_period_statistics the_stats; + rtems_rate_monotonic_period_status the_status; + char name[5]; + + if ( !print ) + return; + + (*print)( context, "Period information by period\n" ); + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + (*print)( context, "--- CPU times are in seconds ---\n" ); + (*print)( context, "--- Wall times are in seconds ---\n" ); + #endif +/* +Layout by columns -- in memory of Hollerith :) + +1234567890123456789012345678901234567890123456789012345678901234567890123456789\ + ID OWNER COUNT MISSED X +ididididid NNNN ccccc mmmmmm X + + Uncomment the following if you are tinkering with the formatting. + Be sure to test the various cases. + (*print)( context,"\ +1234567890123456789012345678901234567890123456789012345678901234567890123456789\ +\n"); +*/ + (*print)( context, " ID OWNER COUNT MISSED " + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + " " + #endif + "CPU TIME " + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + " " + #endif + " WALL TIME\n" + ); + (*print)( context, " " + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + " " + #endif + "MIN/MAX/AVG " + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + " " + #endif + " MIN/MAX/AVG\n" + ); + + /* + * Cycle through all possible ids and try to report on each one. If it + * is a period that is inactive, we just get an error back. No big deal. + */ + for ( id=_Rate_monotonic_Information.minimum_id ; + id <= _Rate_monotonic_Information.maximum_id ; + id++ ) { + status = rtems_rate_monotonic_get_statistics( id, &the_stats ); + if ( status != RTEMS_SUCCESSFUL ) + continue; + + /* If the above passed, so should this but check it anyway */ + #if defined(RTEMS_DEBUG) + status = rtems_rate_monotonic_get_status( id, &the_status ); + if ( status != RTEMS_SUCCESSFUL ) + continue; + #else + (void) rtems_rate_monotonic_get_status( id, &the_status ); + #endif + + rtems_object_get_name( the_status.owner, sizeof(name), name ); + + /* + * Print part of report line that is not dependent on granularity + */ + (*print)( context, + "0x%08" PRIx32 " %4s %5" PRId32 " %6" PRId32 " ", + id, name, + the_stats.count, the_stats.missed_count + ); + + /* + * If the count is zero, don't print statistics + */ + if (the_stats.count == 0) { + (*print)( context, "\n" ); + continue; + } + + /* + * print CPU Usage part of statistics + */ + { + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + struct timespec cpu_average; + struct timespec *min_cpu = &the_stats.min_cpu_time; + struct timespec *max_cpu = &the_stats.max_cpu_time; + struct timespec *total_cpu = &the_stats.total_cpu_time; + + _Timespec_Divide_by_integer( total_cpu, the_stats.count, &cpu_average ); + (*print)( context, + "%" PRId32 "." NANOSECONDS_FMT "/" /* min cpu time */ + "%" PRId32 "." NANOSECONDS_FMT "/" /* max cpu time */ + "%" PRId32 "." NANOSECONDS_FMT " ", /* avg cpu time */ + _Timespec_Get_seconds( min_cpu ), + _Timespec_Get_nanoseconds( min_cpu ) / NANOSECONDS_DIVIDER, + _Timespec_Get_seconds( max_cpu ), + _Timespec_Get_nanoseconds( max_cpu ) / NANOSECONDS_DIVIDER, + _Timespec_Get_seconds( &cpu_average ), + _Timespec_Get_nanoseconds( &cpu_average ) / NANOSECONDS_DIVIDER + ); + #else + uint32_t ival_cpu, fval_cpu; + + ival_cpu = the_stats.total_cpu_time * 100 / the_stats.count; + fval_cpu = ival_cpu % 100; + ival_cpu /= 100; + + (*print)( context, + "%3" PRId32 "/%4" PRId32 "/%3" PRId32 ".%02" PRId32 " ", + the_stats.min_cpu_time, the_stats.max_cpu_time, ival_cpu, fval_cpu + ); + #endif + } + + /* + * print wall time part of statistics + */ + { + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + struct timespec wall_average; + struct timespec *min_wall = &the_stats.min_wall_time; + struct timespec *max_wall = &the_stats.max_wall_time; + struct timespec *total_wall = &the_stats.total_wall_time; + + _Timespec_Divide_by_integer(total_wall, the_stats.count, &wall_average); + (*print)( context, + "%" PRId32 "." NANOSECONDS_FMT "/" /* min wall time */ + "%" PRId32 "." NANOSECONDS_FMT "/" /* max wall time */ + "%" PRId32 "." NANOSECONDS_FMT "\n", /* avg wall time */ + _Timespec_Get_seconds( min_wall ), + _Timespec_Get_nanoseconds( min_wall ) / NANOSECONDS_DIVIDER, + _Timespec_Get_seconds( max_wall ), + _Timespec_Get_nanoseconds( max_wall ) / NANOSECONDS_DIVIDER, + _Timespec_Get_seconds( &wall_average ), + _Timespec_Get_nanoseconds( &wall_average ) / NANOSECONDS_DIVIDER + ); + #else + uint32_t ival_wall, fval_wall; + + ival_wall = the_stats.total_wall_time * 100 / the_stats.count; + fval_wall = ival_wall % 100; + ival_wall /= 100; + (*print)( context, + "%3" PRId32 "/%4" PRId32 "/%3" PRId32 ".%02" PRId32 "\n", + the_stats.min_wall_time, the_stats.max_wall_time, ival_wall, fval_wall + ); + #endif + } + } +} + +void rtems_rate_monotonic_report_statistics( void ) +{ + rtems_rate_monotonic_report_statistics_with_plugin( NULL, printk_plugin ); +} diff --git a/cpukit/rtems/src/ratemonresetall.c b/cpukit/rtems/src/ratemonresetall.c new file mode 100644 index 0000000000..39a2ec91e7 --- /dev/null +++ b/cpukit/rtems/src/ratemonresetall.c @@ -0,0 +1,55 @@ +/* + * Rate Monotonic Manager -- Reset Statistics for All Periods + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +/* + * rtems_rate_monotonic_reset_all_statistics + */ +void rtems_rate_monotonic_reset_all_statistics( void ) +{ + Objects_Id id; + + /* + * Prevent allocation or deallocation of any of the periods while + * we are cycling. Also this is an optimization which ensures that + * we only disable/enable once. The call to + * rtems_rate_monotonic_reset_statistics will be in a nested dispatch + * disabled critical section. + */ + _Thread_Disable_dispatch(); + + /* + * Cycle through all possible ids and try to reset each one. If it + * is a period that is inactive, we just get an error back. No big deal. + */ + for ( id=_Rate_monotonic_Information.minimum_id ; + id <= _Rate_monotonic_Information.maximum_id ; + id++ ) { + (void) rtems_rate_monotonic_reset_statistics( id ); + } + + /* + * Done so exit thread dispatching disabled critical section. + */ + _Thread_Enable_dispatch(); +} diff --git a/cpukit/rtems/src/ratemonresetstatistics.c b/cpukit/rtems/src/ratemonresetstatistics.c new file mode 100644 index 0000000000..065c31aec2 --- /dev/null +++ b/cpukit/rtems/src/ratemonresetstatistics.c @@ -0,0 +1,65 @@ +/* + * Rate Monotonic Manager -- Reset Statistics + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * rtems_rate_monotonic_reset_statistics + * + * This directive allows a thread to reset the statistics information + * on a specific period instance. + * + * Input parameters: + * id - rate monotonic id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + * + */ + +rtems_status_code rtems_rate_monotonic_reset_statistics( + rtems_id id +) +{ + Objects_Locations location; + Rate_monotonic_Control *the_period; + + the_period = _Rate_monotonic_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _Rate_monotonic_Reset_statistics( the_period ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/ratemontimeout.c b/cpukit/rtems/src/ratemontimeout.c new file mode 100644 index 0000000000..de1674636c --- /dev/null +++ b/cpukit/rtems/src/ratemontimeout.c @@ -0,0 +1,83 @@ +/* + * Rate Monotonic Manager -- Period End Timeout Handler + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * _Rate_monotonic_Timeout + * + * This routine processes a period ending. If the owning thread + * is waiting for the period, that thread is unblocked and the + * period reinitiated. Otherwise, the period is expired. + * This routine is called by the watchdog handler. + * + * Input parameters: + * id - period id + * + * Output parameters: NONE + */ + +void _Rate_monotonic_Timeout( + Objects_Id id, + void *ignored +) +{ + Rate_monotonic_Control *the_period; + Objects_Locations location; + Thread_Control *the_thread; + + /* + * When we get here, the Timer is already off the chain so we do not + * have to worry about that -- hence no _Watchdog_Remove(). + */ + the_period = _Rate_monotonic_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + the_thread = the_period->owner; + if ( _States_Is_waiting_for_period( the_thread->current_state ) && + the_thread->Wait.id == the_period->Object.id ) { + _Thread_Unblock( the_thread ); + + _Rate_monotonic_Initiate_statistics( the_period ); + + _Watchdog_Insert_ticks( &the_period->Timer, the_period->next_length ); + } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) { + the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING; + + _Rate_monotonic_Initiate_statistics( the_period ); + + _Watchdog_Insert_ticks( &the_period->Timer, the_period->next_length ); + } else + the_period->state = RATE_MONOTONIC_EXPIRED; + _Thread_Unnest_dispatch(); + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* impossible */ +#endif + case OBJECTS_ERROR: + break; + } +} diff --git a/cpukit/rtems/src/region.c b/cpukit/rtems/src/region.c new file mode 100644 index 0000000000..1b06ee60b5 --- /dev/null +++ b/cpukit/rtems/src/region.c @@ -0,0 +1,70 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * _Region_Manager_initialization + * + * This routine initializes all region manager related data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Region_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_Region_Information, /* object information table */ + OBJECTS_CLASSIC_API, /* object API */ + OBJECTS_RTEMS_REGIONS, /* object class */ + Configuration_RTEMS_API.maximum_regions, + /* maximum objects of this class */ + sizeof( Region_Control ), /* size of this object's control block */ + false, /* true if the name is a string */ + RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); + + /* + * Register the MP Process Packet routine. + */ + +#if defined(RTEMS_MULTIPROCESSING) + _MPCI_Register_packet_processor( + MP_PACKET_REGION, + 0 /* XXX _Region_MP_Process_packet */ + ); +#endif + +} diff --git a/cpukit/rtems/src/regioncreate.c b/cpukit/rtems/src/regioncreate.c new file mode 100644 index 0000000000..90aca79ea7 --- /dev/null +++ b/cpukit/rtems/src/regioncreate.c @@ -0,0 +1,118 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * rtems_region_create + * + * This directive creates a region of physical contiguous memory area + * from which variable sized segments can be allocated. + * + * Input parameters: + * name - user defined region name + * starting_address - physical start address of region + * length - physical length in bytes + * page_size - page size in bytes + * attribute_set - region attributes + * id - address of region id to set + * + * Output parameters: + * id - region id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_create( + rtems_name name, + void *starting_address, + uintptr_t length, + uintptr_t page_size, + rtems_attribute attribute_set, + rtems_id *id +) +{ + rtems_status_code return_status; + Region_Control *the_region; + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + if ( !starting_address ) + return RTEMS_INVALID_ADDRESS; + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + + _RTEMS_Lock_allocator(); /* to prevent deletion */ + + the_region = _Region_Allocate(); + + if ( !the_region ) + return_status = RTEMS_TOO_MANY; + + else { + + the_region->maximum_segment_size = _Heap_Initialize( + &the_region->Memory, starting_address, length, page_size + ); + + if ( !the_region->maximum_segment_size ) { + _Region_Free( the_region ); + return_status = RTEMS_INVALID_SIZE; + } + + else { + + the_region->starting_address = starting_address; + the_region->length = length; + the_region->page_size = page_size; + the_region->attribute_set = attribute_set; + the_region->number_of_used_blocks = 0; + + _Thread_queue_Initialize( + &the_region->Wait_queue, + _Attributes_Is_priority( attribute_set ) ? + THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, + STATES_WAITING_FOR_SEGMENT, + RTEMS_TIMEOUT + ); + + _Objects_Open( + &_Region_Information, + &the_region->Object, + (Objects_Name) name + ); + + *id = the_region->Object.id; + return_status = RTEMS_SUCCESSFUL; + } + } + + _RTEMS_Unlock_allocator(); + return return_status; +} diff --git a/cpukit/rtems/src/regiondata.c b/cpukit/rtems/src/regiondata.c new file mode 100644 index 0000000000..9ecce9e7bb --- /dev/null +++ b/cpukit/rtems/src/regiondata.c @@ -0,0 +1,22 @@ +/* + * Region Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate RTEMS Region data */ +#define RTEMS_REGION_EXTERN + +#include <rtems/system.h> +#include <rtems/rtems/region.h> diff --git a/cpukit/rtems/src/regiondelete.c b/cpukit/rtems/src/regiondelete.c new file mode 100644 index 0000000000..8217e68f71 --- /dev/null +++ b/cpukit/rtems/src/regiondelete.c @@ -0,0 +1,82 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * rtems_region_delete + * + * This directive allows a thread to delete a region specified by + * the region identifier, provided that none of its segments are + * still allocated. + * + * Input parameters: + * id - region id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_delete( + rtems_id id +) +{ + Objects_Locations location; + rtems_status_code return_status; + Region_Control *the_region; + + _RTEMS_Lock_allocator(); + + the_region = _Region_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _Region_Debug_Walk( the_region, 5 ); + if ( the_region->number_of_used_blocks != 0 ) + return_status = RTEMS_RESOURCE_IN_USE; + else { + _Objects_Close( &_Region_Information, &the_region->Object ); + _Region_Free( the_region ); + return_status = RTEMS_SUCCESSFUL; + } + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ + break; +#endif + + case OBJECTS_ERROR: + default: + return_status = RTEMS_INVALID_ID; + break; + } + + _RTEMS_Unlock_allocator(); + return return_status; +} diff --git a/cpukit/rtems/src/regionextend.c b/cpukit/rtems/src/regionextend.c new file mode 100644 index 0000000000..f4b6c93c2d --- /dev/null +++ b/cpukit/rtems/src/regionextend.c @@ -0,0 +1,96 @@ +/* + * Region Manager - Extend (add memory to) a Region + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * rtems_region_extend + * + * This directive attempts to grow a region of physical contiguous memory area + * from which variable sized segments can be allocated. + * + * Input parameters: + * id - id of region to grow + * start - starting address of memory area for extension + * length - physical length in bytes to grow the region + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_extend( + rtems_id id, + void *starting_address, + uintptr_t length +) +{ + uintptr_t amount_extended; + bool extend_ok; + Objects_Locations location; + rtems_status_code return_status; + Region_Control *the_region; + + if ( !starting_address ) + return RTEMS_INVALID_ADDRESS; + + _RTEMS_Lock_allocator(); /* to prevent deletion */ + + the_region = _Region_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + extend_ok = _Heap_Extend( + &the_region->Memory, + starting_address, + length, + &amount_extended + ); + + if ( extend_ok ) { + the_region->length += amount_extended; + the_region->maximum_segment_size += amount_extended; + return_status = RTEMS_SUCCESSFUL; + } else { + return_status = RTEMS_INVALID_ADDRESS; + } + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ + break; +#endif + + case OBJECTS_ERROR: + default: + return_status = RTEMS_INVALID_ID; + break; + } + + _RTEMS_Unlock_allocator(); + return return_status; +} diff --git a/cpukit/rtems/src/regiongetfreeinfo.c b/cpukit/rtems/src/regiongetfreeinfo.c new file mode 100644 index 0000000000..fcfa3bc8b2 --- /dev/null +++ b/cpukit/rtems/src/regiongetfreeinfo.c @@ -0,0 +1,88 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/apimutex.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * rtems_region_get_free_information + * + * This directive will return information about the free blocks + * in the region specified. Information about the used blocks + * will be returned as zero. + * + * Input parameters: + * id - region id + * the_info - pointer to region information block + * + * Output parameters: + * *the_info - region information block filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_get_free_information( + rtems_id id, + Heap_Information_block *the_info +) +{ + Objects_Locations location; + rtems_status_code return_status; + register Region_Control *the_region; + + if ( !the_info ) + return RTEMS_INVALID_ADDRESS; + + _RTEMS_Lock_allocator(); + + the_region = _Region_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + the_info->Used.number = 0; + the_info->Used.total = 0; + the_info->Used.largest = 0; + + _Heap_Get_free_information( &the_region->Memory, &the_info->Free ); + + return_status = RTEMS_SUCCESSFUL; + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ + break; +#endif + + case OBJECTS_ERROR: + default: + return_status = RTEMS_INVALID_ID; + break; + } + + _RTEMS_Unlock_allocator(); + return return_status; +} diff --git a/cpukit/rtems/src/regiongetinfo.c b/cpukit/rtems/src/regiongetinfo.c new file mode 100644 index 0000000000..306f3da947 --- /dev/null +++ b/cpukit/rtems/src/regiongetinfo.c @@ -0,0 +1,80 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/apimutex.h> +#include <rtems/score/thread.h> + +/*PAGE + * + * rtems_region_get_information + * + * This directive will return information about the region specified. + * + * Input parameters: + * id - region id + * the_info - pointer to region information block + * + * Output parameters: + * *the_info - region information block filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_get_information( + rtems_id id, + Heap_Information_block *the_info +) +{ + Objects_Locations location; + rtems_status_code return_status; + register Region_Control *the_region; + + if ( !the_info ) + return RTEMS_INVALID_ADDRESS; + + _RTEMS_Lock_allocator(); + + the_region = _Region_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _Heap_Get_information( &the_region->Memory, the_info ); + return_status = RTEMS_SUCCESSFUL; + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ + break; +#endif + + case OBJECTS_ERROR: + default: + return_status = RTEMS_INVALID_ID; + break; + } + + _RTEMS_Unlock_allocator(); + return return_status; +} diff --git a/cpukit/rtems/src/regiongetsegment.c b/cpukit/rtems/src/regiongetsegment.c new file mode 100644 index 0000000000..c8c8cfa0fb --- /dev/null +++ b/cpukit/rtems/src/regiongetsegment.c @@ -0,0 +1,131 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * rtems_region_get_segment + * + * This directive will obtain a segment from the given region. + * + * Input parameters: + * id - region id + * size - segment size in bytes + * option_set - wait option + * timeout - number of ticks to wait (0 means wait forever) + * segment - pointer to segment address + * + * Output parameters: + * segment - pointer to segment address filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_get_segment( + rtems_id id, + uintptr_t size, + rtems_option option_set, + rtems_interval timeout, + void **segment +) +{ + Thread_Control *executing; + Objects_Locations location; + rtems_status_code return_status; + Region_Control *the_region; + void *the_segment; + + if ( !segment ) + return RTEMS_INVALID_ADDRESS; + + *segment = NULL; + + if ( size == 0 ) + return RTEMS_INVALID_SIZE; + + _RTEMS_Lock_allocator(); + + executing = _Thread_Executing; + the_region = _Region_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( size > the_region->maximum_segment_size ) + return_status = RTEMS_INVALID_SIZE; + + else { + _Region_Debug_Walk( the_region, 1 ); + + the_segment = _Region_Allocate_segment( the_region, size ); + + _Region_Debug_Walk( the_region, 2 ); + + if ( the_segment ) { + the_region->number_of_used_blocks += 1; + *segment = the_segment; + return_status = RTEMS_SUCCESSFUL; + } else if ( _Options_Is_no_wait( option_set ) ) { + return_status = RTEMS_UNSATISFIED; + } else { + /* + * Switch from using the memory allocation mutex to using a + * dispatching disabled critical section. We have to do this + * because this thread is going to block. + */ + _Thread_Disable_dispatch(); + _RTEMS_Unlock_allocator(); + + executing->Wait.queue = &the_region->Wait_queue; + executing->Wait.id = id; + executing->Wait.count = size; + executing->Wait.return_argument = segment; + + _Thread_queue_Enter_critical_section( &the_region->Wait_queue ); + + _Thread_queue_Enqueue( &the_region->Wait_queue, timeout ); + + _Thread_Enable_dispatch(); + + return (rtems_status_code) executing->Wait.return_code; + } + } + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ + break; +#endif + + case OBJECTS_ERROR: + default: + return_status = RTEMS_INVALID_ID; + break; + } + + _RTEMS_Unlock_allocator(); + return return_status; +} diff --git a/cpukit/rtems/src/regiongetsegmentsize.c b/cpukit/rtems/src/regiongetsegmentsize.c new file mode 100644 index 0000000000..601145128a --- /dev/null +++ b/cpukit/rtems/src/regiongetsegmentsize.c @@ -0,0 +1,83 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * rtems_region_get_segment_size + * + * This directive will return the size of the segment indicated + * + * Input parameters: + * id - region id + * segment - segment address + * size - pointer to segment size in bytes + * + * Output parameters: + * size - segment size in bytes filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_get_segment_size( + rtems_id id, + void *segment, + uintptr_t *size +) +{ + Objects_Locations location; + rtems_status_code return_status = RTEMS_SUCCESSFUL; + register Region_Control *the_region; + + if ( !segment ) + return RTEMS_INVALID_ADDRESS; + + if ( !size ) + return RTEMS_INVALID_ADDRESS; + + _RTEMS_Lock_allocator(); + + the_region = _Region_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( !_Heap_Size_of_alloc_area( &the_region->Memory, segment, size ) ) + return_status = RTEMS_INVALID_ADDRESS; + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ + break; +#endif + + case OBJECTS_ERROR: + return_status = RTEMS_INVALID_ID; + break; + } + + _RTEMS_Unlock_allocator(); + return return_status; +} diff --git a/cpukit/rtems/src/regionident.c b/cpukit/rtems/src/regionident.c new file mode 100644 index 0000000000..55df94d48c --- /dev/null +++ b/cpukit/rtems/src/regionident.c @@ -0,0 +1,61 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * rtems_region_ident + * + * This directive returns the system ID associated with + * the region name. + * + * Input parameters: + * name - user defined region name + * id - pointer to region id + * + * Output parameters: + * *id - region id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_ident( + rtems_name name, + rtems_id *id +) +{ + Objects_Name_or_id_lookup_errors status; + + status = _Objects_Name_to_id_u32( + &_Region_Information, + name, + OBJECTS_SEARCH_LOCAL_NODE, + id + ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/regionmp.c b/cpukit/rtems/src/regionmp.c new file mode 100644 index 0000000000..a978c2d288 --- /dev/null +++ b/cpukit/rtems/src/regionmp.c @@ -0,0 +1,315 @@ +/* + * Multiprocessing Support for the Region Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/score/mpci.h> +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * _Region_MP_Send_process_packet + * + */ + +void _Region_MP_Send_process_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + rtems_name name, + Objects_Id proxy_id +) +{ + Region_MP_Packet *the_packet; + uint32_t node; + + switch ( operation ) { + + case REGION_MP_ANNOUNCE_CREATE: + case REGION_MP_ANNOUNCE_DELETE: + case REGION_MP_EXTRACT_PROXY: + + the_packet = _Region_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_REGION; + the_packet->Prefix.length = sizeof ( Region_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Region_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = region_id; + the_packet->name = name; + the_packet->proxy_id = proxy_id; + + if ( operation == REGION_MP_EXTRACT_PROXY ) + node = _Objects_Get_node( region_id ); + else + node = MPCI_ALL_NODES; + + _MPCI_Send_process_packet( node, &the_packet->Prefix ); + break; + + case REGION_MP_GET_SEGMENT_REQUEST: + case REGION_MP_GET_SEGMENT_RESPONSE: + case REGION_MP_RETURN_SEGMENT_REQUEST: + case REGION_MP_RETURN_SEGMENT_RESPONSE: + break; + } +} + +/*PAGE + * + * _Region_MP_Send_request_packet + * + */ + +rtems_status_code _Region_MP_Send_request_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + void *segment, + intptr_t size, + rtems_option option_set, + rtems_interval timeout +) +{ + Region_MP_Packet *the_packet; + + switch ( operation ) { + + case REGION_MP_GET_SEGMENT_REQUEST: + case REGION_MP_RETURN_SEGMENT_REQUEST: + + the_packet = _Region_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_REGION; + the_packet->Prefix.length = sizeof ( Region_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Region_MP_Packet ); + if ( ! _Options_Is_no_wait(option_set)) + the_packet->Prefix.timeout = timeout; + + the_packet->operation = operation; + the_packet->Prefix.id = region_id; + the_packet->segment = segment; + the_packet->size = size; + the_packet->option_set = option_set; + + return (rtems_status_code) _MPCI_Send_request_packet( + _Objects_Get_node( region_id ), + &the_packet->Prefix, + STATES_READY /* Not used */ + ); + break; + + case REGION_MP_ANNOUNCE_CREATE: + case REGION_MP_ANNOUNCE_DELETE: + case REGION_MP_EXTRACT_PROXY: + case REGION_MP_GET_SEGMENT_RESPONSE: + case REGION_MP_RETURN_SEGMENT_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_INTERNAL_ERROR; +} + +/*PAGE + * + * _Region_MP_Send_response_packet + * + */ + +void _Region_MP_Send_response_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + Thread_Control *the_thread +) +{ + Region_MP_Packet *the_packet; + + switch ( operation ) { + + case REGION_MP_GET_SEGMENT_RESPONSE: + case REGION_MP_RETURN_SEGMENT_RESPONSE: + + the_packet = ( Region_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + _Objects_Get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case REGION_MP_ANNOUNCE_CREATE: + case REGION_MP_ANNOUNCE_DELETE: + case REGION_MP_EXTRACT_PROXY: + case REGION_MP_GET_SEGMENT_REQUEST: + case REGION_MP_RETURN_SEGMENT_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Region_MP_Process_packet + * + */ + +void _Region_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Region_MP_Packet *the_packet; + Thread_Control *the_thread; + bool ignored; + + the_packet = (Region_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case REGION_MP_ANNOUNCE_CREATE: + + ignored = _Objects_MP_Allocate_and_open( + &_Region_Information, + the_packet->name, + the_packet->Prefix.id, + true + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case REGION_MP_ANNOUNCE_DELETE: + + _Objects_MP_Close( &_Region_Information, the_packet->Prefix.id ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case REGION_MP_EXTRACT_PROXY: + + the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); + + if ( ! _Thread_Is_null( the_thread ) ) + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case REGION_MP_GET_SEGMENT_REQUEST: + + the_packet->Prefix.return_code = rtems_region_get_segment( + the_packet->Prefix.id, + the_packet->size, + the_packet->option_set, + the_packet->Prefix.timeout, + &the_packet->segment + ); + + _Region_MP_Send_response_packet( + REGION_MP_GET_SEGMENT_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case REGION_MP_GET_SEGMENT_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + *(void **)the_thread->Wait.return_argument = the_packet->segment; + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case REGION_MP_RETURN_SEGMENT_REQUEST: + + the_packet->Prefix.return_code = rtems_region_return_segment( + the_packet->Prefix.id, + the_packet->segment + ); + + _Region_MP_Send_response_packet( + REGION_MP_RETURN_SEGMENT_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case REGION_MP_RETURN_SEGMENT_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + } +} + +/*PAGE + * + * _Region_MP_Send_object_was_deleted + * + * This routine is not needed by the Region since a region + * cannot be deleted when segments are in use. + * + */ + +/*PAGE + * + * _Region_MP_Send_extract_proxy + * + */ + +void _Region_MP_Send_extract_proxy ( + void *argument +) +{ + Thread_Control *the_thread = (Thread_Control *)argument; + + _Region_MP_Send_process_packet( + REGION_MP_EXTRACT_PROXY, + the_thread->Wait.id, + (rtems_name) 0, + the_thread->Object.id + ); +} + +/*PAGE + * + * _Region_MP_Get_packet + * + */ + +Region_MP_Packet *_Region_MP_Get_packet ( void ) +{ + return ( (Region_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/regionprocessqueue.c b/cpukit/rtems/src/regionprocessqueue.c new file mode 100644 index 0000000000..011e646a6c --- /dev/null +++ b/cpukit/rtems/src/regionprocessqueue.c @@ -0,0 +1,87 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * _Region_Process_queue + * + * If enough memory is available to satisfy the rtems_region_get_segment of + * the first blocked task, then that task and as many subsequent tasks as + * possible will be unblocked with their requests satisfied. + * + * Input parameters: + * the_region - the region + * + * Output parameters: + * none + */ + +void _Region_Process_queue( + Region_Control *the_region +) +{ + Thread_Control *the_thread; + void *the_segment; + /* + * Switch from using the memory allocation mutex to using a + * dispatching disabled critical section. We have to do this + * because this thread may unblock one or more threads that were + * waiting on memory. + * + * NOTE: Be sure to disable dispatching before unlocking the mutex + * since we do not want to open a window where a context + * switch could occur. + */ + _Thread_Disable_dispatch(); + _RTEMS_Unlock_allocator(); + + /* + * NOTE: The following loop is O(n) where n is the number of + * threads whose memory request is satisfied. + */ + for ( ; ; ) { + the_thread = _Thread_queue_First( &the_region->Wait_queue ); + + if ( the_thread == NULL ) + break; + + the_segment = (void **) _Region_Allocate_segment( + the_region, + the_thread->Wait.count + ); + + if ( the_segment == NULL ) + break; + + *(void **)the_thread->Wait.return_argument = the_segment; + the_region->number_of_used_blocks += 1; + _Thread_queue_Extract( &the_region->Wait_queue, the_thread ); + the_thread->Wait.return_code = RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); +} diff --git a/cpukit/rtems/src/regionresizesegment.c b/cpukit/rtems/src/regionresizesegment.c new file mode 100644 index 0000000000..737e31436e --- /dev/null +++ b/cpukit/rtems/src/regionresizesegment.c @@ -0,0 +1,109 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * rtems_region_resize_segment + * + * This directive will try to resize segment to the new size 'size' + * "in place". + * + * Input parameters: + * id - region id + * segment - pointer to segment address + * size - new required size + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_resize_segment( + rtems_id id, + void *segment, + uintptr_t size, + uintptr_t *old_size +) +{ + uintptr_t avail_size; + Objects_Locations location; + uintptr_t osize; + rtems_status_code return_status; + Heap_Resize_status status; + register Region_Control *the_region; + + if ( !old_size ) + return RTEMS_INVALID_ADDRESS; + + _RTEMS_Lock_allocator(); + + the_region = _Region_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + _Region_Debug_Walk( the_region, 7 ); + + status = _Heap_Resize_block( + &the_region->Memory, + segment, + (uint32_t) size, + &osize, + &avail_size + ); + *old_size = (uint32_t) osize; + + _Region_Debug_Walk( the_region, 8 ); + + if ( status == HEAP_RESIZE_SUCCESSFUL ) + _Region_Process_queue( the_region ); /* unlocks allocator */ + else + _RTEMS_Unlock_allocator(); + + + if (status == HEAP_RESIZE_SUCCESSFUL) + return RTEMS_SUCCESSFUL; + if (status == HEAP_RESIZE_UNSATISFIED) + return RTEMS_UNSATISFIED; + return RTEMS_INVALID_ADDRESS; + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ + break; +#endif + + case OBJECTS_ERROR: + default: + return_status = RTEMS_INVALID_ID; + break; + } + + _RTEMS_Unlock_allocator(); + return return_status; +} diff --git a/cpukit/rtems/src/regionreturnsegment.c b/cpukit/rtems/src/regionreturnsegment.c new file mode 100644 index 0000000000..b98ff1d486 --- /dev/null +++ b/cpukit/rtems/src/regionreturnsegment.c @@ -0,0 +1,111 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef RTEMS_REGION_SHRED_ON_FREE +#include <string.h> + +#ifndef RTEMS_REGION_FREE_SHRED_PATTERN +#define RTEMS_REGION_FREE_SHRED_PATTERN 0x00 +#endif +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/region.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * rtems_region_return_segment + * + * This directive will return a segment to its region. + * + * Input parameters: + * id - region id + * segment - pointer to segment address + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_return_segment( + rtems_id id, + void *segment +) +{ + Objects_Locations location; + rtems_status_code return_status; +#ifdef RTEMS_REGION_FREE_SHRED_PATTERN + uint32_t size; +#endif + int status; + register Region_Control *the_region; + + _RTEMS_Lock_allocator(); + + the_region = _Region_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + _Region_Debug_Walk( the_region, 3 ); + +#ifdef RTEMS_REGION_FREE_SHRED_PATTERN + if ( !_Heap_Size_of_alloc_area( &the_region->Memory, segment, &size ) ) + return_status = RTEMS_INVALID_ADDRESS; + else { + memset( segment, (RTEMS_REGION_FREE_SHRED_PATTERN & 0xFF), size ); +#endif + status = _Region_Free_segment( the_region, segment ); + + _Region_Debug_Walk( the_region, 4 ); + + if ( !status ) + return_status = RTEMS_INVALID_ADDRESS; + else { + the_region->number_of_used_blocks -= 1; + + _Region_Process_queue(the_region); /* unlocks allocator */ + + return RTEMS_SUCCESSFUL; + } +#ifdef RTEMS_REGION_FREE_SHRED_PATTERN + } +#endif + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* this error cannot be returned */ + break; +#endif + + case OBJECTS_ERROR: + default: + return_status = RTEMS_INVALID_ID; + break; + } + + _RTEMS_Unlock_allocator(); + return return_status; +} diff --git a/cpukit/rtems/src/rtclock.c b/cpukit/rtems/src/rtclock.c new file mode 100644 index 0000000000..652f443677 --- /dev/null +++ b/cpukit/rtems/src/rtclock.c @@ -0,0 +1,26 @@ +/* + * Clock Manager + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/* No initialization routine */ diff --git a/cpukit/rtems/src/rtemsbuildid.c b/cpukit/rtems/src/rtemsbuildid.c new file mode 100644 index 0000000000..916d1dfab5 --- /dev/null +++ b/cpukit/rtems/src/rtemsbuildid.c @@ -0,0 +1,31 @@ +/* + * RTEMS Object Helper -- Build an Object Id + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/types.h> + +#undef rtems_build_id +rtems_id rtems_build_id( + uint32_t api, + uint32_t class, + uint32_t node, + uint32_t index +) +{ + return _Objects_Build_id( api, class, node, index ); +} diff --git a/cpukit/rtems/src/rtemsbuildname.c b/cpukit/rtems/src/rtemsbuildname.c new file mode 100644 index 0000000000..1fbd727297 --- /dev/null +++ b/cpukit/rtems/src/rtemsbuildname.c @@ -0,0 +1,31 @@ +/* + * RTEMS Object Helper -- Build an Object Name + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/types.h> + +#undef rtems_build_name +rtems_name rtems_build_name( + char C1, + char C2, + char C3, + char C4 +) +{ + return _Objects_Build_name( C1, C2, C3, C4 ); +} diff --git a/cpukit/rtems/src/rtemsobjectapimaximumclass.c b/cpukit/rtems/src/rtemsobjectapimaximumclass.c new file mode 100644 index 0000000000..16133084d2 --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectapimaximumclass.c @@ -0,0 +1,27 @@ +/* + * RTEMS Object Helper -- Get Greatest Valid Class for an API + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/types.h> + +int rtems_object_api_maximum_class( + int api +) +{ + return _Objects_API_maximum_class(api); +} diff --git a/cpukit/rtems/src/rtemsobjectapiminimumclass.c b/cpukit/rtems/src/rtemsobjectapiminimumclass.c new file mode 100644 index 0000000000..a3995eb32a --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectapiminimumclass.c @@ -0,0 +1,29 @@ +/* + * RTEMS Object Helper -- Get Least Valid Class for an API + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/types.h> + +uint32_t rtems_object_api_minimum_class( + uint32_t api +) +{ + if ( _Objects_Is_api_valid( api ) ) + return 1; + return -1; +} diff --git a/cpukit/rtems/src/rtemsobjectgetapiclassname.c b/cpukit/rtems/src/rtemsobjectgetapiclassname.c new file mode 100644 index 0000000000..2ea697bc37 --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectgetapiclassname.c @@ -0,0 +1,81 @@ +/* + * RTEMS Object Helper -- Obtain Name of API + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/object.h> + +#include <rtems/assoc.h> + +rtems_assoc_t rtems_object_api_internal_assoc[] = { + { "Thread", OBJECTS_INTERNAL_THREADS, 0}, + { "Mutex", OBJECTS_INTERNAL_MUTEXES, 0}, +}; + +rtems_assoc_t rtems_object_api_classic_assoc[] = { + { "Task", OBJECTS_RTEMS_TASKS, 0}, + { "Timer", OBJECTS_RTEMS_TIMERS, 0}, + { "Semaphore", OBJECTS_RTEMS_SEMAPHORES, 0}, + { "Message Queue", OBJECTS_RTEMS_MESSAGE_QUEUES, 0}, + { "Partition", OBJECTS_RTEMS_PARTITIONS, 0}, + { "Region", OBJECTS_RTEMS_REGIONS, 0}, + { "Port", OBJECTS_RTEMS_PORTS, 0}, + { "Period", OBJECTS_RTEMS_PERIODS, 0}, + { "Extension", OBJECTS_RTEMS_EXTENSIONS, 0}, + { "Barrier", OBJECTS_RTEMS_BARRIERS, 0}, +}; + +#ifdef RTEMS_POSIX_API +rtems_assoc_t rtems_object_api_posix_assoc[] = { + { "Thread", OBJECTS_POSIX_THREADS, 0}, + { "Key", OBJECTS_POSIX_KEYS, 0}, + { "Interrupt", OBJECTS_POSIX_INTERRUPTS, 0}, + { "Queued fd", OBJECTS_POSIX_MESSAGE_QUEUE_FDS, 0}, + { "Message Queue", OBJECTS_POSIX_MESSAGE_QUEUES, 0}, + { "Mutex", OBJECTS_POSIX_MUTEXES, 0}, + { "Semaphore", OBJECTS_POSIX_SEMAPHORES, 0}, + { "Condition Variable", OBJECTS_POSIX_CONDITION_VARIABLES, 0}, + { "Timer", OBJECTS_POSIX_TIMERS, 0}, + { "Barrier", OBJECTS_POSIX_BARRIERS, 0}, + { "Spinlock", OBJECTS_POSIX_SPINLOCKS, 0}, + { "RWLock", OBJECTS_POSIX_RWLOCKS, 0}, +}; +#endif + +const char *rtems_object_get_api_class_name( + int the_api, + int the_class +) +{ + const rtems_assoc_t *api_assoc; + const rtems_assoc_t *class_assoc; + + if ( the_api == OBJECTS_INTERNAL_API ) + api_assoc = rtems_object_api_internal_assoc; + else if ( the_api == OBJECTS_CLASSIC_API ) + api_assoc = rtems_object_api_classic_assoc; +#ifdef RTEMS_POSIX_API + else if ( the_api == OBJECTS_POSIX_API ) + api_assoc = rtems_object_api_posix_assoc; +#endif + else + return "BAD API"; + class_assoc = rtems_assoc_ptr_by_local( api_assoc, the_class ); + if ( class_assoc ) + return class_assoc->name; + return "BAD CLASS"; +} diff --git a/cpukit/rtems/src/rtemsobjectgetapiname.c b/cpukit/rtems/src/rtemsobjectgetapiname.c new file mode 100644 index 0000000000..90a6afa198 --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectgetapiname.c @@ -0,0 +1,42 @@ +/* + * RTEMS Object Helper -- Obtain Name of API + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/object.h> + +#include <rtems/assoc.h> + +rtems_assoc_t rtems_objects_api_assoc[] = { + { "Internal", OBJECTS_INTERNAL_API, 0}, + { "Classic", OBJECTS_CLASSIC_API, 0}, + { "POSIX", OBJECTS_POSIX_API, 0}, + { 0, 0, 0 } +}; + +const char *rtems_object_get_api_name( + int api +) +{ + const rtems_assoc_t *api_assoc; + + api_assoc = rtems_assoc_ptr_by_local( rtems_objects_api_assoc, api ); + if ( api_assoc ) + return api_assoc->name; + return "BAD CLASS"; +} + diff --git a/cpukit/rtems/src/rtemsobjectgetclassicname.c b/cpukit/rtems/src/rtemsobjectgetclassicname.c new file mode 100644 index 0000000000..7a78d59e7e --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectgetclassicname.c @@ -0,0 +1,55 @@ +/* + * RTEMS ID To Name Lookup + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> + +/*PAGE + * + * rtems_object_get_classic_name + * + * This directive returns the name associated with the specified + * object ID. + * + * Input parameters: + * id - message queue id + * + * Output parameters: + * *name - user defined object name + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_object_get_classic_name( + rtems_id id, + rtems_name *name +) +{ + Objects_Name_or_id_lookup_errors status; + Objects_Name name_u; + + if ( !name ) + return RTEMS_INVALID_ADDRESS; + + status = _Objects_Id_to_name( id, &name_u ); + + *name = name_u.name_u32; + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/rtemsobjectgetclassinfo.c b/cpukit/rtems/src/rtemsobjectgetclassinfo.c new file mode 100644 index 0000000000..4f20a6f61f --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectgetclassinfo.c @@ -0,0 +1,59 @@ +/* + * RTEMS Object Helper -- Get Information on Class + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/score/object.h> +#include <rtems/rtems/object.h> + +rtems_status_code rtems_object_get_class_information( + int the_api, + int the_class, + rtems_object_api_class_information *info +) +{ + Objects_Information *obj_info; + int unallocated; + int i; + + /* + * Validate parameters and look up information structure. + */ + if ( !info ) + return RTEMS_INVALID_ADDRESS; + + obj_info = _Objects_Get_information( the_api, the_class ); + if ( !obj_info ) + return RTEMS_INVALID_NUMBER; + + /* + * Return information about this object class to the user. + */ + info->minimum_id = obj_info->minimum_id; + info->maximum_id = obj_info->maximum_id; + info->auto_extend = obj_info->auto_extend; + info->maximum = obj_info->maximum; + + for ( unallocated=0, i=1 ; i <= info->maximum ; i++ ) + if ( !obj_info->local_table[i] ) + unallocated++; + + info->unallocated = unallocated; + + return RTEMS_SUCCESSFUL; +} + diff --git a/cpukit/rtems/src/rtemsobjectgetname.c b/cpukit/rtems/src/rtemsobjectgetname.c new file mode 100644 index 0000000000..c414d2e478 --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectgetname.c @@ -0,0 +1,33 @@ +/* + * RTEMS Object Helper -- Obtain Name of Object as String + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> + +/* + * This method obtain the name of an object and returns its name + * in the form of a C string. It attempts to be careful about + * overflowing the user's string and about returning unprintable characters. + */ +char *rtems_object_get_name( + Objects_Id id, + size_t length, + char *name +) +{ + return _Objects_Get_name_as_string( id, length, name ); +} diff --git a/cpukit/rtems/src/rtemsobjectidapimaximum.c b/cpukit/rtems/src/rtemsobjectidapimaximum.c new file mode 100644 index 0000000000..fbf6c19d02 --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectidapimaximum.c @@ -0,0 +1,26 @@ +/* + * RTEMS Object Helper -- Get Greatest Valid API Number + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/types.h> + +#undef rtems_object_id_api_maximum +int rtems_object_id_api_maximum(void) +{ + return OBJECTS_APIS_LAST; +} diff --git a/cpukit/rtems/src/rtemsobjectidapiminimum.c b/cpukit/rtems/src/rtemsobjectidapiminimum.c new file mode 100644 index 0000000000..057fa09d70 --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectidapiminimum.c @@ -0,0 +1,26 @@ +/* + * RTEMS Object Helper -- Get Least Valid API Number + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/types.h> + +#undef rtems_object_id_api_minimum +int rtems_object_id_api_minimum(void) +{ + return OBJECTS_INTERNAL_API; +} diff --git a/cpukit/rtems/src/rtemsobjectidgetapi.c b/cpukit/rtems/src/rtemsobjectidgetapi.c new file mode 100644 index 0000000000..859e4b5bc6 --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectidgetapi.c @@ -0,0 +1,28 @@ +/* + * RTEMS Object Helper -- Extract API From Id + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/types.h> + +#undef rtems_object_id_get_api +int rtems_object_id_get_api( + rtems_id id +) +{ + return _Objects_Get_API( id ); +} diff --git a/cpukit/rtems/src/rtemsobjectidgetclass.c b/cpukit/rtems/src/rtemsobjectidgetclass.c new file mode 100644 index 0000000000..fe85050c4a --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectidgetclass.c @@ -0,0 +1,28 @@ +/* + * RTEMS Object Helper -- Extract Class From Id + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/types.h> + +#undef rtems_object_id_get_class +int rtems_object_id_get_class( + rtems_id id +) +{ + return _Objects_Get_class( id ); +} diff --git a/cpukit/rtems/src/rtemsobjectidgetindex.c b/cpukit/rtems/src/rtemsobjectidgetindex.c new file mode 100644 index 0000000000..67f795be8d --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectidgetindex.c @@ -0,0 +1,28 @@ +/* + * RTEMS Object Helper -- Extract Index From Id + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/types.h> + +#undef rtems_object_id_get_index +int rtems_object_id_get_index( + rtems_id id +) +{ + return _Objects_Get_index( id ); +} diff --git a/cpukit/rtems/src/rtemsobjectidgetnode.c b/cpukit/rtems/src/rtemsobjectidgetnode.c new file mode 100644 index 0000000000..5dfae4b1f9 --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectidgetnode.c @@ -0,0 +1,28 @@ +/* + * RTEMS Object Helper -- Extract Node From Id + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/rtems/types.h> + +#undef rtems_object_id_get_node +int rtems_object_id_get_node( + rtems_id id +) +{ + return _Objects_Get_node( id ); +} diff --git a/cpukit/rtems/src/rtemsobjectsetname.c b/cpukit/rtems/src/rtemsobjectsetname.c new file mode 100644 index 0000000000..91fac13e7c --- /dev/null +++ b/cpukit/rtems/src/rtemsobjectsetname.c @@ -0,0 +1,64 @@ +/* + * RTEMS Object Helper -- Set Name of Object as String + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> + +/* + * This method will set the object name based upon the user string. + * If the object class uses 32-bit names, then only the first 4 bytes + * of the string will be used. + */ +rtems_status_code rtems_object_set_name( + rtems_id id, + const char *name +) +{ + Objects_Information *information; + Objects_Locations location; + Objects_Control *the_object; + Objects_Id tmpId; + + if ( !name ) + return RTEMS_INVALID_ADDRESS; + + tmpId = (id == OBJECTS_ID_OF_SELF) ? _Thread_Executing->Object.id : id; + + information = _Objects_Get_information_id( tmpId ); + if ( !information ) + return RTEMS_INVALID_ID; + + the_object = _Objects_Get( information, tmpId, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _Objects_Set_name( information, the_object, name ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/rtemstimer.c b/cpukit/rtems/src/rtemstimer.c new file mode 100644 index 0000000000..3cff1f3bf7 --- /dev/null +++ b/cpukit/rtems/src/rtemstimer.c @@ -0,0 +1,64 @@ +/* + * Timer Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * _Timer_Manager_initialization + * + * This routine initializes all timer manager related data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Timer_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_Timer_Information, /* object information table */ + OBJECTS_CLASSIC_API, /* object API */ + OBJECTS_RTEMS_TIMERS, /* object class */ + Configuration_RTEMS_API.maximum_timers , + /* maximum objects of this class */ + sizeof( Timer_Control ), /* size of this object's control block */ + false, /* true if the name is a string */ + RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); + + /* + * Initialize the pointer to the default timer server control block to NULL + * indicating that task-based timer support is not initialized. + */ + + _Timer_server = NULL; +} diff --git a/cpukit/rtems/src/rtemstimerdata.c b/cpukit/rtems/src/rtemstimerdata.c new file mode 100644 index 0000000000..b817c2f788 --- /dev/null +++ b/cpukit/rtems/src/rtemstimerdata.c @@ -0,0 +1,22 @@ +/* + * Timer Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate RTEMS timer data */ +#define RTEMS_TIMER_EXTERN + +#include <rtems/system.h> +#include <rtems/rtems/timer.h> diff --git a/cpukit/rtems/src/sem.c b/cpukit/rtems/src/sem.c new file mode 100644 index 0000000000..ecf070e44d --- /dev/null +++ b/cpukit/rtems/src/sem.c @@ -0,0 +1,93 @@ +/* + * Semaphore Manager + * + * DESCRIPTION: + * + * This package is the implementation of the Semaphore Manager. + * This manager utilizes standard Dijkstra counting semaphores to provide + * synchronization and mutual exclusion capabilities. + * + * Directives provided are: + * + * + create a semaphore + * + get an ID of a semaphore + * + delete a semaphore + * + acquire a semaphore + * + release a semaphore + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/sem.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/coresem.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/score/sysstate.h> + +#include <rtems/score/interr.h> + +/*PAGE + * + * _Semaphore_Manager_initialization + * + * This routine initializes all semaphore manager related data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Semaphore_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_Semaphore_Information, /* object information table */ + OBJECTS_CLASSIC_API, /* object API */ + OBJECTS_RTEMS_SEMAPHORES, /* object class */ + Configuration_RTEMS_API.maximum_semaphores, + /* maximum objects of this class */ + sizeof( Semaphore_Control ), /* size of this object's control block */ + false, /* true if the name is a string */ + RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */ +#if defined(RTEMS_MULTIPROCESSING) + , + true, /* true if this is a global object class */ + _Semaphore_MP_Send_extract_proxy /* Proxy extraction support callout */ +#endif + ); + + /* + * Register the MP Process Packet routine. + */ + +#if defined(RTEMS_MULTIPROCESSING) + _MPCI_Register_packet_processor( + MP_PACKET_SEMAPHORE, + _Semaphore_MP_Process_packet + ); +#endif + +} diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c new file mode 100644 index 0000000000..49cffc8e10 --- /dev/null +++ b/cpukit/rtems/src/semcreate.c @@ -0,0 +1,231 @@ +/* + * Semaphore Manager + * + * DESCRIPTION: + * + * This package is the implementation of the Semaphore Manager. + * This manager utilizes standard Dijkstra counting semaphores to provide + * synchronization and mutual exclusion capabilities. + * + * Directives provided are: + * + * + create a semaphore + * + get an ID of a semaphore + * + delete a semaphore + * + acquire a semaphore + * + release a semaphore + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/sem.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/coresem.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/score/sysstate.h> + +#include <rtems/score/interr.h> + +/*PAGE + * + * rtems_semaphore_create + * + * This directive creates a semaphore and sets the initial value based + * on the given count. A semaphore id is returned. + * + * Input parameters: + * name - user defined semaphore name + * count - initial count of semaphore + * attribute_set - semaphore attributes + * priority_ceiling - semaphore's ceiling priority + * id - pointer to semaphore id + * + * Output parameters: + * id - semaphore id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_semaphore_create( + rtems_name name, + uint32_t count, + rtems_attribute attribute_set, + rtems_task_priority priority_ceiling, + rtems_id *id +) +{ + register Semaphore_Control *the_semaphore; + CORE_mutex_Attributes the_mutex_attr; + CORE_semaphore_Attributes the_semaphore_attr; + CORE_mutex_Status mutex_status; + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( attribute_set ) ) { + + if ( !_System_state_Is_multiprocessing ) + return RTEMS_MP_NOT_CONFIGURED; + + if ( _Attributes_Is_inherit_priority( attribute_set ) || + _Attributes_Is_priority_ceiling( attribute_set ) ) + return RTEMS_NOT_DEFINED; + + } else +#endif + + if ( _Attributes_Is_inherit_priority( attribute_set ) || + _Attributes_Is_priority_ceiling( attribute_set ) ) { + + if ( ! (_Attributes_Is_binary_semaphore( attribute_set ) && + _Attributes_Is_priority( attribute_set ) ) ) + return RTEMS_NOT_DEFINED; + + } + + if ( _Attributes_Is_inherit_priority( attribute_set ) && + _Attributes_Is_priority_ceiling( attribute_set ) ) + return RTEMS_NOT_DEFINED; + + if ( !_Attributes_Is_counting_semaphore( attribute_set ) && ( count > 1 ) ) + return RTEMS_INVALID_NUMBER; + + _Thread_Disable_dispatch(); /* prevents deletion */ + + the_semaphore = _Semaphore_Allocate(); + + if ( !the_semaphore ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( attribute_set ) && + ! ( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name, + the_semaphore->Object.id, false ) ) ) { + _Semaphore_Free( the_semaphore ); + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } +#endif + + the_semaphore->attribute_set = attribute_set; + + /* + * Initialize it as a counting semaphore. + */ + if ( _Attributes_Is_counting_semaphore( attribute_set ) ) { + /* + * This effectively disables limit checking. + */ + the_semaphore_attr.maximum_count = 0xFFFFFFFF; + + if ( _Attributes_Is_priority( attribute_set ) ) + the_semaphore_attr.discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY; + else + the_semaphore_attr.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO; + + /* + * The following are just to make Purify happy. + */ + the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES; + the_mutex_attr.priority_ceiling = PRIORITY_MINIMUM; + + _CORE_semaphore_Initialize( + &the_semaphore->Core_control.semaphore, + &the_semaphore_attr, + count + ); + } else { + /* + * It is either simple binary semaphore or a more powerful mutex + * style binary semaphore. This is the mutex style. + */ + if ( _Attributes_Is_priority( attribute_set ) ) + the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY; + else + the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_FIFO; + + if ( _Attributes_Is_binary_semaphore( attribute_set ) ) { + the_mutex_attr.priority_ceiling = priority_ceiling; + the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES; + the_mutex_attr.only_owner_release = false; + + if ( the_mutex_attr.discipline == CORE_MUTEX_DISCIPLINES_PRIORITY ) { + if ( _Attributes_Is_inherit_priority( attribute_set ) ) { + the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT; + the_mutex_attr.only_owner_release = true; + } else if ( _Attributes_Is_priority_ceiling( attribute_set ) ) { + the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING; + the_mutex_attr.only_owner_release = true; + } + } + } else /* must be simple binary semaphore */ { + the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_BLOCKS; + the_mutex_attr.only_owner_release = false; + } + + mutex_status = _CORE_mutex_Initialize( + &the_semaphore->Core_control.mutex, + &the_mutex_attr, + (count == 1) ? CORE_MUTEX_UNLOCKED : CORE_MUTEX_LOCKED + ); + + if ( mutex_status == CORE_MUTEX_STATUS_CEILING_VIOLATED ) { + _Semaphore_Free( the_semaphore ); + _Thread_Enable_dispatch(); + return RTEMS_INVALID_PRIORITY; + } + } + + /* + * Whether we initialized it as a mutex or counting semaphore, it is + * now ready to be "offered" for use as a Classic API Semaphore. + */ + _Objects_Open( + &_Semaphore_Information, + &the_semaphore->Object, + (Objects_Name) name + ); + + *id = the_semaphore->Object.id; + +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( attribute_set ) ) + _Semaphore_MP_Send_process_packet( + SEMAPHORE_MP_ANNOUNCE_CREATE, + the_semaphore->Object.id, + name, + 0 /* Not used */ + ); +#endif + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/semdata.c b/cpukit/rtems/src/semdata.c new file mode 100644 index 0000000000..cc4126db15 --- /dev/null +++ b/cpukit/rtems/src/semdata.c @@ -0,0 +1,22 @@ +/* + * Semaphore Manager -- Data Instantiation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate semaphore data */ +#define RTEMS_SEM_EXTERN + +#include <rtems/system.h> +#include <rtems/rtems/sem.h> diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c new file mode 100644 index 0000000000..d9c81fc56b --- /dev/null +++ b/cpukit/rtems/src/semdelete.c @@ -0,0 +1,136 @@ +/* + * Semaphore Manager + * + * DESCRIPTION: + * + * This package is the implementation of the Semaphore Manager. + * This manager utilizes standard Dijkstra counting semaphores to provide + * synchronization and mutual exclusion capabilities. + * + * Directives provided are: + * + * + create a semaphore + * + get an ID of a semaphore + * + delete a semaphore + * + acquire a semaphore + * + release a semaphore + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/sem.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/coresem.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/score/sysstate.h> + +#include <rtems/score/interr.h> + +/*PAGE + * + * rtems_semaphore_delete + * + * This directive allows a thread to delete a semaphore specified by + * the semaphore id. The semaphore is freed back to the inactive + * semaphore chain. + * + * Input parameters: + * id - semaphore id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +#if defined(RTEMS_MULTIPROCESSING) +#define SEMAPHORE_MP_OBJECT_WAS_DELETED _Semaphore_MP_Send_object_was_deleted +#else +#define SEMAPHORE_MP_OBJECT_WAS_DELETED NULL +#endif + +rtems_status_code rtems_semaphore_delete( + rtems_id id +) +{ + register Semaphore_Control *the_semaphore; + Objects_Locations location; + + the_semaphore = _Semaphore_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { + if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) && + !_Attributes_Is_simple_binary_semaphore( + the_semaphore->attribute_set ) ) { + _Thread_Enable_dispatch(); + return RTEMS_RESOURCE_IN_USE; + } + _CORE_mutex_Flush( + &the_semaphore->Core_control.mutex, + SEMAPHORE_MP_OBJECT_WAS_DELETED, + CORE_MUTEX_WAS_DELETED + ); + } else { + _CORE_semaphore_Flush( + &the_semaphore->Core_control.semaphore, + SEMAPHORE_MP_OBJECT_WAS_DELETED, + CORE_SEMAPHORE_WAS_DELETED + ); + } + + _Objects_Close( &_Semaphore_Information, &the_semaphore->Object ); + + _Semaphore_Free( the_semaphore ); + +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( the_semaphore->attribute_set ) ) { + + _Objects_MP_Close( &_Semaphore_Information, the_semaphore->Object.id ); + + _Semaphore_MP_Send_process_packet( + SEMAPHORE_MP_ANNOUNCE_DELETE, + the_semaphore->Object.id, + 0, /* Not used */ + 0 /* Not used */ + ); + } +#endif + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/semflush.c b/cpukit/rtems/src/semflush.c new file mode 100644 index 0000000000..120b83e0fe --- /dev/null +++ b/cpukit/rtems/src/semflush.c @@ -0,0 +1,102 @@ +/* + * rtems_semaphore_flush + * + * DESCRIPTION: + * + * This package is the implementation of the flush directive + * of the Semaphore Manager. + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/sem.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/coresem.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/score/sysstate.h> + +#include <rtems/score/interr.h> + +/*PAGE + * + * rtems_semaphore_flush + * + * This directive allows a thread to flush the threads + * pending on the semaphore. + * + * Input parameters: + * id - semaphore id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +#if defined(RTEMS_MULTIPROCESSING) +#define SEND_OBJECT_WAS_DELETED _Semaphore_MP_Send_object_was_deleted +#else +#define SEND_OBJECT_WAS_DELETED NULL +#endif + +rtems_status_code rtems_semaphore_flush( + rtems_id id +) +{ + register Semaphore_Control *the_semaphore; + Objects_Locations location; + + the_semaphore = _Semaphore_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { + _CORE_mutex_Flush( + &the_semaphore->Core_control.mutex, + SEND_OBJECT_WAS_DELETED, + CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT + ); + } else { + _CORE_semaphore_Flush( + &the_semaphore->Core_control.semaphore, + SEND_OBJECT_WAS_DELETED, + CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT + ); + } + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/semident.c b/cpukit/rtems/src/semident.c new file mode 100644 index 0000000000..56f8856da7 --- /dev/null +++ b/cpukit/rtems/src/semident.c @@ -0,0 +1,81 @@ +/* + * Semaphore Manager + * + * DESCRIPTION: + * + * This package is the implementation of the Semaphore Manager. + * This manager utilizes standard Dijkstra counting semaphores to provide + * synchronization and mutual exclusion capabilities. + * + * Directives provided are: + * + * + create a semaphore + * + get an ID of a semaphore + * + delete a semaphore + * + acquire a semaphore + * + release a semaphore + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/sem.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/coresem.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/score/sysstate.h> + +#include <rtems/score/interr.h> + +/*PAGE + * + * rtems_semaphore_ident + * + * This directive returns the system ID associated with + * the semaphore name. + * + * Input parameters: + * name - user defined semaphore name + * node - node(s) to be searched + * id - pointer to semaphore id + * + * Output parameters: + * *id - semaphore id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_semaphore_ident( + rtems_name name, + uint32_t node, + rtems_id *id +) +{ + Objects_Name_or_id_lookup_errors status; + + status = _Objects_Name_to_id_u32( &_Semaphore_Information, name, node, id ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/semmp.c b/cpukit/rtems/src/semmp.c new file mode 100644 index 0000000000..06bed8a52c --- /dev/null +++ b/cpukit/rtems/src/semmp.c @@ -0,0 +1,367 @@ +/* + * Multiprocessing Support for the Semaphore Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/score/mpci.h> +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/sem.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * _Semaphore_MP_Send_process_packet + * + */ + +void _Semaphore_MP_Send_process_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + rtems_name name, + Objects_Id proxy_id +) +{ + Semaphore_MP_Packet *the_packet; + uint32_t node; + + switch ( operation ) { + + case SEMAPHORE_MP_ANNOUNCE_CREATE: + case SEMAPHORE_MP_ANNOUNCE_DELETE: + case SEMAPHORE_MP_EXTRACT_PROXY: + + the_packet = _Semaphore_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_SEMAPHORE; + the_packet->Prefix.length = sizeof ( Semaphore_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = semaphore_id; + the_packet->name = name; + the_packet->proxy_id = proxy_id; + + if ( operation == SEMAPHORE_MP_EXTRACT_PROXY ) + node = _Objects_Get_node( semaphore_id ); + else + node = MPCI_ALL_NODES; + + _MPCI_Send_process_packet( node, &the_packet->Prefix ); + break; + + case SEMAPHORE_MP_OBTAIN_REQUEST: + case SEMAPHORE_MP_OBTAIN_RESPONSE: + case SEMAPHORE_MP_RELEASE_REQUEST: + case SEMAPHORE_MP_RELEASE_RESPONSE: + break; + } +} + +/*PAGE + * + * _Semaphore_MP_Send_request_packet + * + */ + +rtems_status_code _Semaphore_MP_Send_request_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + rtems_option option_set, + rtems_interval timeout +) +{ + Semaphore_MP_Packet *the_packet; + + switch ( operation ) { + + case SEMAPHORE_MP_OBTAIN_REQUEST: + case SEMAPHORE_MP_RELEASE_REQUEST: + + the_packet = _Semaphore_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_SEMAPHORE; + the_packet->Prefix.length = sizeof ( Semaphore_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet ); + if ( ! _Options_Is_no_wait(option_set)) + the_packet->Prefix.timeout = timeout; + + the_packet->operation = operation; + the_packet->Prefix.id = semaphore_id; + the_packet->option_set = option_set; + + return _MPCI_Send_request_packet( + _Objects_Get_node( semaphore_id ), + &the_packet->Prefix, + STATES_WAITING_FOR_SEMAPHORE + ); + break; + + case SEMAPHORE_MP_ANNOUNCE_CREATE: + case SEMAPHORE_MP_ANNOUNCE_DELETE: + case SEMAPHORE_MP_EXTRACT_PROXY: + case SEMAPHORE_MP_OBTAIN_RESPONSE: + case SEMAPHORE_MP_RELEASE_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _Semaphore_MP_Send_response_packet + * + */ + +void _Semaphore_MP_Send_response_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + Thread_Control *the_thread +) +{ + Semaphore_MP_Packet *the_packet; + + switch ( operation ) { + + case SEMAPHORE_MP_OBTAIN_RESPONSE: + case SEMAPHORE_MP_RELEASE_RESPONSE: + + the_packet = ( Semaphore_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + _Objects_Get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case SEMAPHORE_MP_ANNOUNCE_CREATE: + case SEMAPHORE_MP_ANNOUNCE_DELETE: + case SEMAPHORE_MP_EXTRACT_PROXY: + case SEMAPHORE_MP_OBTAIN_REQUEST: + case SEMAPHORE_MP_RELEASE_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Semaphore_MP_Process_packet + * + */ + +void _Semaphore_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Semaphore_MP_Packet *the_packet; + Thread_Control *the_thread; + bool ignored; + + the_packet = (Semaphore_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case SEMAPHORE_MP_ANNOUNCE_CREATE: + + ignored = _Objects_MP_Allocate_and_open( + &_Semaphore_Information, + the_packet->name, + the_packet->Prefix.id, + true + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case SEMAPHORE_MP_ANNOUNCE_DELETE: + + _Objects_MP_Close( &_Semaphore_Information, the_packet->Prefix.id ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case SEMAPHORE_MP_EXTRACT_PROXY: + + the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); + + if ( ! _Thread_Is_null( the_thread ) ) + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case SEMAPHORE_MP_OBTAIN_REQUEST: + + the_packet->Prefix.return_code = rtems_semaphore_obtain( + the_packet->Prefix.id, + the_packet->option_set, + the_packet->Prefix.timeout + ); + + if ( the_packet->Prefix.return_code != RTEMS_PROXY_BLOCKING ) + _Semaphore_MP_Send_response_packet( + SEMAPHORE_MP_OBTAIN_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case SEMAPHORE_MP_OBTAIN_RESPONSE: + case SEMAPHORE_MP_RELEASE_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case SEMAPHORE_MP_RELEASE_REQUEST: + + the_packet->Prefix.return_code = rtems_semaphore_release( + the_packet->Prefix.id + ); + + _Semaphore_MP_Send_response_packet( + SEMAPHORE_MP_RELEASE_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + } +} + +/*PAGE + * + * _Semaphore_MP_Send_object_was_deleted + * + */ + +void _Semaphore_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +) +{ + the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED; + + _Semaphore_MP_Send_response_packet( + SEMAPHORE_MP_OBTAIN_RESPONSE, + the_proxy->Wait.id, + the_proxy + ); + +} + +/*PAGE + * + * _Semaphore_MP_Send_extract_proxy + * + */ + +void _Semaphore_MP_Send_extract_proxy ( + void *argument +) +{ + Thread_Control *the_thread = (Thread_Control *)argument; + + _Semaphore_MP_Send_process_packet( + SEMAPHORE_MP_EXTRACT_PROXY, + the_thread->Wait.id, + (rtems_name) 0, + the_thread->Object.id + ); + +} + +/*PAGE + * + * _Semaphore_MP_Get_packet + * + */ + +Semaphore_MP_Packet *_Semaphore_MP_Get_packet ( void ) +{ + return ( (Semaphore_MP_Packet *) _MPCI_Get_packet() ); +} + +/*PAGE + * + * _Semaphore_Core_mutex_mp_support + * + * Input parameters: + * the_thread - the remote thread the semaphore was surrendered to + * id - id of the surrendered semaphore + * + * Output parameters: NONE + */ + +#if defined(RTEMS_MULTIPROCESSING) +void _Semaphore_Core_mutex_mp_support ( + Thread_Control *the_thread, + Objects_Id id +) +{ + the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL; + + _Semaphore_MP_Send_response_packet( + SEMAPHORE_MP_OBTAIN_RESPONSE, + id, + the_thread + ); +} +#endif + + +/*PAGE + * + * _Semaphore_Core_semaphore_mp_support + * + * Input parameters: + * the_thread - the remote thread the semaphore was surrendered to + * id - id of the surrendered semaphore + * + * Output parameters: NONE + */ + +#if defined(RTEMS_MULTIPROCESSING) +void _Semaphore_Core_semaphore_mp_support ( + Thread_Control *the_thread, + Objects_Id id +) +{ + the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL; + + _Semaphore_MP_Send_response_packet( + SEMAPHORE_MP_OBTAIN_RESPONSE, + id, + the_thread + ); +} +#endif +/* end of file */ diff --git a/cpukit/rtems/src/semobtain.c b/cpukit/rtems/src/semobtain.c new file mode 100644 index 0000000000..e3f3af1b10 --- /dev/null +++ b/cpukit/rtems/src/semobtain.c @@ -0,0 +1,121 @@ +/* + * Semaphore Manager + * + * DESCRIPTION: + * + * This package is the implementation of the Semaphore Manager. + * This manager utilizes standard Dijkstra counting semaphores to provide + * synchronization and mutual exclusion capabilities. + * + * Directives provided are: + * + * + create a semaphore + * + get an ID of a semaphore + * + delete a semaphore + * + acquire a semaphore + * + release a semaphore + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/sem.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/coresem.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/score/sysstate.h> + +#include <rtems/score/interr.h> + +/*PAGE + * + * rtems_semaphore_obtain + * + * This directive allows a thread to acquire a semaphore. + * + * Input parameters: + * id - semaphore id + * option_set - wait option + * timeout - number of ticks to wait (0 means wait forever) + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_semaphore_obtain( + rtems_id id, + rtems_option option_set, + rtems_interval timeout +) +{ + register Semaphore_Control *the_semaphore; + Objects_Locations location; + ISR_Level level; + + the_semaphore = _Semaphore_Get_interrupt_disable( id, &location, &level ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { + _CORE_mutex_Seize( + &the_semaphore->Core_control.mutex, + id, + ((_Options_Is_no_wait( option_set )) ? false : true), + timeout, + level + ); + return _Semaphore_Translate_core_mutex_return_code( + _Thread_Executing->Wait.return_code ); + } + + /* must be a counting semaphore */ + _CORE_semaphore_Seize_isr_disable( + &the_semaphore->Core_control.semaphore, + id, + ((_Options_Is_no_wait( option_set )) ? false : true), + timeout, + &level + ); + return _Semaphore_Translate_core_semaphore_return_code( + _Thread_Executing->Wait.return_code ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return _Semaphore_MP_Send_request_packet( + SEMAPHORE_MP_OBTAIN_REQUEST, + id, + option_set, + timeout + ); +#endif + + case OBJECTS_ERROR: + break; + + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c new file mode 100644 index 0000000000..6ccf0cfbbe --- /dev/null +++ b/cpukit/rtems/src/semrelease.c @@ -0,0 +1,119 @@ +/* + * Semaphore Manager + * + * DESCRIPTION: + * + * This package is the implementation of the Semaphore Manager. + * This manager utilizes standard Dijkstra counting semaphores to provide + * synchronization and mutual exclusion capabilities. + * + * Directives provided are: + * + * + create a semaphore + * + get an ID of a semaphore + * + delete a semaphore + * + acquire a semaphore + * + release a semaphore + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/sem.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/coresem.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/score/sysstate.h> + +#include <rtems/score/interr.h> + +/*PAGE + * + * rtems_semaphore_release + * + * This directive allows a thread to release a semaphore. + * + * Input parameters: + * id - semaphore id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +#if defined(RTEMS_MULTIPROCESSING) +#define MUTEX_MP_SUPPORT _Semaphore_Core_mutex_mp_support +#else +#define MUTEX_MP_SUPPORT NULL +#endif + +rtems_status_code rtems_semaphore_release( + rtems_id id +) +{ + register Semaphore_Control *the_semaphore; + Objects_Locations location; + CORE_mutex_Status mutex_status; + CORE_semaphore_Status semaphore_status; + + the_semaphore = _Semaphore_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { + mutex_status = _CORE_mutex_Surrender( + &the_semaphore->Core_control.mutex, + id, + MUTEX_MP_SUPPORT + ); + _Thread_Enable_dispatch(); + return _Semaphore_Translate_core_mutex_return_code( mutex_status ); + } else { + semaphore_status = _CORE_semaphore_Surrender( + &the_semaphore->Core_control.semaphore, + id, + MUTEX_MP_SUPPORT + ); + _Thread_Enable_dispatch(); + return + _Semaphore_Translate_core_semaphore_return_code( semaphore_status ); + } + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return _Semaphore_MP_Send_request_packet( + SEMAPHORE_MP_RELEASE_REQUEST, + id, + 0, /* Not used */ + MPCI_DEFAULT_TIMEOUT + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/semtranslatereturncode.c b/cpukit/rtems/src/semtranslatereturncode.c new file mode 100644 index 0000000000..02b665e5f6 --- /dev/null +++ b/cpukit/rtems/src/semtranslatereturncode.c @@ -0,0 +1,137 @@ +/* + * Semaphore Manager + * + * DESCRIPTION: + * + * This package is the implementation of the Semaphore Manager. + * This manager utilizes standard Dijkstra counting semaphores to provide + * synchronization and mutual exclusion capabilities. + * + * Directives provided are: + * + * + create a semaphore + * + get an ID of a semaphore + * + delete a semaphore + * + acquire a semaphore + * + release a semaphore + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/attr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/sem.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/coresem.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/score/sysstate.h> + +#include <rtems/score/interr.h> + +/*PAGE + * + * _Semaphore_Translate_core_mutex_return_code + * + * Input parameters: + * status - mutex status code to translate + * + * Output parameters: + * rtems status code - translated RTEMS status code + * + */ + +const rtems_status_code _Semaphore_Translate_core_mutex_return_code_[] = { + RTEMS_SUCCESSFUL, /* CORE_MUTEX_STATUS_SUCCESSFUL */ + RTEMS_UNSATISFIED, /* CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT */ +#if defined(RTEMS_POSIX_API) + RTEMS_UNSATISFIED, /* CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED */ +#endif + RTEMS_NOT_OWNER_OF_RESOURCE, /* CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE */ + RTEMS_OBJECT_WAS_DELETED, /* CORE_MUTEX_WAS_DELETED */ + RTEMS_TIMEOUT, /* CORE_MUTEX_TIMEOUT */ +#if defined(__RTEMS_STRICT_ORDER_MUTEX__) + CORE_MUTEX_RELEASE_NOT_ORDER, +#endif + RTEMS_INVALID_PRIORITY /* CORE_MUTEX_STATUS_CEILING_VIOLATED */ +}; + +rtems_status_code _Semaphore_Translate_core_mutex_return_code ( + uint32_t status +) +{ + /* + * If this thread is blocking waiting for a result on a remote operation. + */ + #if defined(RTEMS_MULTIPROCESSING) + if ( _Thread_Is_proxy_blocking(status) ) + return RTEMS_PROXY_BLOCKING; + #endif + + /* + * Internal consistency check for bad status from SuperCore + */ + #if defined(RTEMS_DEBUG) + if ( status > CORE_MUTEX_STATUS_LAST ) + return RTEMS_INTERNAL_ERROR; + #endif + return _Semaphore_Translate_core_mutex_return_code_[status]; +} + +/*PAGE + * + * _Semaphore_Translate_core_semaphore_return_code + * + * Input parameters: + * status - semaphore status code to translate + * + * Output parameters: + * rtems status code - translated RTEMS status code + * + */ + +const rtems_status_code _Semaphore_Translate_core_semaphore_return_code_[] = { + RTEMS_SUCCESSFUL, /* CORE_SEMAPHORE_STATUS_SUCCESSFUL */ + RTEMS_UNSATISFIED, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */ + RTEMS_OBJECT_WAS_DELETED, /* CORE_SEMAPHORE_WAS_DELETED */ + RTEMS_TIMEOUT, /* CORE_SEMAPHORE_TIMEOUT */ + RTEMS_INTERNAL_ERROR, /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */ +}; + +rtems_status_code _Semaphore_Translate_core_semaphore_return_code ( + uint32_t status +) +{ + #if defined(RTEMS_MULTIPROCESSING) + if ( _Thread_Is_proxy_blocking(status) ) + return RTEMS_PROXY_BLOCKING; + #endif + /* + * Internal consistency check for bad status from SuperCore + */ + #if defined(RTEMS_DEBUG) + if ( status > CORE_SEMAPHORE_STATUS_LAST ) + return RTEMS_INTERNAL_ERROR; + #endif + return _Semaphore_Translate_core_semaphore_return_code_[status]; +} diff --git a/cpukit/rtems/src/signal.c b/cpukit/rtems/src/signal.c new file mode 100644 index 0000000000..d54d1e2491 --- /dev/null +++ b/cpukit/rtems/src/signal.c @@ -0,0 +1,51 @@ +/* + * Signal Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/asr.h> +#include <rtems/score/isr.h> +#include <rtems/rtems/modes.h> +#include <rtems/rtems/signal.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/tasks.h> + +/*PAGE + * + * _Signal_Manager_initialization + * + * This routine initializes all signal manager related data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Signal_Manager_initialization( void ) +{ + /* + * Register the MP Process Packet routine. + */ + +#if defined(RTEMS_MULTIPROCESSING) + _MPCI_Register_packet_processor( + MP_PACKET_SIGNAL, + _Signal_MP_Process_packet + ); +#endif +} diff --git a/cpukit/rtems/src/signalcatch.c b/cpukit/rtems/src/signalcatch.c new file mode 100644 index 0000000000..fd38e06e2f --- /dev/null +++ b/cpukit/rtems/src/signalcatch.c @@ -0,0 +1,69 @@ +/* + * Signal Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/asr.h> +#include <rtems/score/isr.h> +#include <rtems/rtems/modes.h> +#include <rtems/rtems/signal.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/tasks.h> + +/*PAGE + * + * rtems_signal_catch + * + * This directive allows a thread to specify what action to take when + * catching signals. + * + * Input parameters: + * handler - address of asynchronous signal routine (asr) + * ( NULL indicates asr is invalid ) + * mode_set - mode value for asr + * + * Output parameters: + * RTEMS_SUCCESSFUL - always succeeds + */ + +rtems_status_code rtems_signal_catch( + rtems_asr_entry asr_handler, + rtems_mode mode_set +) +{ + Thread_Control *executing; + RTEMS_API_Control *api; + ASR_Information *asr; + +/* XXX normalize mode */ + executing = _Thread_Executing; + api = (RTEMS_API_Control*)executing->API_Extensions[ THREAD_API_RTEMS ]; + asr = &api->Signal; + + _Thread_Disable_dispatch(); /* cannot reschedule while */ + /* the thread is inconsistent */ + + if ( !_ASR_Is_null_handler( asr_handler ) ) { + asr->mode_set = mode_set; + asr->handler = asr_handler; + } + else + _ASR_Initialize( asr ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/signalmp.c b/cpukit/rtems/src/signalmp.c new file mode 100644 index 0000000000..2311e9e4a0 --- /dev/null +++ b/cpukit/rtems/src/signalmp.c @@ -0,0 +1,192 @@ +/* + * Multiprocessing Support for the Signal Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/score/mpci.h> +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/signal.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * _Signal_MP_Send_process_packet + * + * This subprogram is not needed since there are no process + * packets to be sent by this manager. + * + */ + +/*PAGE + * + * _Signal_MP_Send_request_packet + * + */ + +rtems_status_code _Signal_MP_Send_request_packet ( + Signal_MP_Remote_operations operation, + Objects_Id task_id, + rtems_signal_set signal_in +) +{ + Signal_MP_Packet *the_packet; + + switch ( operation ) { + + case SIGNAL_MP_SEND_REQUEST: + + the_packet = _Signal_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_SIGNAL; + the_packet->Prefix.length = sizeof ( Signal_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Signal_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = task_id; + the_packet->signal_in = signal_in; + + return _MPCI_Send_request_packet( + _Objects_Get_node( task_id ), + &the_packet->Prefix, + STATES_READY /* Not used */ + ); + break; + + case SIGNAL_MP_SEND_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_INTERNAL_ERROR; +} + +/*PAGE + * + * _Signal_MP_Send_response_packet + * + */ + +void _Signal_MP_Send_response_packet ( + Signal_MP_Remote_operations operation, + Thread_Control *the_thread +) +{ + Signal_MP_Packet *the_packet; + + switch ( operation ) { + + case SIGNAL_MP_SEND_RESPONSE: + + the_packet = ( Signal_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + _Objects_Get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case SIGNAL_MP_SEND_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Signal_MP_Process_packet + * + */ + +void _Signal_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Signal_MP_Packet *the_packet; + Thread_Control *the_thread; + + the_packet = (Signal_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case SIGNAL_MP_SEND_REQUEST: + + the_packet->Prefix.return_code = rtems_signal_send( + the_packet->Prefix.id, + the_packet->signal_in + ); + + _Signal_MP_Send_response_packet( + SIGNAL_MP_SEND_RESPONSE, + _Thread_Executing + ); + break; + + case SIGNAL_MP_SEND_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + } +} + +/*PAGE + * + * _Signal_MP_Send_object_was_deleted + * + * This subprogram is not needed since there are no objects + * deleted by this manager. + * + */ + +/*PAGE + * + * _Signal_MP_Send_extract_proxy + * + * This subprogram is not needed since there are no objects + * deleted by this manager. + * + */ + +/*PAGE + * + * _Signal_MP_Get_packet + * + */ + +Signal_MP_Packet *_Signal_MP_Get_packet ( void ) +{ + return ( (Signal_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/signalsend.c b/cpukit/rtems/src/signalsend.c new file mode 100644 index 0000000000..031a18979e --- /dev/null +++ b/cpukit/rtems/src/signalsend.c @@ -0,0 +1,92 @@ +/* + * Signal Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/asr.h> +#include <rtems/score/isr.h> +#include <rtems/rtems/modes.h> +#include <rtems/rtems/signal.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/tasks.h> + +/*PAGE + * + * rtems_signal_send + * + * This directive allows a thread to send signals to a thread. + * + * Input parameters: + * id - thread id + * signal_set - signal set + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_signal_send( + rtems_id id, + rtems_signal_set signal_set +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + RTEMS_API_Control *api; + ASR_Information *asr; + + if ( !signal_set ) + return RTEMS_INVALID_NUMBER; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + asr = &api->Signal; + + if ( ! _ASR_Is_null_handler( asr->handler ) ) { + if ( asr->is_enabled ) { + _ASR_Post_signals( signal_set, &asr->signals_posted ); + + if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) ) + _Thread_Dispatch_necessary = true; + } else { + _ASR_Post_signals( signal_set, &asr->signals_pending ); + } + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_NOT_DEFINED; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return _Signal_MP_Send_request_packet( + SIGNAL_MP_SEND_REQUEST, + id, + signal_set + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c new file mode 100644 index 0000000000..c173eced29 --- /dev/null +++ b/cpukit/rtems/src/taskcreate.c @@ -0,0 +1,229 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * rtems_task_create + * + * This directive creates a thread by allocating and initializing a + * thread control block and a stack. The newly created thread is + * placed in the dormant state. + * + * Input parameters: + * name - user defined thread name + * initial_priority - thread priority + * stack_size - stack size in bytes + * initial_modes - initial thread mode + * attribute_set - thread attributes + * id - pointer to thread id + * + * Output parameters: + * id - thread id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_create( + rtems_name name, + rtems_task_priority initial_priority, + size_t stack_size, + rtems_mode initial_modes, + rtems_attribute attribute_set, + rtems_id *id +) +{ + register Thread_Control *the_thread; + bool is_fp; +#if defined(RTEMS_MULTIPROCESSING) + Objects_MP_Control *the_global_object = NULL; + bool is_global; +#endif + bool status; + rtems_attribute the_attribute_set; + Priority_Control core_priority; + RTEMS_API_Control *api; + ASR_Information *asr; + + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + /* + * Core Thread Initialize insures we get the minimum amount of + * stack space. + */ + + /* + * Fix the attribute set to match the attributes which + * this processor (1) requires and (2) is able to support. + * First add in the required flags for attribute_set + * Typically this might include FP if the platform + * or application required all tasks to be fp aware. + * Then turn off the requested bits which are not supported. + */ + + the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED ); + the_attribute_set = + _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED ); + + if ( _Attributes_Is_floating_point( the_attribute_set ) ) + is_fp = true; + else + is_fp = false; + + /* + * Validate the RTEMS API priority and convert it to the core priority range. + */ + + if ( !_Attributes_Is_system_task( the_attribute_set ) ) { + if ( !_RTEMS_tasks_Priority_is_valid( initial_priority ) ) + return RTEMS_INVALID_PRIORITY; + } + + core_priority = _RTEMS_tasks_Priority_to_Core( initial_priority ); + +#if defined(RTEMS_MULTIPROCESSING) + if ( _Attributes_Is_global( the_attribute_set ) ) { + + is_global = true; + + if ( !_System_state_Is_multiprocessing ) + return RTEMS_MP_NOT_CONFIGURED; + + } else + is_global = false; +#endif + + /* + * Make sure system is MP if this task is global + */ + + /* + * Lock the allocator mutex for protection + */ + _RTEMS_Lock_allocator(); + + /* + * Allocate the thread control block and -- if the task is global -- + * allocate a global object control block. + * + * NOTE: This routine does not use the combined allocate and open + * global object routine because this results in a lack of + * control over when memory is allocated and can be freed in + * the event of an error. + */ + + the_thread = _RTEMS_tasks_Allocate(); + + if ( !the_thread ) { + _RTEMS_Unlock_allocator(); + return RTEMS_TOO_MANY; + } + +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global ) { + the_global_object = _Objects_MP_Allocate_global_object(); + + if ( _Objects_MP_Is_null_global_object( the_global_object ) ) { + _RTEMS_tasks_Free( the_thread ); + _RTEMS_Unlock_allocator(); + return RTEMS_TOO_MANY; + } + } +#endif + + /* + * Initialize the core thread for this task. + */ + + status = _Thread_Initialize( + &_RTEMS_tasks_Information, + the_thread, + NULL, + stack_size, + is_fp, + core_priority, + _Modes_Is_preempt(initial_modes) ? true : false, + _Modes_Is_timeslice(initial_modes) ? + THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE : + THREAD_CPU_BUDGET_ALGORITHM_NONE, + NULL, /* no budget algorithm callout */ + _Modes_Get_interrupt_level(initial_modes), + (Objects_Name) name + ); + + if ( !status ) { +#if defined(RTEMS_MULTIPROCESSING) + if ( is_global ) + _Objects_MP_Free_global_object( the_global_object ); +#endif + _RTEMS_tasks_Free( the_thread ); + _RTEMS_Unlock_allocator(); + return RTEMS_UNSATISFIED; + } + + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + asr = &api->Signal; + + asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? false : true; + + *id = the_thread->Object.id; + +#if defined(RTEMS_MULTIPROCESSING) + the_thread->is_global = is_global; + if ( is_global ) { + + _Objects_MP_Open( + &_RTEMS_tasks_Information, + the_global_object, + name, + the_thread->Object.id + ); + + _RTEMS_tasks_MP_Send_process_packet( + RTEMS_TASKS_MP_ANNOUNCE_CREATE, + the_thread->Object.id, + name + ); + + } +#endif + + _RTEMS_Unlock_allocator(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/taskdata.c b/cpukit/rtems/src/taskdata.c new file mode 100644 index 0000000000..13c0a1f6e1 --- /dev/null +++ b/cpukit/rtems/src/taskdata.c @@ -0,0 +1,22 @@ +/* + * RTEMS Task Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate RTEMS Classic API tasks data */ +#define RTEMS_TASKS_EXTERN + +#include <rtems/system.h> +#include <rtems/rtems/tasks.h> diff --git a/cpukit/rtems/src/taskdelete.c b/cpukit/rtems/src/taskdelete.c new file mode 100644 index 0000000000..a29ea77ac4 --- /dev/null +++ b/cpukit/rtems/src/taskdelete.c @@ -0,0 +1,110 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/apimutex.h> + +/*PAGE + * + * rtems_task_delete + * + * This directive allows a thread to delete itself or the thread + * identified in the id field. The executive halts execution + * of the thread and frees the thread control block. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * nothing - if id is the requesting thread (always succeeds) + * RTEMS_SUCCESSFUL - if successful and id is + * not the requesting thread + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_delete( + rtems_id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + Objects_Information *the_information; + + _RTEMS_Lock_allocator(); + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + the_information = _Objects_Get_information_id( the_thread->Object.id ); + + #if defined(RTEMS_DEBUG) + if ( !the_information ) { + _Thread_Enable_dispatch(); + return RTEMS_INVALID_ID; + /* This should never happen if _Thread_Get() works right */ + } + #endif + + #if defined(RTEMS_MULTIPROCESSING) + if ( the_thread->is_global ) { + _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id ); + _RTEMS_tasks_MP_Send_process_packet( + RTEMS_TASKS_MP_ANNOUNCE_DELETE, + the_thread->Object.id, + 0 /* Not used */ + ); + } + #endif + + _Thread_Close( the_information, the_thread ); + + _RTEMS_tasks_Free( the_thread ); + + _RTEMS_Unlock_allocator(); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _RTEMS_Unlock_allocator(); + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + + _RTEMS_Unlock_allocator(); + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/taskgetnote.c b/cpukit/rtems/src/taskgetnote.c new file mode 100644 index 0000000000..46c28460a5 --- /dev/null +++ b/cpukit/rtems/src/taskgetnote.c @@ -0,0 +1,116 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_get_note + * + * This directive obtains the note from the specified notepad + * of the specified thread. + * + * Input parameters: + * id - thread id + * notepad - notepad number + * note - pointer to note + * + * Output parameters: + * note - filled in if successful + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_get_note( + rtems_id id, + uint32_t notepad, + uint32_t *note +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + RTEMS_API_Control *api; + + if ( !rtems_configuration_get_notepads_enabled() ) + return RTEMS_NOT_CONFIGURED; + + if ( !note ) + return RTEMS_INVALID_ADDRESS; + + /* + * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would + * be checking an unsigned number for being negative. + */ + + if ( notepad > RTEMS_NOTEPAD_LAST ) + return RTEMS_INVALID_NUMBER; + + /* + * Optimize the most likely case to avoid the Thread_Dispatch. + */ + + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || + _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { + api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; + *note = api->Notepads[ notepad ]; + return RTEMS_SUCCESSFUL; + } + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + *note = api->Notepads[ notepad ]; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = note; + + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_GET_NOTE_REQUEST, + id, + 0, /* Not used */ + notepad, + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/taskident.c b/cpukit/rtems/src/taskident.c new file mode 100644 index 0000000000..8888c77ee2 --- /dev/null +++ b/cpukit/rtems/src/taskident.c @@ -0,0 +1,72 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_ident + * + * This directive returns the system ID associated with + * the thread name. + * + * Input parameters: + * name - user defined thread name + * node - node(s) to be searched + * id - pointer to thread id + * + * Output parameters: + * *id - thread id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_ident( + rtems_name name, + uint32_t node, + rtems_id *id +) +{ + Objects_Name_or_id_lookup_errors status; + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + + if ( name == OBJECTS_ID_OF_SELF ) { + *id = _Thread_Executing->Object.id; + return RTEMS_SUCCESSFUL; + } + + status = _Objects_Name_to_id_u32( &_RTEMS_tasks_Information, name, node, id ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/taskinitusers.c b/cpukit/rtems/src/taskinitusers.c new file mode 100644 index 0000000000..b0c1198421 --- /dev/null +++ b/cpukit/rtems/src/taskinitusers.c @@ -0,0 +1,92 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/rtems/rtemsapi.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * _RTEMS_tasks_Initialize_user_tasks_body + * + * This routine creates and starts all configured user + * initialzation threads. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _RTEMS_tasks_Initialize_user_tasks_body( void ) +{ + uint32_t index; + uint32_t maximum; + rtems_id id; + rtems_status_code return_value; + rtems_initialization_tasks_table *user_tasks; + + /* + * Move information into local variables + */ + user_tasks = Configuration_RTEMS_API.User_initialization_tasks_table; + maximum = Configuration_RTEMS_API.number_of_initialization_tasks; + + /* + * Verify that we have a set of user tasks to iterate + */ + if ( !user_tasks ) + return; + + /* + * Now iterate over the initialization tasks and create/start them. + */ + for ( index=0 ; index < maximum ; index++ ) { + return_value = rtems_task_create( + user_tasks[ index ].name, + user_tasks[ index ].initial_priority, + user_tasks[ index ].stack_size, + user_tasks[ index ].mode_set, + user_tasks[ index ].attribute_set, + &id + ); + if ( !rtems_is_status_successful( return_value ) ) + _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, true, return_value ); + + return_value = rtems_task_start( + id, + user_tasks[ index ].entry_point, + user_tasks[ index ].argument + ); + if ( !rtems_is_status_successful( return_value ) ) + _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, true, return_value ); + } +} diff --git a/cpukit/rtems/src/taskissuspended.c b/cpukit/rtems/src/taskissuspended.c new file mode 100644 index 0000000000..eaea72160d --- /dev/null +++ b/cpukit/rtems/src/taskissuspended.c @@ -0,0 +1,80 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_is_suspended + * + * This directive returns a status indicating whether or not + * the specified task is suspended. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful and not suspended + * RTEMS_ALREADY_SUSPENDED - if successful and suspended + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_is_suspended( + rtems_id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( !_States_Is_suspended( the_thread->current_state ) ) { + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_ALREADY_SUSPENDED; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c new file mode 100644 index 0000000000..40a456f2be --- /dev/null +++ b/cpukit/rtems/src/taskmode.c @@ -0,0 +1,125 @@ +/* + * RTEMS Task Manager - Change Task Mode + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/* + * rtems_task_mode + * + * This directive enables and disables several modes of + * execution for the requesting thread. + * + * Input parameters: + * mode_set - new mode + * mask - mask + * previous_mode_set - address of previous mode set + * + * Output: + * *previous_mode_set - previous mode set + * always return RTEMS_SUCCESSFUL; + */ + +rtems_status_code rtems_task_mode( + rtems_mode mode_set, + rtems_mode mask, + rtems_mode *previous_mode_set +) +{ + Thread_Control *executing; + RTEMS_API_Control *api; + ASR_Information *asr; + bool is_asr_enabled = false; + bool needs_asr_dispatching = false; + rtems_mode old_mode; + + if ( !previous_mode_set ) + return RTEMS_INVALID_ADDRESS; + + executing = _Thread_Executing; + api = executing->API_Extensions[ THREAD_API_RTEMS ]; + asr = &api->Signal; + + old_mode = (executing->is_preemptible) ? RTEMS_PREEMPT : RTEMS_NO_PREEMPT; + + if ( executing->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_NONE ) + old_mode |= RTEMS_NO_TIMESLICE; + else + old_mode |= RTEMS_TIMESLICE; + + old_mode |= (asr->is_enabled) ? RTEMS_ASR : RTEMS_NO_ASR; + old_mode |= _ISR_Get_level(); + + *previous_mode_set = old_mode; + + /* + * These are generic thread scheduling characteristics. + */ + if ( mask & RTEMS_PREEMPT_MASK ) + executing->is_preemptible = _Modes_Is_preempt(mode_set) ? true : false; + + if ( mask & RTEMS_TIMESLICE_MASK ) { + if ( _Modes_Is_timeslice(mode_set) ) { + executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE; + executing->cpu_time_budget = _Thread_Ticks_per_timeslice; + } else + executing->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; + } + + /* + * Set the new interrupt level + */ + if ( mask & RTEMS_INTERRUPT_MASK ) + _Modes_Set_interrupt_level( mode_set ); + + /* + * This is specific to the RTEMS API + */ + is_asr_enabled = false; + needs_asr_dispatching = false; + + if ( mask & RTEMS_ASR_MASK ) { + is_asr_enabled = _Modes_Is_asr_disabled( mode_set ) ? false : true; + if ( is_asr_enabled != asr->is_enabled ) { + asr->is_enabled = is_asr_enabled; + _ASR_Swap_signals( asr ); + if ( _ASR_Are_signals_pending( asr ) ) { + needs_asr_dispatching = true; + } + } + } + + if ( _System_state_Is_up( _System_state_Get() ) ) { + if (_Thread_Evaluate_is_dispatch_needed( needs_asr_dispatching ) ) + _Thread_Dispatch(); + } + + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/taskmp.c b/cpukit/rtems/src/taskmp.c new file mode 100644 index 0000000000..5f13860492 --- /dev/null +++ b/cpukit/rtems/src/taskmp.c @@ -0,0 +1,343 @@ +/* + * Multiprocessing Support for the RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/score/mpci.h> +#include <rtems/score/mppkt.h> +#include <rtems/score/object.h> +#include <rtems/rtems/options.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> +#include <rtems/rtems/support.h> + +/*PAGE + * + * _RTEMS_tasks_MP_Send_process_packet + * + */ + +void _RTEMS_tasks_MP_Send_process_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Objects_Id task_id, + rtems_name name +) +{ + RTEMS_tasks_MP_Packet *the_packet; + + switch ( operation ) { + + case RTEMS_TASKS_MP_ANNOUNCE_CREATE: + case RTEMS_TASKS_MP_ANNOUNCE_DELETE: + + the_packet = _RTEMS_tasks_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_TASKS; + the_packet->Prefix.length = sizeof ( RTEMS_tasks_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( RTEMS_tasks_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = task_id; + the_packet->name = name; + + _MPCI_Send_process_packet( MPCI_ALL_NODES, &the_packet->Prefix ); + break; + + case RTEMS_TASKS_MP_SUSPEND_REQUEST: + case RTEMS_TASKS_MP_SUSPEND_RESPONSE: + case RTEMS_TASKS_MP_RESUME_REQUEST: + case RTEMS_TASKS_MP_RESUME_RESPONSE: + case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST: + case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE: + case RTEMS_TASKS_MP_GET_NOTE_REQUEST: + case RTEMS_TASKS_MP_GET_NOTE_RESPONSE: + case RTEMS_TASKS_MP_SET_NOTE_REQUEST: + case RTEMS_TASKS_MP_SET_NOTE_RESPONSE: + break; + } +} + +/*PAGE + * + * _RTEMS_tasks_MP_Send_request_packet + * + */ + +rtems_status_code _RTEMS_tasks_MP_Send_request_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Objects_Id task_id, + rtems_task_priority new_priority, + uint32_t notepad, + uint32_t note +) +{ + RTEMS_tasks_MP_Packet *the_packet; + + switch ( operation ) { + + case RTEMS_TASKS_MP_SUSPEND_REQUEST: + case RTEMS_TASKS_MP_RESUME_REQUEST: + case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST: + case RTEMS_TASKS_MP_GET_NOTE_REQUEST: + case RTEMS_TASKS_MP_SET_NOTE_REQUEST: + + the_packet = _RTEMS_tasks_MP_Get_packet(); + the_packet->Prefix.the_class = MP_PACKET_TASKS; + the_packet->Prefix.length = sizeof ( RTEMS_tasks_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( RTEMS_tasks_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = task_id; + the_packet->the_priority = new_priority; + the_packet->notepad = notepad; + the_packet->note = note; + + return _MPCI_Send_request_packet( + _Objects_Get_node( task_id ), + &the_packet->Prefix, + STATES_READY /* Not used */ + ); + break; + + case RTEMS_TASKS_MP_ANNOUNCE_CREATE: + case RTEMS_TASKS_MP_ANNOUNCE_DELETE: + case RTEMS_TASKS_MP_SUSPEND_RESPONSE: + case RTEMS_TASKS_MP_RESUME_RESPONSE: + case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE: + case RTEMS_TASKS_MP_GET_NOTE_RESPONSE: + case RTEMS_TASKS_MP_SET_NOTE_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _RTEMS_tasks_MP_Send_response_packet + * + */ + +void _RTEMS_tasks_MP_Send_response_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Thread_Control *the_thread +) +{ + RTEMS_tasks_MP_Packet *the_packet; + + switch ( operation ) { + + case RTEMS_TASKS_MP_SUSPEND_RESPONSE: + case RTEMS_TASKS_MP_RESUME_RESPONSE: + case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE: + case RTEMS_TASKS_MP_GET_NOTE_RESPONSE: + case RTEMS_TASKS_MP_SET_NOTE_RESPONSE: + + the_packet = (RTEMS_tasks_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + _Objects_Get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case RTEMS_TASKS_MP_ANNOUNCE_CREATE: + case RTEMS_TASKS_MP_ANNOUNCE_DELETE: + case RTEMS_TASKS_MP_SUSPEND_REQUEST: + case RTEMS_TASKS_MP_RESUME_REQUEST: + case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST: + case RTEMS_TASKS_MP_GET_NOTE_REQUEST: + case RTEMS_TASKS_MP_SET_NOTE_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _RTEMS_tasks_MP_Process_packet + * + */ + +void _RTEMS_tasks_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + RTEMS_tasks_MP_Packet *the_packet; + Thread_Control *the_thread; + bool ignored; + + the_packet = (RTEMS_tasks_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case RTEMS_TASKS_MP_ANNOUNCE_CREATE: + + ignored = _Objects_MP_Allocate_and_open( + &_RTEMS_tasks_Information, + the_packet->name, + the_packet->Prefix.id, + true + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case RTEMS_TASKS_MP_ANNOUNCE_DELETE: + + _Objects_MP_Close( &_RTEMS_tasks_Information, the_packet->Prefix.id ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case RTEMS_TASKS_MP_SUSPEND_REQUEST: + + the_packet->Prefix.return_code = rtems_task_suspend( + the_packet->Prefix.id + ); + + _RTEMS_tasks_MP_Send_response_packet( + RTEMS_TASKS_MP_SUSPEND_RESPONSE, + _Thread_Executing + ); + break; + + case RTEMS_TASKS_MP_SUSPEND_RESPONSE: + case RTEMS_TASKS_MP_RESUME_RESPONSE: + case RTEMS_TASKS_MP_SET_NOTE_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case RTEMS_TASKS_MP_RESUME_REQUEST: + + the_packet->Prefix.return_code = rtems_task_resume( + the_packet->Prefix.id + ); + + _RTEMS_tasks_MP_Send_response_packet( + RTEMS_TASKS_MP_RESUME_RESPONSE, + _Thread_Executing + ); + break; + + case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST: + + the_packet->Prefix.return_code = rtems_task_set_priority( + the_packet->Prefix.id, + the_packet->the_priority, + &the_packet->the_priority + ); + + _RTEMS_tasks_MP_Send_response_packet( + RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE, + _Thread_Executing + ); + break; + + case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + *(rtems_task_priority *)the_thread->Wait.return_argument = + the_packet->the_priority; + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case RTEMS_TASKS_MP_GET_NOTE_REQUEST: + + the_packet->Prefix.return_code = rtems_task_get_note( + the_packet->Prefix.id, + the_packet->notepad, + &the_packet->note + ); + + _RTEMS_tasks_MP_Send_response_packet( + RTEMS_TASKS_MP_GET_NOTE_RESPONSE, + _Thread_Executing + ); + break; + + case RTEMS_TASKS_MP_GET_NOTE_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + *(uint32_t *)the_thread->Wait.return_argument = the_packet->note; + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case RTEMS_TASKS_MP_SET_NOTE_REQUEST: + + the_packet->Prefix.return_code = rtems_task_set_note( + the_packet->Prefix.id, + the_packet->notepad, + the_packet->note + ); + + _RTEMS_tasks_MP_Send_response_packet( + RTEMS_TASKS_MP_SET_NOTE_RESPONSE, + _Thread_Executing + ); + break; + } +} + +/*PAGE + * + * _RTEMS_tasks_MP_Send_object_was_deleted + * + * This routine is not neededby the Tasks since a task + * cannot be globally deleted. + * + */ + +/*PAGE + * + * _RTEMS_tasks_MP_Send_extract_proxy + * + * This routine is not neededby the Tasks since a task + * cannot be globally deleted. + * + */ + +/*PAGE + * + * _RTEMS_tasks_MP_Get_packet + * + */ + +RTEMS_tasks_MP_Packet *_RTEMS_tasks_MP_Get_packet ( void ) +{ + return (RTEMS_tasks_MP_Packet *) _MPCI_Get_packet(); +} + +/* end of file */ diff --git a/cpukit/rtems/src/taskrestart.c b/cpukit/rtems/src/taskrestart.c new file mode 100644 index 0000000000..bc85137b23 --- /dev/null +++ b/cpukit/rtems/src/taskrestart.c @@ -0,0 +1,83 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_restart + * + * This directive readies the specified thread. It restores + * the thread environment to the original values established + * at thread creation and start time. A thread can be restarted + * from any state except the dormant state. + * + * Input parameters: + * id - thread id + * argument - thread argument + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_restart( + rtems_id id, + uint32_t argument +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( _Thread_Restart( the_thread, NULL, argument ) ) { + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INCORRECT_STATE; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/taskresume.c b/cpukit/rtems/src/taskresume.c new file mode 100644 index 0000000000..1c6ef490b7 --- /dev/null +++ b/cpukit/rtems/src/taskresume.c @@ -0,0 +1,85 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_resume + * + * This directive will remove the specified thread + * from the suspended state. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_resume( + rtems_id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( _States_Is_suspended( the_thread->current_state ) ) { + _Thread_Resume( the_thread ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INCORRECT_STATE; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_RESUME_REQUEST, + id, + 0, /* Not used */ + 0, /* Not used */ + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c new file mode 100644 index 0000000000..e81bf72167 --- /dev/null +++ b/cpukit/rtems/src/tasks.c @@ -0,0 +1,305 @@ +/* + * RTEMS Task Manager -- Initialize Manager + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * _RTEMS_tasks_Create_extension + * + * This routine is an extension routine that is invoked as part + * of creating any type of task or thread in the system. If the + * task is created via another API, then this routine is invoked + * and this API given the opportunity to initialize its extension + * area. + */ + +bool _RTEMS_tasks_Create_extension( + Thread_Control *executing, + Thread_Control *created +) +{ + RTEMS_API_Control *api; + int i; + size_t to_allocate; + + /* + * Notepads must be the last entry in the structure and they + * can be left off if disabled in the configuration. + */ + to_allocate = sizeof( RTEMS_API_Control ); + if ( !rtems_configuration_get_notepads_enabled() ) + to_allocate -= (RTEMS_NUMBER_NOTEPADS * sizeof(uint32_t)); + + api = _Workspace_Allocate( to_allocate ); + + if ( !api ) + return false; + + created->API_Extensions[ THREAD_API_RTEMS ] = api; + + api->pending_events = EVENT_SETS_NONE_PENDING; + api->event_condition = 0; + _ASR_Initialize( &api->Signal ); + created->task_variables = NULL; + + if ( rtems_configuration_get_notepads_enabled() ) { + for (i=0; i < RTEMS_NUMBER_NOTEPADS; i++) + api->Notepads[i] = 0; + } + + return true; +} + +/*PAGE + * + * _RTEMS_tasks_Start_extension + * + * This extension routine is invoked when a task is started for the + * first time. + */ + +void _RTEMS_tasks_Start_extension( + Thread_Control *executing, + Thread_Control *started +) +{ + RTEMS_API_Control *api; + + api = started->API_Extensions[ THREAD_API_RTEMS ]; + + api->pending_events = EVENT_SETS_NONE_PENDING; +} + +/*PAGE + * + * _RTEMS_tasks_Delete_extension + * + * This extension routine is invoked when a task is deleted. + */ + +void _RTEMS_tasks_Delete_extension( + Thread_Control *executing, + Thread_Control *deleted +) +{ + rtems_task_variable_t *tvp, *next; + + /* + * Free per task variable memory + */ + + tvp = deleted->task_variables; + deleted->task_variables = NULL; + while (tvp) { + next = (rtems_task_variable_t *)tvp->next; + _RTEMS_Tasks_Invoke_task_variable_dtor( deleted, tvp ); + tvp = next; + } + + /* + * Free API specific memory + */ + + (void) _Workspace_Free( deleted->API_Extensions[ THREAD_API_RTEMS ] ); + deleted->API_Extensions[ THREAD_API_RTEMS ] = NULL; +} + +/*PAGE + * + * _RTEMS_tasks_Switch_extension + * + * This extension routine is invoked at each context switch. + */ + +void _RTEMS_tasks_Switch_extension( + Thread_Control *executing, + Thread_Control *heir +) +{ + rtems_task_variable_t *tvp; + + /* + * Per Task Variables + */ + + tvp = executing->task_variables; + while (tvp) { + tvp->tval = *tvp->ptr; + *tvp->ptr = tvp->gval; + tvp = (rtems_task_variable_t *)tvp->next; + } + + tvp = heir->task_variables; + while (tvp) { + tvp->gval = *tvp->ptr; + *tvp->ptr = tvp->tval; + tvp = (rtems_task_variable_t *)tvp->next; + } +} + +/*PAGE + * + * _RTEMS_tasks_Post_switch_extension + * + * This extension routine is invoked at each context switch. + */ + +void _RTEMS_tasks_Post_switch_extension( + Thread_Control *executing +) +{ + ISR_Level level; + RTEMS_API_Control *api; + ASR_Information *asr; + rtems_signal_set signal_set; + Modes_Control prev_mode; + + api = executing->API_Extensions[ THREAD_API_RTEMS ]; + if ( !api ) + return; + + /* + * Signal Processing + */ + + asr = &api->Signal; + + _ISR_Disable( level ); + signal_set = asr->signals_posted; + asr->signals_posted = 0; + _ISR_Enable( level ); + + + if ( !signal_set ) /* similar to _ASR_Are_signals_pending( asr ) */ + return; + + asr->nest_level += 1; + rtems_task_mode( asr->mode_set, RTEMS_ALL_MODE_MASKS, &prev_mode ); + + (*asr->handler)( signal_set ); + + asr->nest_level -= 1; + rtems_task_mode( prev_mode, RTEMS_ALL_MODE_MASKS, &prev_mode ); + +} + +API_extensions_Control _RTEMS_tasks_API_extensions = { + { NULL, NULL }, + #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API) + NULL, /* predriver */ + #endif + _RTEMS_tasks_Initialize_user_tasks, /* postdriver */ + _RTEMS_tasks_Post_switch_extension /* post switch */ +}; + +User_extensions_Control _RTEMS_tasks_User_extensions = { + { NULL, NULL }, + { { NULL, NULL }, _RTEMS_tasks_Switch_extension }, + { _RTEMS_tasks_Create_extension, /* create */ + _RTEMS_tasks_Start_extension, /* start */ + _RTEMS_tasks_Start_extension, /* restart */ + _RTEMS_tasks_Delete_extension, /* delete */ + _RTEMS_tasks_Switch_extension, /* switch */ + NULL, /* begin */ + NULL, /* exitted */ + NULL /* fatal */ + } +}; + +/*PAGE + * + * _RTEMS_tasks_Manager_initialization + * + * This routine initializes all Task Manager related data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _RTEMS_tasks_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_RTEMS_tasks_Information, /* object information table */ + OBJECTS_CLASSIC_API, /* object API */ + OBJECTS_RTEMS_TASKS, /* object class */ + Configuration_RTEMS_API.maximum_tasks, + /* maximum objects of this class */ + sizeof( Thread_Control ), /* size of this object's control block */ + false, /* true if the name is a string */ + RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */ +#if defined(RTEMS_MULTIPROCESSING) + , + true, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); + + /* + * Add all the extensions for this API + */ + + _User_extensions_Add_API_set( &_RTEMS_tasks_User_extensions ); + + _API_extensions_Add( &_RTEMS_tasks_API_extensions ); + + /* + * Register the MP Process Packet routine. + */ + +#if defined(RTEMS_MULTIPROCESSING) + _MPCI_Register_packet_processor( + MP_PACKET_TASKS, + _RTEMS_tasks_MP_Process_packet + ); +#endif + +} + +/*PAGE + * + * _RTEMS_tasks_Initialize_user_tasks + * + * This routine creates and starts all configured user + * initialzation threads. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _RTEMS_tasks_Initialize_user_tasks( void ) +{ + if ( _RTEMS_tasks_Initialize_user_tasks_p ) + (*_RTEMS_tasks_Initialize_user_tasks_p)(); +} diff --git a/cpukit/rtems/src/taskself.c b/cpukit/rtems/src/taskself.c new file mode 100644 index 0000000000..e596c15c60 --- /dev/null +++ b/cpukit/rtems/src/taskself.c @@ -0,0 +1,24 @@ +/* + * RTEMS Task Manager - Get ID of Self + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/tasks.h> + +rtems_id rtems_task_self(void) +{ + return _Thread_Executing->Object.id; +} diff --git a/cpukit/rtems/src/tasksetnote.c b/cpukit/rtems/src/tasksetnote.c new file mode 100644 index 0000000000..cd2bfb6dd1 --- /dev/null +++ b/cpukit/rtems/src/tasksetnote.c @@ -0,0 +1,109 @@ +/* + * RTEMS Task Manager + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_set_note + * + * This directive sets the specified notepad contents to the given + * note. + * + * Input parameters: + * id - thread id + * notepad - notepad number + * note - note value + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_set_note( + rtems_id id, + uint32_t notepad, + uint32_t note +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + RTEMS_API_Control *api; + + if ( !rtems_configuration_get_notepads_enabled() ) + return RTEMS_NOT_CONFIGURED; + + /* + * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would + * be checking an unsigned number for being negative. + */ + + if ( notepad > RTEMS_NOTEPAD_LAST ) + return RTEMS_INVALID_NUMBER; + + /* + * Optimize the most likely case to avoid the Thread_Dispatch. + */ + + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || + _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { + api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; + api->Notepads[ notepad ] = note; + return RTEMS_SUCCESSFUL; + } + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; + api->Notepads[ notepad ] = note; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SET_NOTE_REQUEST, + id, + 0, /* Not used */ + notepad, + note + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/tasksetpriority.c b/cpukit/rtems/src/tasksetpriority.c new file mode 100644 index 0000000000..4e85e56533 --- /dev/null +++ b/cpukit/rtems/src/tasksetpriority.c @@ -0,0 +1,102 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_set_priority + * + * This directive changes the priority of the specified thread. + * The specified thread can be any thread in the system including + * the requesting thread. + * + * Input parameters: + * id - thread id (0 indicates requesting thread) + * new_priority - thread priority (0 indicates current priority) + * old_priority - pointer to previous priority + * + * Output parameters: + * old_priority - previous priority + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_set_priority( + rtems_id id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + if ( new_priority != RTEMS_CURRENT_PRIORITY && + !_RTEMS_tasks_Priority_is_valid( new_priority ) ) + return RTEMS_INVALID_PRIORITY; + + if ( !old_priority ) + return RTEMS_INVALID_ADDRESS; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + /* XXX need helper to "convert" from core priority */ + *old_priority = the_thread->current_priority; + if ( new_priority != RTEMS_CURRENT_PRIORITY ) { + the_thread->real_priority = new_priority; + if ( the_thread->resource_count == 0 || + the_thread->current_priority > new_priority ) + _Thread_Change_priority( the_thread, new_priority, false ); + } + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = old_priority; + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SET_PRIORITY_REQUEST, + id, + new_priority, + 0, /* Not used */ + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/taskstart.c b/cpukit/rtems/src/taskstart.c new file mode 100644 index 0000000000..9d2ce0cec4 --- /dev/null +++ b/cpukit/rtems/src/taskstart.c @@ -0,0 +1,88 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_start + * + * This directive readies the thread identified by the "id" + * based on its current priorty, to await execution. A thread + * can be started only from the dormant state. + * + * Input parameters: + * id - thread id + * entry_point - start execution address of thread + * argument - thread argument + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_start( + rtems_id id, + rtems_task_entry entry_point, + rtems_task_argument argument +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + if ( entry_point == NULL ) + return RTEMS_INVALID_ADDRESS; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( _Thread_Start( + the_thread, THREAD_START_NUMERIC, entry_point, NULL, argument ) ) { + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INCORRECT_STATE; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/tasksuspend.c b/cpukit/rtems/src/tasksuspend.c new file mode 100644 index 0000000000..3f7e8b7d03 --- /dev/null +++ b/cpukit/rtems/src/tasksuspend.c @@ -0,0 +1,86 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_suspend + * + * This directive will place the specified thread in the "suspended" + * state. Note that the suspended state can be in addition to + * other waiting states. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_suspend( + rtems_id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( !_States_Is_suspended( the_thread->current_state ) ) { + _Thread_Suspend( the_thread ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_ALREADY_SUSPENDED; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SUSPEND_REQUEST, + id, + 0, /* Not used */ + 0, /* Not used */ + 0 /* Not used */ + ); +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/taskvariable_invoke_dtor.c b/cpukit/rtems/src/taskvariable_invoke_dtor.c new file mode 100644 index 0000000000..d348c6d90e --- /dev/null +++ b/cpukit/rtems/src/taskvariable_invoke_dtor.c @@ -0,0 +1,43 @@ +/* + * Invoke the destructor on a per-task variable + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/wkspace.h> + +void _RTEMS_Tasks_Invoke_task_variable_dtor( + Thread_Control *the_thread, + rtems_task_variable_t *tvp +) +{ + void (*dtor)(void *); + void *value; + + dtor = tvp->dtor; + if (_Thread_Is_executing(the_thread)) { + value = *tvp->ptr; + *tvp->ptr = tvp->gval; + } else { + value = tvp->tval; + } + + if ( dtor ) + (*dtor)(value); + + _Workspace_Free(tvp); +} diff --git a/cpukit/rtems/src/taskvariableadd.c b/cpukit/rtems/src/taskvariableadd.c new file mode 100644 index 0000000000..41d6bed57c --- /dev/null +++ b/cpukit/rtems/src/taskvariableadd.c @@ -0,0 +1,87 @@ +/* + * rtems_task_variable_add - Add a per-task variable + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/wkspace.h> + +/* + * rtems_task_variable_add + * + * This directive registers a task variable. + */ + +rtems_status_code rtems_task_variable_add( + rtems_id tid, + void **ptr, + void (*dtor)(void *) +) +{ + Thread_Control *the_thread; + Objects_Locations location; + rtems_task_variable_t *tvp, *new; + + if ( !ptr ) + return RTEMS_INVALID_ADDRESS; + + the_thread = _Thread_Get (tid, &location); + switch (location) { + + case OBJECTS_LOCAL: + /* + * Figure out if the variable is already in this task's list. + */ + tvp = the_thread->task_variables; + while (tvp) { + if (tvp->ptr == ptr) { + tvp->dtor = dtor; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + tvp = (rtems_task_variable_t *)tvp->next; + } + + /* + * Now allocate memory for this task variable. + */ + new = (rtems_task_variable_t *) + _Workspace_Allocate(sizeof(rtems_task_variable_t)); + if (new == NULL) { + _Thread_Enable_dispatch(); + return RTEMS_NO_MEMORY; + } + new->gval = *ptr; + new->ptr = ptr; + new->dtor = dtor; + + new->next = (struct rtems_task_variable_tt *)the_thread->task_variables; + the_thread->task_variables = new; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/taskvariabledelete.c b/cpukit/rtems/src/taskvariabledelete.c new file mode 100644 index 0000000000..fe34732f57 --- /dev/null +++ b/cpukit/rtems/src/taskvariabledelete.c @@ -0,0 +1,76 @@ +/* + * rtems_task_variable_delete - Delete a per-task variable + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/wkspace.h> + +/* + * rtems_task_variable_delete + * + * This directive removes a task variable. + */ + +rtems_status_code rtems_task_variable_delete( + rtems_id tid, + void **ptr +) +{ + Thread_Control *the_thread; + Objects_Locations location; + rtems_task_variable_t *tvp, *prev; + + if ( !ptr ) + return RTEMS_INVALID_ADDRESS; + + prev = NULL; + + the_thread = _Thread_Get (tid, &location); + switch (location) { + + case OBJECTS_LOCAL: + tvp = the_thread->task_variables; + while (tvp) { + if (tvp->ptr == ptr) { + if (prev) + prev->next = tvp->next; + else + the_thread->task_variables = (rtems_task_variable_t *)tvp->next; + + _RTEMS_Tasks_Invoke_task_variable_dtor( the_thread, tvp ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + prev = tvp; + tvp = (rtems_task_variable_t *)tvp->next; + } + _Thread_Enable_dispatch(); + return RTEMS_INVALID_ADDRESS; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/taskvariableget.c b/cpukit/rtems/src/taskvariableget.c new file mode 100644 index 0000000000..fbe3b10d7f --- /dev/null +++ b/cpukit/rtems/src/taskvariableget.c @@ -0,0 +1,78 @@ +/* + * rtems_task_variable_get - Get a per-task variable + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/wkspace.h> + +/* + * rtems_task_variable_get + * + * This directive gets the value of a task variable. + */ + +rtems_status_code rtems_task_variable_get( + rtems_id tid, + void **ptr, + void **result +) +{ + Thread_Control *the_thread; + Objects_Locations location; + rtems_task_variable_t *tvp; + + if ( !ptr ) + return RTEMS_INVALID_ADDRESS; + + if ( !result ) + return RTEMS_INVALID_ADDRESS; + + the_thread = _Thread_Get (tid, &location); + switch (location) { + + case OBJECTS_LOCAL: + /* + * Figure out if the variable is in this task's list. + */ + tvp = the_thread->task_variables; + while (tvp) { + if (tvp->ptr == ptr) { + /* + * Should this return the current (i.e not the + * saved) value if `tid' is the current task? + */ + *result = tvp->tval; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + tvp = (rtems_task_variable_t *)tvp->next; + } + _Thread_Enable_dispatch(); + return RTEMS_INVALID_ADDRESS; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; +#endif + + case OBJECTS_ERROR: + break; + } + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/taskwakeafter.c b/cpukit/rtems/src/taskwakeafter.c new file mode 100644 index 0000000000..2f6fecfe5d --- /dev/null +++ b/cpukit/rtems/src/taskwakeafter.c @@ -0,0 +1,69 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/score/object.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_wake_after + * + * This directive suspends the requesting thread for the given amount + * of ticks. + * + * Input parameters: + * ticks - number of ticks to wait + * + * Output parameters: + * RTEMS_SUCCESSFUL - always successful + */ + +rtems_status_code rtems_task_wake_after( + rtems_interval ticks +) +{ + _Thread_Disable_dispatch(); + if ( ticks == 0 ) { + _Scheduler_Yield(); + } else { + _Thread_Set_state( _Thread_Executing, STATES_DELAYING ); + _Watchdog_Initialize( + &_Thread_Executing->Timer, + _Thread_Delay_ended, + _Thread_Executing->Object.id, + NULL + ); + _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks ); + } + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/taskwakewhen.c b/cpukit/rtems/src/taskwakewhen.c new file mode 100644 index 0000000000..5496f55a73 --- /dev/null +++ b/cpukit/rtems/src/taskwakewhen.c @@ -0,0 +1,87 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/rtems/modes.h> +#include <rtems/rtems/clock.h> +#include <rtems/score/object.h> +#include <rtems/score/stack.h> +#include <rtems/score/states.h> +#include <rtems/rtems/tasks.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/apiext.h> +#include <rtems/score/sysstate.h> + +/*PAGE + * + * rtems_task_wake_when + * + * This directive blocks the requesting thread until the given date and + * time is reached. + * + * Input parameters: + * time_buffer - pointer to the time and date structure + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_wake_when( + rtems_time_of_day *time_buffer +) +{ + Watchdog_Interval seconds; + + if ( !_TOD_Is_set ) + return RTEMS_NOT_DEFINED; + + if ( !time_buffer ) + return RTEMS_INVALID_ADDRESS; + + time_buffer->ticks = 0; + + if ( !_TOD_Validate( time_buffer ) ) + return RTEMS_INVALID_CLOCK; + + seconds = _TOD_To_seconds( time_buffer ); + + if ( seconds <= _TOD_Seconds_since_epoch() ) + return RTEMS_INVALID_CLOCK; + + _Thread_Disable_dispatch(); + _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME ); + _Watchdog_Initialize( + &_Thread_Executing->Timer, + _Thread_Delay_ended, + _Thread_Executing->Object.id, + NULL + ); + _Watchdog_Insert_seconds( + &_Thread_Executing->Timer, + seconds - _TOD_Seconds_since_epoch() + ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/timercancel.c b/cpukit/rtems/src/timercancel.c new file mode 100644 index 0000000000..abab3f424c --- /dev/null +++ b/cpukit/rtems/src/timercancel.c @@ -0,0 +1,66 @@ +/* + * Timer Manager - rtems_timer_cancel directive + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_timer_cancel + * + * This directive allows a thread to cancel a timer. + * + * Input parameters: + * id - timer id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_cancel( + rtems_id id +) +{ + Timer_Control *the_timer; + Objects_Locations location; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( !_Timer_Is_dormant_class( the_timer->the_class ) ) + (void) _Watchdog_Remove( &the_timer->Ticker ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/timercreate.c b/cpukit/rtems/src/timercreate.c new file mode 100644 index 0000000000..e277768933 --- /dev/null +++ b/cpukit/rtems/src/timercreate.c @@ -0,0 +1,78 @@ +/* + * Timer Manager - rtems_timer_create directive + * + * + * COPYRIGHT (c) 1989-2002. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_timer_create + * + * This directive creates a timer and performs some initialization. + * + * Input parameters: + * name - timer name + * id - pointer to timer id + * + * Output parameters: + * id - timer id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_create( + rtems_name name, + rtems_id *id +) +{ + Timer_Control *the_timer; + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_timer = _Timer_Allocate(); + + if ( !the_timer ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + + the_timer->the_class = TIMER_DORMANT; + _Watchdog_Initialize( &the_timer->Ticker, NULL, 0, NULL ); + + _Objects_Open( + &_Timer_Information, + &the_timer->Object, + (Objects_Name) name + ); + + *id = the_timer->Object.id; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/timerdelete.c b/cpukit/rtems/src/timerdelete.c new file mode 100644 index 0000000000..7dbc812a2e --- /dev/null +++ b/cpukit/rtems/src/timerdelete.c @@ -0,0 +1,67 @@ +/* + * Timer Manager - rtems_timer_delete directive + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_timer_delete + * + * This directive allows a thread to delete a timer. + * + * Input parameters: + * id - timer id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_delete( + rtems_id id +) +{ + Timer_Control *the_timer; + Objects_Locations location; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _Objects_Close( &_Timer_Information, &the_timer->Object ); + (void) _Watchdog_Remove( &the_timer->Ticker ); + _Timer_Free( the_timer ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/timerfireafter.c b/cpukit/rtems/src/timerfireafter.c new file mode 100644 index 0000000000..540ede38ad --- /dev/null +++ b/cpukit/rtems/src/timerfireafter.c @@ -0,0 +1,103 @@ +/* + * Timer Manager - rtems_timer_fire_after directive + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_timer_fire_after + * + * This directive allows a thread to start a timer. + * + * Input parameters: + * id - timer id + * ticks - interval until routine is fired + * routine - routine to schedule + * user_data - passed as argument to routine when it is fired + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_fire_after( + rtems_id id, + rtems_interval ticks, + rtems_timer_service_routine_entry routine, + void *user_data +) +{ + Timer_Control *the_timer; + Objects_Locations location; + ISR_Level level; + + if ( ticks == 0 ) + return RTEMS_INVALID_NUMBER; + + if ( !routine ) + return RTEMS_INVALID_ADDRESS; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + (void) _Watchdog_Remove( &the_timer->Ticker ); + + _ISR_Disable( level ); + + /* + * Check to see if the watchdog has just been inserted by a + * higher priority interrupt. If so, abandon this insert. + */ + + if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) { + _ISR_Enable( level ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + /* + * OK. Now we now the timer was not rescheduled by an interrupt + * so we can atomically initialize it as in use. + */ + + the_timer->the_class = TIMER_INTERVAL; + _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); + _ISR_Enable( level ); + + + _Watchdog_Insert_ticks( &the_timer->Ticker, ticks ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/timerfirewhen.c b/cpukit/rtems/src/timerfirewhen.c new file mode 100644 index 0000000000..670b39ec1b --- /dev/null +++ b/cpukit/rtems/src/timerfirewhen.c @@ -0,0 +1,91 @@ +/* + * Timer Manager - rtems_timer_fire_when directive + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_timer_fire_when + * + * This directive allows a thread to start a timer. + * + * Input parameters: + * id - timer id + * wall_time - time of day to fire timer + * routine - routine to schedule + * user_data - passed as argument to routine when it is fired + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_fire_when( + rtems_id id, + rtems_time_of_day *wall_time, + rtems_timer_service_routine_entry routine, + void *user_data +) +{ + Timer_Control *the_timer; + Objects_Locations location; + rtems_interval seconds; + + if ( !_TOD_Is_set ) + return RTEMS_NOT_DEFINED; + + if ( !_TOD_Validate( wall_time ) ) + return RTEMS_INVALID_CLOCK; + + if ( !routine ) + return RTEMS_INVALID_ADDRESS; + + seconds = _TOD_To_seconds( wall_time ); + if ( seconds <= _TOD_Seconds_since_epoch() ) + return RTEMS_INVALID_CLOCK; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + (void) _Watchdog_Remove( &the_timer->Ticker ); + the_timer->the_class = TIMER_TIME_OF_DAY; + _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); + _Watchdog_Insert_seconds( + &the_timer->Ticker, + seconds - _TOD_Seconds_since_epoch() + ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/timergetinfo.c b/cpukit/rtems/src/timergetinfo.c new file mode 100644 index 0000000000..2b648597fe --- /dev/null +++ b/cpukit/rtems/src/timergetinfo.c @@ -0,0 +1,75 @@ +/* + * Timer Manager - rtems_timer_get_information directive + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_timer_get_information + * + * This directive allows a thread to obtain information about a timer. + * + * Input parameters: + * id - timer id + * the_info - pointer to timer information block + * + * Output parameters: + * *the_info - region information block filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + * + */ + +rtems_status_code rtems_timer_get_information( + rtems_id id, + rtems_timer_information *the_info +) +{ + Timer_Control *the_timer; + Objects_Locations location; + + if ( !the_info ) + return RTEMS_INVALID_ADDRESS; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + the_info->the_class = the_timer->the_class; + the_info->initial = the_timer->Ticker.initial; + the_info->start_time = the_timer->Ticker.start_time; + the_info->stop_time = the_timer->Ticker.stop_time; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/timerident.c b/cpukit/rtems/src/timerident.c new file mode 100644 index 0000000000..1f1ebbcd7d --- /dev/null +++ b/cpukit/rtems/src/timerident.c @@ -0,0 +1,60 @@ +/* + * Timer Manager - rtems_timer_ident directive + * + * + * COPYRIGHT (c) 1989-2002. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_timer_ident + * + * This directive returns the system ID associated with + * the timer name. + * + * Input parameters: + * name - user defined message queue name + * id - pointer to timer id + * + * Output parameters: + * *id - message queue id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_ident( + rtems_name name, + rtems_id *id +) +{ + Objects_Name_or_id_lookup_errors status; + + status = _Objects_Name_to_id_u32( + &_Timer_Information, + name, + OBJECTS_SEARCH_LOCAL_NODE, + id + ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/timerreset.c b/cpukit/rtems/src/timerreset.c new file mode 100644 index 0000000000..4a3e094a08 --- /dev/null +++ b/cpukit/rtems/src/timerreset.c @@ -0,0 +1,93 @@ +/* + * Timer Manager - rtems_timer_reset directive + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_timer_reset + * + * This directive allows a thread to reset a timer. + * + * Input parameters: + * id - timer id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_reset( + rtems_id id +) +{ + Timer_Control *the_timer; + Objects_Locations location; + rtems_status_code status = RTEMS_SUCCESSFUL; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( the_timer->the_class == TIMER_INTERVAL ) { + _Watchdog_Remove( &the_timer->Ticker ); + _Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker ); + } else if ( the_timer->the_class == TIMER_INTERVAL_ON_TASK ) { + Timer_server_Control *timer_server = _Timer_server; + + /* + * There is no way for a timer to have this class unless + * it was scheduled as a server fire. That requires that + * the Timer Server be initiated. So this error cannot + * occur unless something is internally wrong. + */ + #if defined(RTEMS_DEBUG) + if ( !timer_server ) { + _Thread_Enable_dispatch(); + return RTEMS_INCORRECT_STATE; + } + #endif + _Watchdog_Remove( &the_timer->Ticker ); + (*timer_server->schedule_operation)( timer_server, the_timer ); + } else { + /* + * Must be dormant or time of day timer (e.g. TIMER_DORMANT, + * TIMER_TIME_OF_DAY, or TIMER_TIME_OF_DAY_ON_TASK). We + * can only reset active interval timers. + */ + status = RTEMS_NOT_DEFINED; + } + _Thread_Enable_dispatch(); + return status; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/timerserver.c b/cpukit/rtems/src/timerserver.c new file mode 100644 index 0000000000..9f8da0d5c3 --- /dev/null +++ b/cpukit/rtems/src/timerserver.c @@ -0,0 +1,583 @@ +/** + * @file timerserver.c + * + * Timer Manager - rtems_timer_initiate_server directive along with + * the Timer Server Body and support routines + * + * @note Data specific to the Timer Server is declared in this + * file as the Timer Server so it does not have to be in the + * minimum footprint. It is only really required when + * task-based timers are used. Since task-based timers can + * not be started until the server is initiated, this structure + * does not have to be initialized until then. + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * Copyright (c) 2009 embedded brains GmbH. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +#include <rtems/rtems/tasks.h> +#include <rtems/rtems/support.h> +#include <rtems/score/thread.h> + +static Timer_server_Control _Timer_server_Default; + +static void _Timer_server_Stop_interval_system_watchdog( + Timer_server_Control *ts +) +{ + _Watchdog_Remove( &ts->Interval_watchdogs.System_watchdog ); +} + +static void _Timer_server_Reset_interval_system_watchdog( + Timer_server_Control *ts +) +{ + ISR_Level level; + + _Timer_server_Stop_interval_system_watchdog( ts ); + + _ISR_Disable( level ); + if ( !_Chain_Is_empty( &ts->Interval_watchdogs.Chain ) ) { + Watchdog_Interval delta_interval = + _Watchdog_First( &ts->Interval_watchdogs.Chain )->delta_interval; + _ISR_Enable( level ); + + /* + * The unit is TICKS here. + */ + _Watchdog_Insert_ticks( + &ts->Interval_watchdogs.System_watchdog, + delta_interval + ); + } else { + _ISR_Enable( level ); + } +} + +static void _Timer_server_Stop_tod_system_watchdog( + Timer_server_Control *ts +) +{ + _Watchdog_Remove( &ts->TOD_watchdogs.System_watchdog ); +} + +static void _Timer_server_Reset_tod_system_watchdog( + Timer_server_Control *ts +) +{ + ISR_Level level; + + _Timer_server_Stop_tod_system_watchdog( ts ); + + _ISR_Disable( level ); + if ( !_Chain_Is_empty( &ts->TOD_watchdogs.Chain ) ) { + Watchdog_Interval delta_interval = + _Watchdog_First( &ts->TOD_watchdogs.Chain )->delta_interval; + _ISR_Enable( level ); + + /* + * The unit is SECONDS here. + */ + _Watchdog_Insert_seconds( + &ts->TOD_watchdogs.System_watchdog, + delta_interval + ); + } else { + _ISR_Enable( level ); + } +} + +static void _Timer_server_Insert_timer( + Timer_server_Control *ts, + Timer_Control *timer +) +{ + if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) { + _Watchdog_Insert( &ts->Interval_watchdogs.Chain, &timer->Ticker ); + } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) { + _Watchdog_Insert( &ts->TOD_watchdogs.Chain, &timer->Ticker ); + } +} + +static void _Timer_server_Insert_timer_and_make_snapshot( + Timer_server_Control *ts, + Timer_Control *timer +) +{ + Watchdog_Control *first_watchdog; + Watchdog_Interval delta_interval; + Watchdog_Interval last_snapshot; + Watchdog_Interval snapshot; + Watchdog_Interval delta; + ISR_Level level; + + /* + * We have to update the time snapshots here, because otherwise we may have + * problems with the integer range of the delta values. The time delta DT + * from the last snapshot to now may be arbitrarily long. The last snapshot + * is the reference point for the delta chain. Thus if we do not update the + * reference point we have to add DT to the initial delta of the watchdog + * being inserted. This could result in an integer overflow. + */ + + _Thread_Disable_dispatch(); + + if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) { + /* + * We have to advance the last known ticks value of the server and update + * the watchdog chain accordingly. + */ + _ISR_Disable( level ); + snapshot = _Watchdog_Ticks_since_boot; + last_snapshot = ts->Interval_watchdogs.last_snapshot; + if ( !_Chain_Is_empty( &ts->Interval_watchdogs.Chain ) ) { + first_watchdog = _Watchdog_First( &ts->Interval_watchdogs.Chain ); + + /* + * We assume adequate unsigned arithmetic here. + */ + delta = snapshot - last_snapshot; + + delta_interval = first_watchdog->delta_interval; + if (delta_interval > delta) { + delta_interval -= delta; + } else { + delta_interval = 0; + } + first_watchdog->delta_interval = delta_interval; + } + ts->Interval_watchdogs.last_snapshot = snapshot; + _ISR_Enable( level ); + + _Watchdog_Insert( &ts->Interval_watchdogs.Chain, &timer->Ticker ); + + if ( !ts->active ) { + _Timer_server_Reset_interval_system_watchdog( ts ); + } + } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) { + /* + * We have to advance the last known seconds value of the server and update + * the watchdog chain accordingly. + */ + _ISR_Disable( level ); + snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch(); + last_snapshot = ts->TOD_watchdogs.last_snapshot; + if ( !_Chain_Is_empty( &ts->TOD_watchdogs.Chain ) ) { + first_watchdog = _Watchdog_First( &ts->TOD_watchdogs.Chain ); + delta_interval = first_watchdog->delta_interval; + if ( snapshot > last_snapshot ) { + /* + * We advanced in time. + */ + delta = snapshot - last_snapshot; + if (delta_interval > delta) { + delta_interval -= delta; + } else { + delta_interval = 0; + } + } else { + /* + * Someone put us in the past. + */ + delta = last_snapshot - snapshot; + delta_interval += delta; + } + first_watchdog->delta_interval = delta_interval; + } + ts->TOD_watchdogs.last_snapshot = snapshot; + _ISR_Enable( level ); + + _Watchdog_Insert( &ts->TOD_watchdogs.Chain, &timer->Ticker ); + + if ( !ts->active ) { + _Timer_server_Reset_tod_system_watchdog( ts ); + } + } + + _Thread_Enable_dispatch(); +} + +static void _Timer_server_Schedule_operation_method( + Timer_server_Control *ts, + Timer_Control *timer +) +{ + if ( ts->insert_chain == NULL ) { + _Timer_server_Insert_timer_and_make_snapshot( ts, timer ); + } else { + /* + * We interrupted a critical section of the timer server. The timer + * server is not preemptible, so we must be in interrupt context here. No + * thread dispatch will happen until the timer server finishes its + * critical section. We have to use the protected chain methods because + * we may be interrupted by a higher priority interrupt. + */ + _Chain_Append( ts->insert_chain, &timer->Object.Node ); + } +} + +static void _Timer_server_Process_interval_watchdogs( + Timer_server_Watchdogs *watchdogs, + Chain_Control *fire_chain +) +{ + Watchdog_Interval snapshot = _Watchdog_Ticks_since_boot; + + /* + * We assume adequate unsigned arithmetic here. + */ + Watchdog_Interval delta = snapshot - watchdogs->last_snapshot; + + watchdogs->last_snapshot = snapshot; + + _Watchdog_Adjust_to_chain( &watchdogs->Chain, delta, fire_chain ); +} + +static void _Timer_server_Process_tod_watchdogs( + Timer_server_Watchdogs *watchdogs, + Chain_Control *fire_chain +) +{ + Watchdog_Interval snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch(); + Watchdog_Interval last_snapshot = watchdogs->last_snapshot; + Watchdog_Interval delta; + + /* + * Process the seconds chain. Start by checking that the Time + * of Day (TOD) has not been set backwards. If it has then + * we want to adjust the watchdogs->Chain to indicate this. + */ + if ( snapshot > last_snapshot ) { + /* + * This path is for normal forward movement and cases where the + * TOD has been set forward. + */ + delta = snapshot - last_snapshot; + _Watchdog_Adjust_to_chain( &watchdogs->Chain, delta, fire_chain ); + + } else if ( snapshot < last_snapshot ) { + /* + * The current TOD is before the last TOD which indicates that + * TOD has been set backwards. + */ + delta = last_snapshot - snapshot; + _Watchdog_Adjust( &watchdogs->Chain, WATCHDOG_BACKWARD, delta ); + } + + watchdogs->last_snapshot = snapshot; +} + +static void _Timer_server_Process_insertions( Timer_server_Control *ts ) +{ + while ( true ) { + Timer_Control *timer = (Timer_Control *) _Chain_Get( ts->insert_chain ); + + if ( timer == NULL ) { + break; + } + + _Timer_server_Insert_timer( ts, timer ); + } +} + +static void _Timer_server_Get_watchdogs_that_fire_now( + Timer_server_Control *ts, + Chain_Control *insert_chain, + Chain_Control *fire_chain +) +{ + /* + * Afterwards all timer inserts are directed to this chain and the interval + * and TOD chains will be no more modified by other parties. + */ + ts->insert_chain = insert_chain; + + while ( true ) { + ISR_Level level; + + /* + * Remove all the watchdogs that need to fire so we can invoke them. + */ + _Timer_server_Process_interval_watchdogs( + &ts->Interval_watchdogs, + fire_chain + ); + _Timer_server_Process_tod_watchdogs( &ts->TOD_watchdogs, fire_chain ); + + /* + * The insertions have to take place here, because they reference the + * current time. The previous process methods take a snapshot of the + * current time. In case someone inserts a watchdog with an initial value + * of zero it will be processed in the next iteration of the timer server + * body loop. + */ + _Timer_server_Process_insertions( ts ); + + _ISR_Disable( level ); + if ( _Chain_Is_empty( insert_chain ) ) { + ts->insert_chain = NULL; + _ISR_Enable( level ); + + break; + } else { + _ISR_Enable( level ); + } + } +} + +/** + * @brief Timer server body. + * + * This is the server for task based timers. This task executes whenever a + * task-based timer should fire. It services both "after" and "when" timers. + * It is not created automatically but must be created explicitly by the + * application before task-based timers may be initiated. The parameter + * @a arg points to the corresponding timer server control block. + */ +static rtems_task _Timer_server_Body( + rtems_task_argument arg +) +{ + Timer_server_Control *ts = (Timer_server_Control *) arg; + Chain_Control insert_chain; + Chain_Control fire_chain; + + _Chain_Initialize_empty( &insert_chain ); + _Chain_Initialize_empty( &fire_chain ); + + while ( true ) { + _Timer_server_Get_watchdogs_that_fire_now( ts, &insert_chain, &fire_chain ); + + if ( !_Chain_Is_empty( &fire_chain ) ) { + /* + * Fire the watchdogs. + */ + while ( true ) { + Watchdog_Control *watchdog; + ISR_Level level; + + /* + * It is essential that interrupts are disable here since an interrupt + * service routine may remove a watchdog from the chain. + */ + _ISR_Disable( level ); + watchdog = (Watchdog_Control *) _Chain_Get_unprotected( &fire_chain ); + if ( watchdog != NULL ) { + watchdog->state = WATCHDOG_INACTIVE; + _ISR_Enable( level ); + } else { + _ISR_Enable( level ); + + break; + } + + /* + * The timer server may block here and wait for resources or time. + * The system watchdogs are inactive and will remain inactive since + * the active flag of the timer server is true. + */ + (*watchdog->routine)( watchdog->id, watchdog->user_data ); + } + } else { + ts->active = false; + + /* + * Block until there is something to do. + */ + _Thread_Disable_dispatch(); + _Thread_Set_state( ts->thread, STATES_DELAYING ); + _Timer_server_Reset_interval_system_watchdog( ts ); + _Timer_server_Reset_tod_system_watchdog( ts ); + _Thread_Enable_dispatch(); + + ts->active = true; + + /* + * Maybe an interrupt did reset the system timers, so we have to stop + * them here. Since we are active now, there will be no more resets + * until we are inactive again. + */ + _Timer_server_Stop_interval_system_watchdog( ts ); + _Timer_server_Stop_tod_system_watchdog( ts ); + } + } +} + +/** + * @brief rtems_timer_initiate_server + * + * This directive creates and starts the server for task-based timers. + * It must be invoked before any task-based timers can be initiated. + * + * @param[in] priority is the timer server priority + * @param[in] stack_size is the stack size in bytes + * @param[in] attribute_set is the timer server attributes + * + * @return This method returns RTEMS_SUCCESSFUL if successful and an + * error code otherwise. + */ +rtems_status_code rtems_timer_initiate_server( + uint32_t priority, + uint32_t stack_size, + rtems_attribute attribute_set +) +{ + rtems_id id; + rtems_status_code status; + rtems_task_priority _priority; + static bool initialized = false; + bool tmpInitialized; + Timer_server_Control *ts = &_Timer_server_Default; + + /* + * Make sure the requested priority is valid. The if is + * structured so we check it is invalid before looking for + * a specific invalid value as the default. + */ + _priority = priority; + if ( !_RTEMS_tasks_Priority_is_valid( priority ) ) { + if ( priority != RTEMS_TIMER_SERVER_DEFAULT_PRIORITY ) + return RTEMS_INVALID_PRIORITY; + _priority = 0; + } + + /* + * Just to make sure this is only called once. + */ + _Thread_Disable_dispatch(); + tmpInitialized = initialized; + initialized = true; + _Thread_Enable_dispatch(); + + if ( tmpInitialized ) + return RTEMS_INCORRECT_STATE; + + /* + * Create the Timer Server with the name the name of "TIME". The attribute + * RTEMS_SYSTEM_TASK allows us to set a priority to 0 which will makes it + * higher than any other task in the system. It can be viewed as a low + * priority interrupt. It is also always NO_PREEMPT so it looks like + * an interrupt to other tasks. + * + * We allow the user to override the default priority because the Timer + * Server can invoke TSRs which must adhere to language run-time or + * other library rules. For example, if using a TSR written in Ada the + * Server should run at the same priority as the priority Ada task. + * Otherwise, the priority ceiling for the mutex used to protect the + * GNAT run-time is violated. + */ + status = rtems_task_create( + _Objects_Build_name('T','I','M','E'), /* "TIME" */ + _priority, /* create with priority 1 since 0 is illegal */ + stack_size, /* let user specify stack size */ + RTEMS_NO_PREEMPT, /* no preempt is like an interrupt */ + /* user may want floating point but we need */ + /* system task specified for 0 priority */ + attribute_set | RTEMS_SYSTEM_TASK, + &id /* get the id back */ + ); + if (status) { + initialized = false; + return status; + } + + /* + * Do all the data structure initialization before starting the + * Timer Server so we do not have to have a critical section. + */ + + /* + * We work with the TCB pointer, not the ID, so we need to convert + * to a TCB pointer from here out. + */ + ts->thread = (Thread_Control *)_Objects_Get_local_object( + &_RTEMS_tasks_Information, + _Objects_Get_index(id) + ); + + /* + * Initialize the timer lists that the server will manage. + */ + _Chain_Initialize_empty( &ts->Interval_watchdogs.Chain ); + _Chain_Initialize_empty( &ts->TOD_watchdogs.Chain ); + + /* + * Initialize the timers that will be used to control when the + * Timer Server wakes up and services the task-based timers. + */ + _Watchdog_Initialize( + &ts->Interval_watchdogs.System_watchdog, + _Thread_Delay_ended, + id, + NULL + ); + _Watchdog_Initialize( + &ts->TOD_watchdogs.System_watchdog, + _Thread_Delay_ended, + id, + NULL + ); + + /* + * Initialize the pointer to the timer schedule method so applications that + * do not use the Timer Server do not have to pull it in. + */ + ts->schedule_operation = _Timer_server_Schedule_operation_method; + + ts->Interval_watchdogs.last_snapshot = _Watchdog_Ticks_since_boot; + ts->TOD_watchdogs.last_snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch(); + + ts->insert_chain = NULL; + ts->active = false; + + /* + * The default timer server is now available. + */ + _Timer_server = ts; + + /* + * Start the timer server + */ + status = rtems_task_start( + id, + _Timer_server_Body, + (rtems_task_argument) ts + ); + + #if defined(RTEMS_DEBUG) + /* + * One would expect a call to rtems_task_delete() here to clean up + * but there is actually no way (in normal circumstances) that the + * start can fail. The id and starting address are known to be + * be good. If this service fails, something is weirdly wrong on the + * target such as a stray write in an ISR or incorrect memory layout. + */ + if (status) { + initialized = false; + } + #endif + + return status; +} diff --git a/cpukit/rtems/src/timerserverfireafter.c b/cpukit/rtems/src/timerserverfireafter.c new file mode 100644 index 0000000000..a0af568865 --- /dev/null +++ b/cpukit/rtems/src/timerserverfireafter.c @@ -0,0 +1,109 @@ +/* + * Timer Manager - rtems_timer_server fire_after directive + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_timer_server_fire_after + * + * This directive allows a thread to start a timer which will by + * executed by the Timer Server when it fires. + * + * Input parameters: + * id - timer id + * ticks - interval until routine is fired + * routine - routine to schedule + * user_data - passed as argument to routine when it is fired + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_server_fire_after( + rtems_id id, + rtems_interval ticks, + rtems_timer_service_routine_entry routine, + void *user_data +) +{ + Timer_Control *the_timer; + Objects_Locations location; + ISR_Level level; + Timer_server_Control *timer_server = _Timer_server; + + if ( !timer_server ) + return RTEMS_INCORRECT_STATE; + + if ( !routine ) + return RTEMS_INVALID_ADDRESS; + + if ( ticks == 0 ) + return RTEMS_INVALID_NUMBER; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + (void) _Watchdog_Remove( &the_timer->Ticker ); + + _ISR_Disable( level ); + + /* + * Check to see if the watchdog has just been inserted by a + * higher priority interrupt. If so, abandon this insert. + */ + + if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) { + _ISR_Enable( level ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + /* + * OK. Now we now the timer was not rescheduled by an interrupt + * so we can atomically initialize it as in use. + */ + + the_timer->the_class = TIMER_INTERVAL_ON_TASK; + _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); + the_timer->Ticker.initial = ticks; + _ISR_Enable( level ); + + (*timer_server->schedule_operation)( timer_server, the_timer ); + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/timerserverfirewhen.c b/cpukit/rtems/src/timerserverfirewhen.c new file mode 100644 index 0000000000..d5e6c472a1 --- /dev/null +++ b/cpukit/rtems/src/timerserverfirewhen.c @@ -0,0 +1,96 @@ +/* + * Timer Manager - rtems_timer_server fire_when directive + * + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/tod.h> +#include <rtems/score/watchdog.h> + +/*PAGE + * + * rtems_timer_server_fire_when + * + * This directive allows a thread to start a timer which will by + * executed by the Timer Server when it fires. + * + * Input parameters: + * id - timer id + * wall_time - time of day to fire timer + * routine - routine to schedule + * user_data - passed as argument to routine when it is fired + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_server_fire_when( + rtems_id id, + rtems_time_of_day *wall_time, + rtems_timer_service_routine_entry routine, + void *user_data +) +{ + Timer_Control *the_timer; + Objects_Locations location; + rtems_interval seconds; + Timer_server_Control *timer_server = _Timer_server; + + if ( !timer_server ) + return RTEMS_INCORRECT_STATE; + + if ( !_TOD_Is_set ) + return RTEMS_NOT_DEFINED; + + if ( !routine ) + return RTEMS_INVALID_ADDRESS; + + if ( !_TOD_Validate( wall_time ) ) + return RTEMS_INVALID_CLOCK; + + seconds = _TOD_To_seconds( wall_time ); + if ( seconds <= _TOD_Seconds_since_epoch() ) + return RTEMS_INVALID_CLOCK; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + (void) _Watchdog_Remove( &the_timer->Ticker ); + the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK; + _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); + the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch(); + + (*timer_server->schedule_operation)( timer_server, the_timer ); + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/rtems/src/workspace.c b/cpukit/rtems/src/workspace.c new file mode 100644 index 0000000000..e6394aca86 --- /dev/null +++ b/cpukit/rtems/src/workspace.c @@ -0,0 +1,75 @@ +/* + * Workspace Handler + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/wkspace.h> +#include <rtems/score/protectedheap.h> +#include <rtems/score/interr.h> +#include <rtems/config.h> + +#include <string.h> /* for memset */ + +bool rtems_workspace_get_information( + Heap_Information_block *the_info +) +{ + if ( !the_info ) + return false; + + return _Protected_heap_Get_information( &_Workspace_Area, the_info ); +} + +/* + * _Workspace_Allocate + */ +bool rtems_workspace_allocate( + uintptr_t bytes, + void **pointer +) +{ + void *ptr; + + /* + * check the arguments + */ + if ( !pointer ) + return false; + + if ( !bytes ) + return false; + + /* + * Allocate the memory + */ + ptr = _Protected_heap_Allocate( &_Workspace_Area, (intptr_t) bytes ); + if (!ptr) + return false; + + *pointer = ptr; + return true; +} + +/* + * _Workspace_Allocate + */ +bool rtems_workspace_free( + void *pointer +) +{ + return _Protected_heap_Free( &_Workspace_Area, pointer ); +} + |