summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
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;
+}