summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1995-09-19 14:53:29 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1995-09-19 14:53:29 +0000
commit3652ad356bf13abe0963c992cbbda96476d31609 (patch)
tree8ae01f1eec49c8fabc0a3db3d5b58b29a61428f2 /cpukit/score
parentInitial attempt at building HP PA-RISC using Solaris hosted tools. (diff)
downloadrtems-3652ad356bf13abe0963c992cbbda96476d31609.tar.bz2
Minor bug fixes to get all targets compilable and running. The
single biggest changes were the expansion of the workspace size macro to include other types of objects and the increase in the minimum stack size for most CPUs.
Diffstat (limited to 'cpukit/score')
-rw-r--r--cpukit/score/cpu/hppa1.1/cpu.c9
-rw-r--r--cpukit/score/cpu/i386/cpu.c4
-rw-r--r--cpukit/score/cpu/unix/cpu.c85
-rw-r--r--cpukit/score/include/rtems/score/coremsg.h408
-rw-r--r--cpukit/score/inline/rtems/score/coremsg.inl186
-rw-r--r--cpukit/score/macros/rtems/score/coremsg.inl121
-rw-r--r--cpukit/score/src/coremsg.c436
7 files changed, 1215 insertions, 34 deletions
diff --git a/cpukit/score/cpu/hppa1.1/cpu.c b/cpukit/score/cpu/hppa1.1/cpu.c
index 6dee0c1225..ba70357a33 100644
--- a/cpukit/score/cpu/hppa1.1/cpu.c
+++ b/cpukit/score/cpu/hppa1.1/cpu.c
@@ -193,7 +193,7 @@ void _CPU_ISR_install_vector(
void
hppa_external_interrupt_initialize(void)
{
- hppa_rtems_isr_entry ignore;
+ hppa_rtems_isr_entry ignore = 0;
/* mark them all unused */
@@ -201,8 +201,11 @@ hppa_external_interrupt_initialize(void)
DISMISS(~0);
/* install the external interrupt handler */
- rtems_interrupt_catch((rtems_isr_entry) hppa_external_interrupt,
- HPPA_INTERRUPT_EXTERNAL_INTERRUPT, &ignore) ;
+ _CPU_ISR_install_vector(
+ HPPA_INTERRUPT_EXTERNAL_INTERRUPT,
+ (proc_ptr)hppa_external_interrupt,
+ (proc_ptr *)ignore
+ );
}
/*
diff --git a/cpukit/score/cpu/i386/cpu.c b/cpukit/score/cpu/i386/cpu.c
index 446515d6f9..73108e66d1 100644
--- a/cpukit/score/cpu/i386/cpu.c
+++ b/cpukit/score/cpu/i386/cpu.c
@@ -34,7 +34,7 @@ void _CPU_Initialize(
)
{
register unsigned16 fp_status asm ("ax");
- register unsigned8 *fp_context;
+ register void *fp_context;
_CPU_Table = *cpu_table;
@@ -56,7 +56,7 @@ void _CPU_Initialize(
if ( fp_status == 0 ) {
- fp_context = _CPU_Null_fp_context;
+ fp_context = &_CPU_Null_fp_context;
asm volatile( "fsave (%0)" : "=r" (fp_context)
: "0" (fp_context)
diff --git a/cpukit/score/cpu/unix/cpu.c b/cpukit/score/cpu/unix/cpu.c
index 339bb2a3ce..a1994da5ae 100644
--- a/cpukit/score/cpu/unix/cpu.c
+++ b/cpukit/score/cpu/unix/cpu.c
@@ -1,5 +1,5 @@
/*
- * HP PA-RISC CPU Dependent Source
+ * UNIX Simulator Dependent Source
*
*
* To anyone who acknowledges that this file is provided "AS IS"
@@ -18,6 +18,7 @@
#include <rtems/system.h>
#include <rtems/core/isr.h>
+#include <rtems/core/interr.h>
#include <stdio.h>
#include <stdlib.h>
@@ -169,21 +170,16 @@ void _CPU_Context_From_CPU_Init()
*/
_CPU_ISR_Set_level( 0 );
- setjmp( _CPU_Context_Default_with_ISRs_enabled.regs );
- sigprocmask(
- SIG_SETMASK, /* ignored when second arg is NULL */
- 0,
- &_CPU_Context_Default_with_ISRs_enabled.isr_level
+ _CPU_Context_switch(
+ &_CPU_Context_Default_with_ISRs_enabled,
+ &_CPU_Context_Default_with_ISRs_enabled
);
_CPU_ISR_Set_level( 1 );
- setjmp( _CPU_Context_Default_with_ISRs_disabled.regs );
- sigprocmask(
- SIG_SETMASK, /* ignored when second arg is NULL */
- 0,
- &_CPU_Context_Default_with_ISRs_disabled.isr_level
+ _CPU_Context_switch(
+ &_CPU_Context_Default_with_ISRs_disabled,
+ &_CPU_Context_Default_with_ISRs_disabled
);
-
}
/*PAGE
@@ -191,21 +187,21 @@ void _CPU_Context_From_CPU_Init()
* _CPU_ISR_Get_level
*/
+sigset_t GET_old_mask;
+
unsigned32 _CPU_ISR_Get_level( void )
{
- sigset_t sigset;
+/* sigset_t old_mask; */
+ unsigned32 old_level;
- sigprocmask( 0, 0, &sigset );
-
- /*
- * This is an educated guess based on ONLY ONE of the signals we
- * disable/enable to mask ISRs.
- */
+ sigprocmask(0, 0, &GET_old_mask);
+
+ if (memcmp((void *)&posix_empty_mask, (void *)&GET_old_mask, sizeof(sigset_t)))
+ old_level = 1;
+ else
+ old_level = 0;
- if ( sigismember( &sigset, SIGUSR1 ) )
- return 1;
- else
- return 0;
+ return old_level;
}
/* _CPU_Initialize
@@ -383,7 +379,7 @@ void _CPU_Context_Initialize(
else
source = _CPU_Context_Default_with_ISRs_disabled.regs;
- memcpy(_the_context, source, sizeof(jmp_buf));
+ memcpy(_the_context, source, sizeof(Context_Control) ); /* sizeof(jmp_buf)); */
addr = (unsigned32 *)_the_context;
@@ -470,15 +466,30 @@ void _CPU_Context_switch(
Context_Control *next
)
{
+ int status;
+
/*
* Switch levels in one operation
*/
- sigprocmask( SIG_SETMASK, &next->isr_level, &current->isr_level );
+ status = sigprocmask( SIG_SETMASK, &next->isr_level, &current->isr_level );
+ if ( status )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ status
+ );
if (setjmp(current->regs) == 0) { /* Save the current context */
longjmp(next->regs, 0); /* Switch to the new context */
+ if ( status )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ status
+ );
}
+
}
/*PAGE
@@ -510,11 +521,18 @@ void _CPU_Restore_float_context(
unsigned32 _CPU_ISR_Disable_support(void)
{
+ int status;
sigset_t old_mask;
- sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, &old_mask);
+ status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, &old_mask);
+ if ( status )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ status
+ );
- if (memcmp((void *)&posix_empty_mask, (void *)&old_mask, sizeof(sigset_t)) != 0)
+ if (memcmp((void *)&posix_empty_mask, (void *)&old_mask, sizeof(sigset_t)))
return 1;
return 0;
@@ -529,10 +547,19 @@ void _CPU_ISR_Enable(
unsigned32 level
)
{
+ int status;
+
if (level == 0)
- sigprocmask(SIG_UNBLOCK, &_CPU_Signal_mask, 0);
+ status = sigprocmask(SIG_UNBLOCK, &_CPU_Signal_mask, 0);
else
- sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0);
+ status = sigprocmask(SIG_BLOCK, &_CPU_Signal_mask, 0);
+
+ if ( status )
+ _Internal_error_Occurred(
+ INTERNAL_ERROR_CORE,
+ TRUE,
+ status
+ );
}
/*PAGE
diff --git a/cpukit/score/include/rtems/score/coremsg.h b/cpukit/score/include/rtems/score/coremsg.h
new file mode 100644
index 0000000000..109d792c78
--- /dev/null
+++ b/cpukit/score/include/rtems/score/coremsg.h
@@ -0,0 +1,408 @@
+/* coremsg.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Message queue Handler.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#ifndef __RTEMS_CORE_MESSAGE_QUEUE_h
+#define __RTEMS_CORE_MESSAGE_QUEUE_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/core/thread.h>
+#include <rtems/core/threadq.h>
+#include <rtems/core/priority.h>
+#include <rtems/core/watchdog.h>
+
+/*
+ * The following type defines the callout which the API provides
+ * to support global/multiprocessor operations on message_queues.
+ */
+
+typedef void ( *CORE_message_queue_API_mp_support_callout )(
+ Thread_Control *,
+ Objects_Id
+ );
+
+/*
+ * The following defines the data types needed to manipulate
+ * the contents of message buffers.
+ * Since msgs are variable length we just make a ptr to 1.
+ */
+
+typedef struct {
+ unsigned32 size;
+
+#ifndef __cplusplus
+ /* NOTE: [0] is gcc specific,
+ * but specifically disallowed by ANSI STD C++
+ * g++ warns about it, so we #ifdef it out to
+ * get rid of warnings when compiled by g++.
+ */
+ unsigned32 buffer[0];
+#endif
+
+} CORE_message_queue_Buffer;
+
+/*
+ * The following records define the organization of a message
+ * buffer.
+ */
+
+typedef struct {
+ Chain_Node Node;
+ CORE_message_queue_Buffer Contents;
+} CORE_message_queue_Buffer_control;
+
+/*
+ * Blocking disciplines for a message_queue.
+ */
+
+typedef enum {
+ CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO,
+ CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY
+} CORE_message_queue_Disciplines;
+
+/*
+ * 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 {
+ CORE_MESSAGE_QUEUE_SEND_REQUEST = 0,
+ CORE_MESSAGE_QUEUE_URGENT_REQUEST = 1
+} CORE_message_queue_Submit_types;
+
+/*
+ * Core Message queue handler return statuses.
+ */
+
+typedef enum {
+ CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL,
+ CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE,
+ CORE_MESSAGE_QUEUE_STATUS_TOO_MANY,
+ CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED,
+ CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT,
+ CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED,
+ CORE_MESSAGE_QUEUE_STATUS_TIMEOUT
+} CORE_message_queue_Status;
+
+/*
+ * The following defines the control block used to manage the
+ * attributes of each message queue.
+ */
+
+typedef struct {
+ CORE_message_queue_Disciplines discipline;
+} CORE_message_queue_Attributes;
+
+/*
+ * The following defines the control block used to manage each
+ * counting message_queue.
+ */
+
+typedef struct {
+ Thread_queue_Control Wait_queue;
+ CORE_message_queue_Attributes Attributes;
+ unsigned32 maximum_pending_messages;
+ unsigned32 number_of_pending_messages;
+ unsigned32 maximum_message_size;
+ Chain_Control Pending_messages;
+ CORE_message_queue_Buffer *message_buffers;
+ Chain_Control Inactive_messages;
+} CORE_message_queue_Control;
+
+/*
+ * _CORE_message_queue_Initialize
+ *
+ * DESCRIPTION:
+ *
+ * This routine initializes the message_queue based on the parameters passed.
+ */
+
+boolean _CORE_message_queue_Initialize(
+ CORE_message_queue_Control *the_message_queue,
+ Objects_Classes the_class,
+ CORE_message_queue_Attributes *the_message_queue_attributes,
+ unsigned32 maximum_pending_messages,
+ unsigned32 maximum_message_size,
+ Thread_queue_Extract_callout proxy_extract_callout
+);
+
+/*
+ * _CORE_message_queue_Close
+ *
+ * DESCRIPTION:
+ *
+ * This function closes a message by returning all allocated space and
+ * flushing the message_queue's task wait queue.
+ */
+
+void _CORE_message_queue_Close(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_queue_Flush_callout remote_extract_callout,
+ unsigned32 status
+);
+
+/*
+ *
+ * _CORE_message_queue_Flush
+ *
+ * DESCRIPTION:
+ *
+ * This function flushes the message_queue's task wait queue. The number
+ * messages flushed from the queue is returned.
+ *
+ */
+
+unsigned32 _CORE_message_queue_Flush(
+ CORE_message_queue_Control *the_message_queue
+);
+
+/*
+ * _CORE_message_queue_Flush_support
+ *
+ * DESCRIPTION:
+ *
+ * This routine flushes all outstanding messages and returns
+ * them to the inactive message chain.
+ */
+
+unsigned32 _CORE_message_queue_Flush_support(
+ CORE_message_queue_Control *the_message_queue
+);
+
+/*
+ * _CORE_message_queue_send
+ *
+ * DESCRIPTION:
+ *
+ * This routine sends a message to the end of the specified message queue.
+ *
+ */
+
+STATIC INLINE CORE_message_queue_Status _CORE_message_queue_Send(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ unsigned32 size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support
+);
+
+/*
+ *
+ * _CORE_message_queue_Urgent
+ *
+ * DESCRIPTION:
+ *
+ * This routine sends a message to the front of the specified message queue.
+ *
+ */
+
+STATIC INLINE CORE_message_queue_Status _CORE_message_queue_Urgent(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ unsigned32 size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support
+);
+
+/*
+ *
+ * _CORE_message_queue_Broadcast
+ *
+ * DESCRIPTION:
+ *
+ * This function sends a message for every thread waiting on the queue and
+ * returns the number of threads made ready by the message.
+ *
+ */
+
+CORE_message_queue_Status _CORE_message_queue_Broadcast(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ unsigned32 size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
+ unsigned32 *count
+);
+
+/*
+ *
+ * _CORE_message_queue_Submit
+ *
+ * DESCRIPTION:
+ *
+ * This routine implements the send and urgent message functions. It
+ * processes a message that is to be submitted to the designated
+ * message queue. The message will either be processed as a
+ * 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.
+ *
+ */
+
+CORE_message_queue_Status _CORE_message_queue_Submit(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ unsigned32 size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
+ CORE_message_queue_Submit_types submit_type
+);
+
+/*
+ *
+ * _CORE_message_queue_Seize
+ *
+ * DESCRIPTION:
+ *
+ * This kernel routine dequeues a message, copies the message buffer to
+ * a given destination buffer, and frees the message buffer to the
+ * inactive message pool. The thread will be blocked if wait is TRUE,
+ * otherwise an error will be given to the thread if no messages are available.
+ *
+ */
+
+void _CORE_message_queue_Seize(
+ CORE_message_queue_Control *the_message_queue,
+ Objects_Id id,
+ void *buffer,
+ unsigned32 *size,
+ boolean wait,
+ Watchdog_Interval timeout
+);
+
+/*
+ * _CORE_message_queue_Allocate_message_buffer
+ *
+ * DESCRIPTION:
+ *
+ * This function allocates a message buffer from the inactive
+ * message buffer chain.
+ */
+
+STATIC INLINE CORE_message_queue_Buffer_control *
+ _CORE_message_queue_Allocate_message_buffer (
+ CORE_message_queue_Control *the_message_queue
+);
+
+/*
+ * _CORE_message_queue_Free_message_buffer
+ *
+ * DESCRIPTION:
+ *
+ * This routine frees a message buffer to the inactive
+ * message buffer chain.
+ */
+
+STATIC INLINE void _CORE_message_queue_Free_message_buffer (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message
+);
+
+/*
+ * _CORE_message_queue_Copy_buffer
+ *
+ * DESCRIPTION:
+ *
+ * This routine copies the contents of the source message buffer
+ * to the destination message buffer.
+ */
+
+STATIC INLINE void _CORE_message_queue_Copy_buffer (
+ void *source,
+ void *destination,
+ unsigned32 size
+);
+
+/*
+ * _CORE_message_queue_Get_pending_message
+ *
+ * DESCRIPTION:
+ *
+ * This function removes the first message from the_message_queue
+ * and returns a pointer to it.
+ */
+
+STATIC INLINE
+ CORE_message_queue_Buffer_control *_CORE_message_queue_Get_pending_message (
+ CORE_message_queue_Control *the_message_queue
+);
+
+/*
+ * _CORE_message_queue_Is_priority
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the priority attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+
+STATIC INLINE boolean _CORE_message_queue_Is_priority(
+ CORE_message_queue_Attributes *the_attribute
+);
+
+/*
+ * _CORE_message_queue_Append
+ *
+ * DESCRIPTION:
+ *
+ * This routine places the_message at the rear of the outstanding
+ * messages on the_message_queue.
+ */
+
+STATIC INLINE void _CORE_message_queue_Append (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message
+);
+
+/*
+ * _CORE_message_queue_Prepend
+ *
+ * DESCRIPTION:
+ *
+ * This routine places the_message at the rear of the outstanding
+ * messages on the_message_queue.
+ */
+
+STATIC INLINE void _CORE_message_queue_Prepend (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message
+);
+
+/*
+ * _CORE_message_queue_Is_null
+ *
+ * DESCRIPTION:
+ *
+ * This function places the_message at the rear of the outstanding
+ * messages on the_message_queue.
+ */
+
+STATIC INLINE boolean _CORE_message_queue_Is_null (
+ CORE_message_queue_Control *the_message_queue
+);
+
+#include <rtems/core/coremsg.inl>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/score/inline/rtems/score/coremsg.inl b/cpukit/score/inline/rtems/score/coremsg.inl
new file mode 100644
index 0000000000..d1b5429947
--- /dev/null
+++ b/cpukit/score/inline/rtems/score/coremsg.inl
@@ -0,0 +1,186 @@
+/* coremsg.inl
+ *
+ * This include file contains the static inline implementation of all
+ * inlined routines in the Core Message Handler.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#ifndef __CORE_MESSAGE_QUEUE_inl
+#define __CORE_MESSAGE_QUEUE_inl
+
+/*PAGE
+ *
+ * _CORE_message_queue_Send
+ *
+ */
+
+STATIC INLINE CORE_message_queue_Status _CORE_message_queue_Send(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ unsigned32 size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support
+)
+{
+ return _CORE_message_queue_Submit(
+ the_message_queue,
+ buffer,
+ size,
+ id,
+ api_message_queue_mp_support,
+ CORE_MESSAGE_QUEUE_SEND_REQUEST
+ );
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Urgent
+ *
+ */
+
+STATIC INLINE CORE_message_queue_Status _CORE_message_queue_Urgent(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ unsigned32 size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support
+)
+{
+ return _CORE_message_queue_Submit(
+ the_message_queue,
+ buffer,
+ size,
+ id,
+ api_message_queue_mp_support,
+ CORE_MESSAGE_QUEUE_URGENT_REQUEST
+ );
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Copy_buffer
+ *
+ */
+
+STATIC INLINE void _CORE_message_queue_Copy_buffer (
+ void *source,
+ void *destination,
+ unsigned32 size
+)
+{
+ memcpy(destination, source, size);
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Allocate_message_buffer
+ *
+ */
+
+STATIC INLINE CORE_message_queue_Buffer_control *
+_CORE_message_queue_Allocate_message_buffer (
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ return (CORE_message_queue_Buffer_control *)
+ _Chain_Get( &the_message_queue->Inactive_messages );
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Free_message_buffer
+ *
+ */
+
+STATIC INLINE void _CORE_message_queue_Free_message_buffer (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message
+)
+{
+ _Chain_Append( &the_message_queue->Inactive_messages, &the_message->Node );
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Get_pending_message
+ *
+ */
+
+STATIC INLINE
+ CORE_message_queue_Buffer_control *_CORE_message_queue_Get_pending_message (
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ return (CORE_message_queue_Buffer_control *)
+ _Chain_Get_unprotected( &the_message_queue->Pending_messages );
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Is_priority
+ *
+ */
+
+STATIC INLINE boolean _CORE_message_queue_Is_priority(
+ CORE_message_queue_Attributes *the_attribute
+)
+{
+ return (the_attribute->discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY);
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Append
+ *
+ */
+
+STATIC INLINE void _CORE_message_queue_Append (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message
+)
+{
+ _Chain_Append( &the_message_queue->Pending_messages, &the_message->Node );
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Prepend
+ *
+ */
+
+STATIC INLINE void _CORE_message_queue_Prepend (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message
+)
+{
+ _Chain_Prepend(
+ &the_message_queue->Pending_messages,
+ &the_message->Node
+ );
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Is_null
+ *
+ */
+
+STATIC INLINE boolean _CORE_message_queue_Is_null (
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ return ( the_message_queue == NULL );
+}
+
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/macros/rtems/score/coremsg.inl b/cpukit/score/macros/rtems/score/coremsg.inl
new file mode 100644
index 0000000000..877d737afd
--- /dev/null
+++ b/cpukit/score/macros/rtems/score/coremsg.inl
@@ -0,0 +1,121 @@
+/* coremsg.inl
+ *
+ * This include file contains the macro implementation of all
+ * inlined routines in the Core Message Handler.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#ifndef __CORE_MESSAGE_QUEUE_inl
+#define __CORE_MESSAGE_QUEUE_inl
+
+/*PAGE
+ *
+ * _CORE_message_queue_Send
+ *
+ */
+
+#define _CORE_message_queue_Send( _the_message_queue, _buffer, _size, \
+_id, _api_message_queue_mp_support ) \
+ _CORE_message_queue_Submit( (_the_message_queue), (_buffer), (_size), \
+ (_id), (_api_message_queue_mp_support), CORE_MESSAGE_QUEUE_SEND_REQUEST )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Urgent
+ *
+ */
+
+#define _CORE_message_queue_Urgent( _the_message_queue, _buffer, _size, \
+_id, _api_message_queue_mp_support ) \
+ _CORE_message_queue_Submit( (_the_message_queue), (_buffer), (_size), \
+ (_id), (_api_message_queue_mp_support), CORE_MESSAGE_QUEUE_URGENT_REQUEST )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Copy_buffer
+ */
+
+#define _CORE_message_queue_Copy_buffer( _source, _destination, _size ) \
+ memcpy( _destination, _source, _size)
+
+/*PAGE
+ *
+ * _CORE_message_queue_Allocate_message_buffer
+ *
+ */
+
+#define _CORE_message_queue_Allocate_message_buffer( _the_message_queue ) \
+ (CORE_message_queue_Buffer_control *) \
+ _Chain_Get( &(_the_message_queue)->Inactive_messages )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Free_message_buffer
+ *
+ */
+
+#define _CORE_message_queue_Free_message_buffer( _the_message_queue, _the_message ) \
+ _Chain_Append( \
+ &(_the_message_queue)->Inactive_messages, \
+ &(_the_message)->Node \
+ )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Is_priority
+ *
+ */
+
+#define _CORE_message_queue_Is_priority( _the_attribute ) \
+ ((_the_attribute)->discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY)
+
+/*PAGE
+ *
+ * _CORE_message_queue_Get_pending_message
+ *
+ */
+
+#define _CORE_message_queue_Get_pending_message( _the_message_queue ) \
+ (CORE_message_queue_Buffer_control *) \
+ _Chain_Get_unprotected( &(_the_message_queue)->Pending_messages )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Append
+ *
+ */
+
+#define _CORE_message_queue_Append( _the_message_queue, _the_message ) \
+ _Chain_Append( &(_the_message_queue)->Pending_messages, \
+ &(_the_message)->Node )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Prepend
+ *
+ */
+
+#define _CORE_message_queue_Prepend( _the_message_queue, _the_message ) \
+ _Chain_Prepend( &(_the_message_queue)->Pending_messages, \
+ &(_the_message)->Node )
+
+/*PAGE
+ *
+ * _CORE_message_queue_Is_null
+ *
+ */
+
+#define _CORE_message_queue_Is_null( _the_message_queue ) \
+ ( (_the_message_queue) == NULL )
+
+#endif
+/* end of include file */
diff --git a/cpukit/score/src/coremsg.c b/cpukit/score/src/coremsg.c
new file mode 100644
index 0000000000..2ce0587b5f
--- /dev/null
+++ b/cpukit/score/src/coremsg.c
@@ -0,0 +1,436 @@
+/*
+ * CORE Message Queue Handler
+ *
+ * DESCRIPTION:
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems/system.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/core/chain.h>
+#include <rtems/core/isr.h>
+#include <rtems/rtems/message.h>
+#include <rtems/core/object.h>
+#include <rtems/rtems/options.h>
+#include <rtems/core/states.h>
+#include <rtems/rtems/support.h>
+#include <rtems/core/thread.h>
+#include <rtems/core/wkspace.h>
+#include <rtems/core/mpci.h>
+#include <rtems/sysstate.h>
+
+/*PAGE
+ *
+ * _CORE_message_queue_Initialize
+ *
+ * This routine initializes a newly created message queue based on the
+ * specified data.
+ *
+ * Input parameters:
+ * the_message_queue - the message queue to initialize
+ * the_class - the API specific object class
+ * the_message_queue_attributes - the message queue's attributes
+ * maximum_pending_messages - maximum message and reserved buffer count
+ * maximum_message_size - maximum size of each message
+ * proxy_extract_callout - remote extract support
+ *
+ * Output parameters:
+ * TRUE - if the message queue is initialized
+ * FALSE - if the message queue is NOT initialized
+ */
+
+boolean _CORE_message_queue_Initialize(
+ CORE_message_queue_Control *the_message_queue,
+ Objects_Classes the_class,
+ CORE_message_queue_Attributes *the_message_queue_attributes,
+ unsigned32 maximum_pending_messages,
+ unsigned32 maximum_message_size,
+ Thread_queue_Extract_callout proxy_extract_callout
+)
+{
+ unsigned32 message_buffering_required;
+ unsigned32 allocated_message_size;
+
+ the_message_queue->maximum_pending_messages = maximum_pending_messages;
+ the_message_queue->number_of_pending_messages = 0;
+ the_message_queue->maximum_message_size = maximum_message_size;
+
+ /*
+ * round size up to multiple of a ptr for chain init
+ */
+
+ allocated_message_size = maximum_message_size;
+ if (allocated_message_size & (sizeof(unsigned32) - 1)) {
+ allocated_message_size += sizeof(unsigned32);
+ allocated_message_size &= ~(sizeof(unsigned32) - 1);
+ }
+
+ message_buffering_required = maximum_pending_messages *
+ (allocated_message_size + sizeof(CORE_message_queue_Buffer_control));
+
+ the_message_queue->message_buffers = (CORE_message_queue_Buffer *)
+ _Workspace_Allocate( message_buffering_required );
+
+ if (the_message_queue->message_buffers == 0)
+ return FALSE;
+
+ _Chain_Initialize (
+ &the_message_queue->Inactive_messages,
+ the_message_queue->message_buffers,
+ maximum_pending_messages,
+ allocated_message_size + sizeof( CORE_message_queue_Buffer_control )
+ );
+
+ _Chain_Initialize_empty( &the_message_queue->Pending_messages );
+
+ _Thread_queue_Initialize(
+ &the_message_queue->Wait_queue,
+ the_class,
+ _CORE_message_queue_Is_priority( the_message_queue_attributes ) ?
+ THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
+ STATES_WAITING_FOR_MESSAGE,
+ proxy_extract_callout,
+ CORE_MESSAGE_QUEUE_STATUS_TIMEOUT
+ );
+
+ return TRUE;
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Close
+ *
+ * This function closes a message by returning all allocated space and
+ * flushing the message_queue's task wait queue.
+ *
+ * Input parameters:
+ * the_message_queue - the message_queue to be flushed
+ * remote_extract_callout - function to invoke remotely
+ * status - status to pass to thread
+ *
+ * Output parameters: NONE
+ */
+
+void _CORE_message_queue_Close(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_queue_Flush_callout remote_extract_callout,
+ unsigned32 status
+)
+{
+
+ if ( the_message_queue->number_of_pending_messages != 0 )
+ (void) _CORE_message_queue_Flush_support( the_message_queue );
+ else
+ _Thread_queue_Flush(
+ &the_message_queue->Wait_queue,
+ remote_extract_callout,
+ status
+ );
+
+ (void) _Workspace_Free( the_message_queue->message_buffers );
+
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Flush
+ *
+ * This function flushes the message_queue's task wait queue. The number
+ * of messages flushed from the queue is returned.
+ *
+ * Input parameters:
+ * the_message_queue - the message_queue to be flushed
+ *
+ * Output parameters:
+ * returns - the number of messages flushed from the queue
+ */
+
+unsigned32 _CORE_message_queue_Flush(
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ if ( the_message_queue->number_of_pending_messages != 0 )
+ return _CORE_message_queue_Flush_support( the_message_queue );
+ else
+ return 0;
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Broadcast
+ *
+ * This function sends a message for every thread waiting on the queue and
+ * returns the number of threads made ready by the message.
+ *
+ * Input parameters:
+ * the_message_queue - message is submitted to this message queue
+ * buffer - pointer to message buffer
+ * size - size in bytes of message to send
+ * id - id of message queue
+ * api_message_queue_mp_support - api specific mp support callout
+ * count - area to store number of threads made ready
+ *
+ * Output parameters:
+ * count - number of threads made ready
+ * CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+CORE_message_queue_Status _CORE_message_queue_Broadcast(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ unsigned32 size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
+ unsigned32 *count
+)
+{
+ Thread_Control *the_thread;
+ unsigned32 number_broadcasted;
+ Thread_Wait_information *waitp;
+ unsigned32 constrained_size;
+
+ number_broadcasted = 0;
+ while ((the_thread = _Thread_queue_Dequeue(&the_message_queue->Wait_queue))) {
+ waitp = &the_thread->Wait;
+ number_broadcasted += 1;
+
+ constrained_size = size;
+ if ( size > the_message_queue->maximum_message_size )
+ constrained_size = the_message_queue->maximum_message_size;
+
+ _CORE_message_queue_Copy_buffer(
+ buffer,
+ waitp->return_argument,
+ constrained_size
+ );
+
+ *(rtems_unsigned32 *)the_thread->Wait.return_argument_1 = size;
+
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ (*api_message_queue_mp_support) ( the_thread, id );
+
+ }
+ *count = number_broadcasted;
+ return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Seize
+ *
+ * This kernel routine dequeues a message, copies the message buffer to
+ * a given destination buffer, and frees the message buffer to the
+ * inactive message pool. The thread will be blocked if wait is TRUE,
+ * otherwise an error will be given to the thread if no messages are available.
+ *
+ * Input parameters:
+ * the_message_queue - pointer to message queue
+ * id - id of object we are waitig on
+ * buffer - pointer to message buffer to be filled
+ * size - pointer to the size of buffer to be filled
+ * wait - TRUE if wait is allowed, FALSE otherwise
+ * timeout - time to wait for a message
+ *
+ * Output parameters: NONE
+ *
+ * NOTE: Dependent on BUFFER_LENGTH
+ *
+ * INTERRUPT LATENCY:
+ * available
+ * wait
+ */
+
+void _CORE_message_queue_Seize(
+ CORE_message_queue_Control *the_message_queue,
+ Objects_Id id,
+ void *buffer,
+ unsigned32 *size,
+ boolean wait,
+ Watchdog_Interval timeout
+)
+{
+ ISR_Level level;
+ CORE_message_queue_Buffer_control *the_message;
+ Thread_Control *executing;
+
+ executing = _Thread_Executing;
+ executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
+ _ISR_Disable( level );
+ if ( the_message_queue->number_of_pending_messages != 0 ) {
+ the_message_queue->number_of_pending_messages -= 1;
+
+ the_message = _CORE_message_queue_Get_pending_message( the_message_queue );
+ _ISR_Enable( level );
+ *size = the_message->Contents.size;
+ _CORE_message_queue_Copy_buffer(the_message->Contents.buffer,buffer,*size );
+ _CORE_message_queue_Free_message_buffer(the_message_queue, the_message );
+ return;
+ }
+
+ if ( !wait ) {
+ _ISR_Enable( level );
+ executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT;
+ return;
+ }
+
+ the_message_queue->Wait_queue.sync = TRUE;
+ executing->Wait.queue = &the_message_queue->Wait_queue;
+ executing->Wait.id = id;
+ executing->Wait.return_argument = (void *)buffer;
+ executing->Wait.return_argument_1 = (void *)size;
+ _ISR_Enable( level );
+
+ _Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Flush_support
+ *
+ * This message handler routine removes all messages from a message queue
+ * and returns them to the inactive message pool. The number of messages
+ * flushed from the queue is returned
+ *
+ * Input parameters:
+ * the_message_queue - pointer to message queue
+ *
+ * Output parameters:
+ * returns - number of messages placed on inactive chain
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+unsigned32 _CORE_message_queue_Flush_support(
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ ISR_Level level;
+ Chain_Node *inactive_first;
+ Chain_Node *message_queue_first;
+ Chain_Node *message_queue_last;
+ unsigned32 count;
+
+ _ISR_Disable( level );
+ inactive_first = the_message_queue->Inactive_messages.first;
+ message_queue_first = the_message_queue->Pending_messages.first;
+ message_queue_last = the_message_queue->Pending_messages.last;
+
+ the_message_queue->Inactive_messages.first = message_queue_first;
+ message_queue_last->next = inactive_first;
+ inactive_first->previous = message_queue_last;
+ message_queue_first->previous =
+ _Chain_Head( &the_message_queue->Inactive_messages );
+
+ _Chain_Initialize_empty( &the_message_queue->Pending_messages );
+
+ count = the_message_queue->number_of_pending_messages;
+ the_message_queue->number_of_pending_messages = 0;
+ _ISR_Enable( level );
+ return count;
+}
+
+/*PAGE
+ *
+ * _CORE_message_queue_Submit
+ *
+ * This routine implements the send and urgent message functions. It
+ * processes a message that is to be submitted to the designated
+ * message queue. The message will either be processed as a
+ * 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.
+ *
+ * Input parameters:
+ * the_message_queue - message is submitted to this message queue
+ * buffer - pointer to message buffer
+ * size - size in bytes of message to send
+ * id - id of message queue
+ * api_message_queue_mp_support - api specific mp support callout
+ * submit_type - send or urgent message
+ *
+ * Output parameters:
+ * CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
+ * error code - if unsuccessful
+ */
+
+CORE_message_queue_Status _CORE_message_queue_Submit(
+ CORE_message_queue_Control *the_message_queue,
+ void *buffer,
+ unsigned32 size,
+ Objects_Id id,
+ CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
+ CORE_message_queue_Submit_types submit_type
+)
+{
+ CORE_message_queue_Buffer_control *the_message;
+ Thread_Control *the_thread;
+
+ if ( size > the_message_queue->maximum_message_size )
+ return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
+
+ /*
+ * Is there a thread currently waiting on this message queue?
+ */
+
+ the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
+ if ( the_thread )
+ {
+ _CORE_message_queue_Copy_buffer(
+ buffer,
+ the_thread->Wait.return_argument,
+ size
+ );
+ *(rtems_unsigned32 *)the_thread->Wait.return_argument_1 = size;
+
+ if ( !_Objects_Is_local_id( the_thread->Object.id ) )
+ (*api_message_queue_mp_support) ( the_thread, id );
+
+ return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
+ }
+
+ /*
+ * No one waiting on this one currently.
+ * Allocate a message buffer and store it away
+ */
+
+ if ( the_message_queue->number_of_pending_messages ==
+ the_message_queue->maximum_pending_messages ) {
+ return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
+ }
+
+ the_message = _CORE_message_queue_Allocate_message_buffer(the_message_queue);
+ if ( the_message == 0)
+ return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
+
+ _CORE_message_queue_Copy_buffer( buffer, the_message->Contents.buffer, size );
+ the_message->Contents.size = size;
+
+ the_message_queue->number_of_pending_messages += 1;
+
+ switch ( submit_type ) {
+ case CORE_MESSAGE_QUEUE_SEND_REQUEST:
+ _CORE_message_queue_Append( the_message_queue, the_message );
+ break;
+ case CORE_MESSAGE_QUEUE_URGENT_REQUEST:
+ _CORE_message_queue_Prepend( the_message_queue, the_message );
+ break;
+ }
+
+ return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
+}