[runtime] rts serialization additions
1. Increment rts-pingpong model to include more complex data.
2. Add UMLRTInMessage
3. Debug UMLRTObject_class encode/decode/fprintf.
4. Add fields to UMLRTObject_class and UMLRTObject_field
5. Resolve Bug 467789 - missing RTType for long double.
6. Resolve Bug 467787 - segfault when incarnating a capsule with no ports
Change-Id: I1a06221ffc6eb87cbcd7037c972d59964bfc25b5
Signed-off-by: Barry Maher <bmaher@gpinc.ca>
diff --git a/.gitignore b/.gitignore
index a291f7e..b848b16 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,4 @@
rts/build
rts/lib
rts/test/rts-pingpong/main
-rts/test/rts-pingpong/*.o
+*.o
diff --git a/rts/Makefile b/rts/Makefile
index 1efb7d4..b862691 100644
--- a/rts/Makefile
+++ b/rts/Makefile
@@ -182,6 +182,7 @@
$(BUILDROOT)/umlrt/umlrtframeprotocol.o \
$(BUILDROOT)/umlrt/umlrtframeservice.o \
$(BUILDROOT)/umlrt/umlrthashmap.o \
+ $(BUILDROOT)/umlrt/umlrtinmessage.o \
$(BUILDROOT)/umlrt/umlrtinsignal.o \
$(BUILDROOT)/umlrt/umlrtlogprotocol.o \
$(BUILDROOT)/umlrt/umlrtmain.o \
diff --git a/rts/include/umlrtcapsule.hh b/rts/include/umlrtcapsule.hh
index 8812ff5..7b2dd0a 100644
--- a/rts/include/umlrtcapsule.hh
+++ b/rts/include/umlrtcapsule.hh
@@ -25,7 +25,7 @@
// Sub-classes define the model's capsules and contain user-defined and methods.
struct UMLRTSlot;
-struct UMLRTMessage;
+struct UMLRTInMessage;
struct UMLRTController;
struct UMLRTCapsuleClass;
class UMLRTRtsInterface;
@@ -34,8 +34,8 @@
{
public:
virtual ~UMLRTCapsule ( );
- virtual void initialize ( const UMLRTMessage & msg ) = 0;
- virtual void inject ( const UMLRTMessage & msg ) = 0;
+ virtual void initialize ( const UMLRTInMessage & msg ) = 0;
+ virtual void inject ( const UMLRTInMessage & msg ) = 0;
virtual void unbindPort ( bool isBorder, int portIndex, int farEndIndex );
virtual void bindPort ( bool isBorder, int portIndex, int farEndIndex );
diff --git a/rts/include/umlrtinmessage.hh b/rts/include/umlrtinmessage.hh
new file mode 100644
index 0000000..3c45ed7
--- /dev/null
+++ b/rts/include/umlrtinmessage.hh
@@ -0,0 +1,30 @@
+// umlrtinmessage.hh
+
+/*******************************************************************************
+* Copyright (c) 2015 Zeligsoft (2009) Limited and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*******************************************************************************/
+
+#ifndef UMLRTINMESSAGE_HH
+#define UMLRTINMESSAGE_HH
+
+#include <stdint.h>
+#include "umlrtmessage.hh"
+
+class UMLRTInMessage : public UMLRTMessage
+{
+public:
+
+ UMLRTInMessage ( ) : UMLRTMessage() {};
+
+ int getSignalId ( ) const { return signal.getId(); }
+
+ void decodeInit ( const UMLRTObject_class * desc ) const;
+ void decode ( void * data, int arraySize = 1 ) const;
+ void decode ( int ptrIndirection, void * data, int arraySize = 1 ) const;
+};
+
+#endif // UMLRTMESSAGE_HH
diff --git a/rts/include/umlrtinsignal.hh b/rts/include/umlrtinsignal.hh
index f1b6b78..6bfe421 100644
--- a/rts/include/umlrtinsignal.hh
+++ b/rts/include/umlrtinsignal.hh
@@ -27,11 +27,8 @@
// for the FIRST call to the #decode methods, after which is it modified
// during decoding (i.e. is an input/output parameter to #decode methods).
- // Bug 101 tracks buffer-overrun detection.
- // Initial version will have FATAL called if decoding fails (e.g. runs out of payload).
- // Other behaviour can be specified later.
- void decode( void * * decodeInfo, void * data, const UMLRTObject_class * desc, int arraySize = 1 ) const;
- void decode( void * * decodeInfo, int ptrIndirection, void * data, const UMLRTObject_class * desc, int arraySize = 1 ) const;
+ void decode( const void * * decodeInfo, const UMLRTObject_class * desc, void * data, int arraySize = 1 ) const;
+ void decode( const void * * decodeInfo, const UMLRTObject_class * desc, int ptrIndirection, void * data, int arraySize = 1 ) const;
// Delete all deferred signals of this type on all port instances. Returns the number of deleted messages.
int purge();
diff --git a/rts/include/umlrtlogprotocol.hh b/rts/include/umlrtlogprotocol.hh
index 4d48b13..1f0b1cf 100644
--- a/rts/include/umlrtlogprotocol.hh
+++ b/rts/include/umlrtlogprotocol.hh
@@ -40,7 +40,7 @@
int log ( unsigned long long ull ) const;
int log ( float f ) const;
int log ( double d ) const;
- int log ( const void * userData, const UMLRTObject_class * type ) const;
+ int log ( const void * userData, const UMLRTObject_class * type, int arraySize = 1 ) const;
int log ( const UMLRTTypedValue & value ) const;
// Output data with NO new-line appended.
@@ -57,7 +57,7 @@
int show ( unsigned long long ull ) const;
int show ( float f ) const;
int show ( double d ) const;
- int show ( const void * userData, const UMLRTObject_class * type ) const;
+ int show ( const void * userData, const UMLRTObject_class * type, int arraySize = 1 ) const;
int show ( const UMLRTTypedValue & value ) const;
// Output newline(s).
diff --git a/rts/include/umlrtmessage.hh b/rts/include/umlrtmessage.hh
index 2e2f7fe..028c515 100644
--- a/rts/include/umlrtmessage.hh
+++ b/rts/include/umlrtmessage.hh
@@ -35,7 +35,7 @@
{
public:
- UMLRTMessage() : srcPortIndex(0), sapIndex0(0), destPort(NULL), destSlot(NULL), isCommand(false) {};
+ UMLRTMessage() : srcPortIndex(0), sapIndex0(0), destPort(NULL), destSlot(NULL), desc(NULL), decodeInfo(NULL), isCommand(false), allocated(false) {};
size_t srcPortIndex; // The associated srcPort of the message is contained within the signal.
size_t sapIndex0; // The port index on the receive side.
@@ -45,6 +45,9 @@
UMLRTSignal signal;
+ mutable const UMLRTObject_class * desc;
+ mutable const void * decodeInfo;
+
unsigned isCommand : 1; // true when it's a command and not a signal.
unsigned allocated : 1; // For sanity checking of message allocation.
diff --git a/rts/include/umlrtobjectclass.hh b/rts/include/umlrtobjectclass.hh
index 17cd28a..5a86b78 100644
--- a/rts/include/umlrtobjectclass.hh
+++ b/rts/include/umlrtobjectclass.hh
@@ -44,13 +44,9 @@
const char * name;
const UMLRTObject_class * desc;
int offset;
- int ptrIndirection;
-};
-
-// Fields types which are arrays have the (additional) array size as part of the type descriptor.
-struct UMLRTObject_arrayField : public UMLRTObject_field
-{
+ int sizeDecoded;
int arraySize;
+ int ptrIndirection;
};
// All types are described by a 'data descriptor', namely a UMLRTObject_class.
@@ -69,18 +65,21 @@
{
const char * const name;
- void * ( * initialize )( const UMLRTObject_class * desc, void * data );
- void * ( * copy )( const UMLRTObject_class * desc, const void * src, void * dst );
- void * ( * decode )( const UMLRTObject_class * desc, const void * src, void * dst );
- void * ( * encode )( const UMLRTObject_class * desc, const void * src, void * dst );
- void * ( * destroy )( const UMLRTObject_class * desc, void * data );
- size_t ( * getSize )( const UMLRTObject_class * desc );
- int ( * fprintf )( FILE * ostream, const UMLRTObject_class * desc, const void * data ); // returns number of chars output.
+ void * ( * initialize ) ( const UMLRTObject_class * desc, void * data );
+ void * ( * copy ) ( const UMLRTObject_class * desc, const void * src, void * dst );
+ // decode returns pointer to next byte in decoded bytes.
+ const void * ( * decode ) ( const UMLRTObject_class * desc, const void * src, void * dst, int nest );
+ // encode returns pointer to next byte in encoded bytes.
+ void * ( * encode ) ( const UMLRTObject_class * desc, const void * src, void * dst, int nest );
+ void * ( * destroy ) ( const UMLRTObject_class * desc, void * data );
+ size_t ( * getSize ) ( const UMLRTObject_class * desc );
+ int ( * fprintf ) ( FILE * ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize ); // returns number of chars output.
const UMLRTObject_class * const super; // Base type
const uint16_t version;
const uint16_t backwards;
- const size_t size; // Is either size of type (fields NULL) or number of fields (fields non-NULL)
+ const int sizeDecoded; // Size of a decoded element of this type.
+ const int size; // Is either encoded size of basic type (fields NULL) or number of fields (fields non-NULL)
const UMLRTObject_field * fields;
};
@@ -92,14 +91,15 @@
};
// A set of default functions for basic data-descriptions (types) are pre-defined.
-extern void * UMLRTObject_initialize( const UMLRTObject_class * desc, void * data );
-extern void * UMLRTObject_copy( const UMLRTObject_class * desc, const void * src, void * dst );
-extern void * UMLRTObject_decode( const UMLRTObject_class * desc, const void * src, void * dst );
-extern void * UMLRTObject_encode( const UMLRTObject_class * desc, const void * src, void * dst );
-extern void * UMLRTObject_destroy( const UMLRTObject_class * desc, void * data );
-extern size_t UMLRTObject_getSize( const UMLRTObject_class * desc );
-// Returns the number of characters that were printed.
-extern int UMLRTObject_fprintf( FILE *ostream, const UMLRTObject_class * desc, const void * data );
+extern void * UMLRTObject_initialize ( const UMLRTObject_class * desc, void * data );
+extern void * UMLRTObject_copy ( const UMLRTObject_class * desc, const void * src, void * dst );
+extern const void * UMLRTObject_decode ( const UMLRTObject_class * desc, const void * src, void * dst, int nest );
+extern void * UMLRTObject_encode ( const UMLRTObject_class * desc, const void * src, void * dst, int nest );
+extern void * UMLRTObject_destroy ( const UMLRTObject_class * desc, void * data );
+extern size_t UMLRTObject_getSize ( const UMLRTObject_class * desc );
+
+// The following returns the number of characters that were printed.
+extern int UMLRTObject_fprintf( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize );
// These are the primitive data-types with pre-defined data descriptors.
extern const UMLRTObject_class * const UMLRTType_bool;
diff --git a/rts/include/umlrtoutsignal.hh b/rts/include/umlrtoutsignal.hh
index 944b5cf..acb9365 100644
--- a/rts/include/umlrtoutsignal.hh
+++ b/rts/include/umlrtoutsignal.hh
@@ -27,11 +27,8 @@
// The encoding keeps track of where in the payload the next data-item should be
// serialized. The 'initialize' function initializes the encoding and each call
// to the encoding functions moves the encoding-location forward.
-
- // Currently, FATAL is called if encoding fails (e.g. runs out of payload).
- // Other behaviour can be specified later.
- void encode( const void * data, const UMLRTObject_class * desc, int arraySize = 1 );
- void encode( int ptrIndirection, void * data, const UMLRTObject_class * desc, int arraySize = 1 );
+ void encode( const UMLRTObject_class * desc, const void * data, int arraySize = 1 );
+ void encode( const UMLRTObject_class * desc, int ptrIndirection, void * data, int arraySize = 1 );
// Synchronous send out all port instances. Returns the number of replies (0 if fail).
int invoke( UMLRTMessage * replyMsgs );
diff --git a/rts/include/umlrtprioritymessagequeue.hh b/rts/include/umlrtprioritymessagequeue.hh
index 570266d..b233c6d 100644
--- a/rts/include/umlrtprioritymessagequeue.hh
+++ b/rts/include/umlrtprioritymessagequeue.hh
@@ -11,7 +11,7 @@
#ifndef UMLRTPRIORITYMESSAGEQUEUE_HH
#define UMLRTPRIORITYMESSAGEQUEUE_HH
-#include "umlrtmessage.hh"
+#include "umlrtinmessage.hh"
#include "umlrtmessagequeue.hh"
#include "umlrtsemaphore.hh"
#include "umlrtsignal.hh"
@@ -43,7 +43,7 @@
void queueTimerMessages( UMLRTTimerQueue * timerQueue );
// Get the highest priority message from the collection of queues.
- UMLRTMessage * dequeueHighestPriority();
+ UMLRTInMessage * dequeueHighestPriority();
// Put the message into its appropriate priority-queue.
void enqueue( UMLRTMessage * msg, bool front = false );
diff --git a/rts/include/umlrtsignalelement.hh b/rts/include/umlrtsignalelement.hh
index ecf0312..6f10fe4 100644
--- a/rts/include/umlrtsignalelement.hh
+++ b/rts/include/umlrtsignalelement.hh
@@ -80,13 +80,13 @@
Priority getPriority() const { return priority; }
void setPriority( Priority priority_) { priority = priority_; }
- // See documentation in UMLRTSignal.
+ // Encode 'data' buffer into payload.
void encode( const UMLRTObject_class * desc, const void * data, int arraySize = 1 );
void encode( const UMLRTObject_class * desc, int ptrIndirection, const void * data, int arraySize = 1 );
- // See documentation in UMLRTSignal.
- void decode( void * * decodeInfo, const UMLRTObject_class * desc, void * data, int arraySize = 1 );
- void decode( void * * decodeInfo, const UMLRTObject_class * desc, int ptrIndirection, void * data, int arraySize = 1 );
+ // Decode payload into 'data' buffer.
+ void decode( const void * * decodeInfo, const UMLRTObject_class * desc, void * data, int arraySize = 1 );
+ void decode( const void * * decodeInfo, const UMLRTObject_class * desc, int ptrIndirection, void * data, int arraySize = 1 );
// Pool allocation sanity check.
void setAllocated( bool allocated_ );
diff --git a/rts/test/rts-pingpong/DataType1.cc b/rts/test/rts-pingpong/DataType1.cc
index 3e5f119..fef44b1 100644
--- a/rts/test/rts-pingpong/DataType1.cc
+++ b/rts/test/rts-pingpong/DataType1.cc
@@ -4,31 +4,91 @@
#include "umlrtobjectclass.hh"
#include <cstddef>
+static const UMLRTObject_field sst1fields[] =
+{
+ {
+ "name",
+ UMLRTType_char,
+ offsetof( SubStructType1, name ),
+ sizeof(((struct SubStructType1 *)0)->name[0]),
+ 8,
+ 0
+ },
+ {
+ "character",
+ UMLRTType_char,
+ offsetof( SubStructType1, character),
+ sizeof(((struct SubStructType1 *)0)->character),
+ 1,
+ 0
+ },
+ {
+ "integer",
+ UMLRTType_int,
+ offsetof( SubStructType1, integer ),
+ sizeof(((struct SubStructType1 *)0)->integer),
+ 1,
+ 0
+ },
+};
+static const UMLRTObject_class sst1desc =
+{
+ "SubStructType1",
+ UMLRTObject_initialize,
+ UMLRTObject_copy,
+ UMLRTObject_decode,
+ UMLRTObject_encode,
+ UMLRTObject_destroy,
+ UMLRTObject_getSize,
+ UMLRTObject_fprintf,
+ NULL,
+ UMLRTOBJECTCLASS_DEFAULT_VERSION,
+ UMLRTOBJECTCLASS_DEFAULT_BACKWARDS,
+ sizeof(SubStructType1),
+ 3,
+ sst1fields
+};
+const UMLRTObject_class * const RTType_SubStruct1 = &sst1desc;
-static const UMLRTObject_field fields[] =
+static const UMLRTObject_field dt1fields[] =
{
{
"field1_int",
UMLRTType_int,
offsetof( DataType1, field1_int ),
+ sizeof(((struct DataType1 *)0)->field1_int[0]),
+ 2,
0
},
{
"field2_bool",
UMLRTType_bool,
offsetof( DataType1, field2_bool ),
+ sizeof(((struct DataType1 *)0)->field2_bool),
+ 1,
0
},
{
"field3_double",
UMLRTType_double,
offsetof( DataType1, field3_double ),
+ sizeof(((struct DataType1 *)0)->field3_double),
+ 1,
0
- }
+ },
+ {
+ "field4_sst1",
+ RTType_SubStruct1,
+ offsetof( DataType1, field4_sst1 ),
+ sizeof(((struct DataType1 *)0)->field4_sst1[0]),
+ 3,
+ 0
+ },
+
};
-static const UMLRTObject_class desc =
+static const UMLRTObject_class dt1desc =
{
"DataType1",
UMLRTObject_initialize,
@@ -41,7 +101,9 @@
NULL,
UMLRTOBJECTCLASS_DEFAULT_VERSION,
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS,
- 3,
- fields
+ sizeof(DataType1),
+ 4,
+ dt1fields
};
-const UMLRTObject_class * const RTType_DataType1 = &desc;
+
+const UMLRTObject_class * const RTType_DataType1 = &dt1desc;
diff --git a/rts/test/rts-pingpong/DataType1.hh b/rts/test/rts-pingpong/DataType1.hh
index e6b3af8..ce1c122 100644
--- a/rts/test/rts-pingpong/DataType1.hh
+++ b/rts/test/rts-pingpong/DataType1.hh
@@ -4,12 +4,21 @@
struct UMLRTObject_class;
+struct SubStructType1
+{
+ char name[8];
+ char character; // Force alignment to insert padding.
+ int integer;
+};
+
struct DataType1
{
- int field1_int;
+ int field1_int[2];
bool field2_bool;
double field3_double;
+ SubStructType1 field4_sst1[3];
};
+extern const UMLRTObject_class * const RTType_SubStructType1;
extern const UMLRTObject_class * const RTType_DataType1;
#endif
diff --git a/rts/test/rts-pingpong/Makefile b/rts/test/rts-pingpong/Makefile
index 17b57ce..c9f3905 100644
--- a/rts/test/rts-pingpong/Makefile
+++ b/rts/test/rts-pingpong/Makefile
@@ -3,7 +3,7 @@
################################################
# Location of RTS root.
-UMLRTS_ROOT ?= /home/barrymintzs/org.eclipse2/org.eclipse.papyrus-rt/rts
+UMLRTS_ROOT ?= ../../../rts
# Compiler
# This can be overridden while invoking make with CC=xxx.
diff --git a/rts/test/rts-pingpong/PingPongProtocol.cc b/rts/test/rts-pingpong/PingPongProtocol.cc
index 082777d..06ba27d 100644
--- a/rts/test/rts-pingpong/PingPongProtocol.cc
+++ b/rts/test/rts-pingpong/PingPongProtocol.cc
@@ -7,42 +7,71 @@
struct UMLRTCommsPort;
-UMLRTOutSignal PingPongProtocol::OutSignals::ping( const UMLRTCommsPort * sourcePort, const DataType1 & param ) const
+UMLRTOutSignal PingPongProtocol::OutSignals::ping ( const UMLRTCommsPort * sourcePort, const DataType1 (& param)[2] ) const
{
UMLRTOutSignal signal;
- signal.initialize( signal_ping, sourcePort, sizeof( param ) );
- memcpy( signal.getPayload(), ¶m, sizeof( param ) );
+ if (signal.initialize( signal_ping, sourcePort, RTType_DataType1->getSize(RTType_DataType1)*2))
+ {
+ signal.encode(RTType_DataType1, ¶m, 2);
+ }
+ return signal;
+}
+
+UMLRTInSignal PingPongProtocol::OutSignals::pong ( const UMLRTCommsPort * sourcePort ) const
+{
+ UMLRTInSignal signal;
+ signal.initialize( signal_pong, sourcePort );
return signal;
}
-UMLRTOutSignal PingPongProtocol::InSignals::pong( const UMLRTCommsPort * sourcePort ) const
+UMLRTOutSignal PingPongProtocol::InSignals::pong ( const UMLRTCommsPort * sourcePort, const DataType1 (& param)[2] ) const
{
UMLRTOutSignal signal;
- signal.initialize( signal_pong, sourcePort, 0 );
+ if (signal.initialize( signal_pong, sourcePort, RTType_DataType1->getSize(RTType_DataType1)*2))
+ {
+ signal.encode(RTType_DataType1, ¶m, 2);
+ }
+ return signal;
+}
+
+UMLRTInSignal PingPongProtocol::InSignals::ping ( const UMLRTCommsPort * sourcePort ) const
+{
+ UMLRTInSignal signal;
+ signal.initialize( signal_ping, sourcePort );
return signal;
}
-PingPongProtocol_baserole::PingPongProtocol_baserole( const UMLRTCommsPort * srcPort )
+PingPongProtocol_baserole::PingPongProtocol_baserole ( const UMLRTCommsPort * srcPort )
: UMLRTProtocol( srcPort )
{
}
-UMLRTOutSignal PingPongProtocol_baserole::ping( const DataType1 & param ) const
+UMLRTOutSignal PingPongProtocol_baserole::ping ( const DataType1 (& param)[2] ) const
{
return PingPongProtocol::Base::ping( srcPort, param );
}
+UMLRTInSignal PingPongProtocol_baserole::pong ( ) const
+{
+ return PingPongProtocol::Base::pong( srcPort );
+}
+
PingPongProtocol_conjrole::PingPongProtocol_conjrole( const UMLRTCommsPort * srcPort )
: UMLRTProtocol( srcPort )
{
}
-UMLRTOutSignal PingPongProtocol_conjrole::pong() const
+UMLRTOutSignal PingPongProtocol_conjrole::pong( const DataType1 (& param)[2] ) const
{
- return PingPongProtocol::Conjugate::pong( srcPort );
+ return PingPongProtocol::Conjugate::pong( srcPort, param );
+}
+
+UMLRTInSignal PingPongProtocol_conjrole::ping ( ) const
+{
+ return PingPongProtocol::Conjugate::ping( srcPort );
}
diff --git a/rts/test/rts-pingpong/PingPongProtocol.hh b/rts/test/rts-pingpong/PingPongProtocol.hh
index 325a79c..3c41f43 100644
--- a/rts/test/rts-pingpong/PingPongProtocol.hh
+++ b/rts/test/rts-pingpong/PingPongProtocol.hh
@@ -3,6 +3,7 @@
#define PINGPONGPROTOCOL_HH
#include "DataType1.hh"
+#include "umlrtinsignal.hh"
#include "umlrtoutsignal.hh"
#include "umlrtprotocol.hh"
#include "umlrtsignal.hh"
@@ -19,12 +20,14 @@
class OutSignals
{
public:
- UMLRTOutSignal ping( const UMLRTCommsPort * sourcePort, const DataType1 & param ) const;
+ UMLRTOutSignal ping ( const UMLRTCommsPort * sourcePort, const DataType1 (& param)[2] ) const;
+ UMLRTInSignal pong ( const UMLRTCommsPort * sourcePort ) const;
};
class InSignals
{
public:
- UMLRTOutSignal pong( const UMLRTCommsPort * sourcePort ) const;
+ UMLRTInSignal ping ( const UMLRTCommsPort * sourcePort ) const;
+ UMLRTOutSignal pong ( const UMLRTCommsPort * sourcePort, const DataType1 (& param)[2] ) const;
};
typedef OutSignals Base;
typedef InSignals Conjugate;
@@ -32,14 +35,16 @@
class PingPongProtocol_baserole : protected UMLRTProtocol, private PingPongProtocol::Base
{
public:
- PingPongProtocol_baserole( const UMLRTCommsPort * srcPort );
- UMLRTOutSignal ping( const DataType1 & param ) const;
+ PingPongProtocol_baserole ( const UMLRTCommsPort * srcPort );
+ UMLRTOutSignal ping ( const DataType1 (& param)[2] ) const;
+ UMLRTInSignal pong ( ) const;
};
class PingPongProtocol_conjrole : protected UMLRTProtocol, private PingPongProtocol::Conjugate
{
public:
- PingPongProtocol_conjrole( const UMLRTCommsPort * srcPort );
- UMLRTOutSignal pong() const;
+ PingPongProtocol_conjrole ( const UMLRTCommsPort * srcPort );
+ UMLRTOutSignal pong ( const DataType1 (& param)[2] ) const;
+ UMLRTInSignal ping ( ) const;
};
#endif
diff --git a/rts/test/rts-pingpong/Pinger.cc b/rts/test/rts-pingpong/Pinger.cc
index 6477137..0b7f501 100644
--- a/rts/test/rts-pingpong/Pinger.cc
+++ b/rts/test/rts-pingpong/Pinger.cc
@@ -7,16 +7,17 @@
#include "umlrtcommsportfarend.hh"
#include "umlrtcommsportrole.hh"
#include "umlrtframeservice.hh"
-#include "umlrtmessage.hh"
+#include "umlrtinmessage.hh"
#include "umlrtslot.hh"
#include "umlrttimerprotocol.hh"
#include <cstddef>
class UMLRTRtsInterface;
#include <iostream>
+#include <stdio.h>
Capsule_Pinger::Capsule_Pinger( UMLRTSlot * st, const UMLRTCommsPort * * border, const UMLRTCommsPort * internal, bool isStat )
-: UMLRTCapsule( NULL, &Pinger, st, border, internal, isStat )
+: UMLRTCapsule( NULL, &Pinger, st, border, internal, isStat ), timeoutCount(0)
{
}
@@ -64,7 +65,7 @@
}
}
-void Capsule_Pinger::inject( const UMLRTMessage & msg )
+void Capsule_Pinger::inject( const UMLRTInMessage & msg )
{
switch( currentState )
{
@@ -74,7 +75,7 @@
}
}
-void Capsule_Pinger::initialize( const UMLRTMessage & msg )
+void Capsule_Pinger::initialize( const UMLRTInMessage & msg )
{
actionchain_____top__initialise__ActionChain3( msg );
currentState = top__Running;
@@ -82,55 +83,73 @@
-void Capsule_Pinger::entryaction_____top__initialise__ActionChain3__onEntry( const UMLRTMessage & msg )
+void Capsule_Pinger::entryaction_____top__initialise__ActionChain3__onEntry( const UMLRTInMessage & msg )
{
void * rtdata = *(void * *)msg.signal.getPayload();
}
-void Capsule_Pinger::transitionaction_____top__initialise__ActionChain3__onInit( const UMLRTMessage & msg )
+void Capsule_Pinger::transitionaction_____top__initialise__ActionChain3__onInit( const UMLRTInMessage & msg )
{
void * rtdata = *(void * *)msg.signal.getPayload();
std::cout << "Pinger initialised" << std::endl;
- timerPort().informIn( UMLRTTimespec( 2, 0 ) );
+ timerPort().informEvery( UMLRTTimespec( 2, 0 ) );
}
-void Capsule_Pinger::transitionaction_____top__onPong__ActionChain5__onPong( const UMLRTMessage & msg )
+void Capsule_Pinger::transitionaction_____top__onPong__ActionChain5__onPong( const UMLRTInMessage & msg )
+{
+ std::cout << getName() << ":received pong payload size " << msg.signal.getPayloadSize() << std::endl;
+ RTType_DataType1->fprintf(stdout, RTType_DataType1, msg.signal.getPayload(), 0/*nest*/, 2/*arraySize*/);
+ std::cout << std::endl;
+
+ DataType1 rtdata[2];
+ msg.decode(&rtdata, 2);
+ std::cout << getName() <<
+ " rtdata[2] size " << sizeof(rtdata) <<
+ " rtdata[0].field1_int[1] " << rtdata[0].field1_int[1] <<
+ " rtdata[1].sst1.[2].name " << rtdata[1].field4_sst1[2].name <<
+ " rtdata[1].sst1.[2].integer " << rtdata[1].field4_sst1[2].integer <<
+ std::endl;
+}
+
+void Capsule_Pinger::transitionaction_____top__onTimeout__ActionChain7__onTimeout( const UMLRTInMessage & msg )
{
void * rtdata = *(void * *)msg.signal.getPayload();
- std::cout << "Pong received" << std::endl;
- timerPort().informIn( UMLRTTimespec( 2, 0 ) );
+ DataType1 dt[2] = {
+ { {timeoutCount*10, timeoutCount*10 + 1}, (timeoutCount & 1) != 0, timeoutCount*10 + 3.,
+ {{"start", 'a', timeoutCount*10 + 4}, {"middle", 'b', timeoutCount*10 + 5}, {"end", 'c', timeoutCount*10 + 6}}},
+ { {timeoutCount*10 + 7, timeoutCount*10 + 8}, (timeoutCount & 2) != 0, timeoutCount*10 + 9.,
+ {{"start2", 'd', timeoutCount*10 + 1}, {"middle2", 'e', timeoutCount*10 + 2}, {"end2", 'f', timeoutCount*10 + 3 }}},
+ };
+ std::cout << getName() << ":Sending ping from timeout transition action - timeoutCount " << timeoutCount << " " << std::endl;
+ UMLRTOutSignal s = PingPort().ping( dt );
+ std::cout << "Encoded parameter:" << std::endl;
+ RTType_DataType1->fprintf(stdout, RTType_DataType1, s.getPayload(), 0/*nest*/, 2/*arraySize*/);
+ s.send();
+ ++timeoutCount;
}
-void Capsule_Pinger::transitionaction_____top__onTimeout__ActionChain7__onTimeout( const UMLRTMessage & msg )
-{
- void * rtdata = *(void * *)msg.signal.getPayload();
- std::cout << "Sending Ping from timeout transition action" << std::endl;
- DataType1 dt = { 0, true, 3. };
- PingPort().ping( dt ).send();
-}
-
-void Capsule_Pinger::actionchain_____top__initialise__ActionChain3( const UMLRTMessage & msg )
+void Capsule_Pinger::actionchain_____top__initialise__ActionChain3( const UMLRTInMessage & msg )
{
transitionaction_____top__initialise__ActionChain3__onInit( msg );
entryaction_____top__initialise__ActionChain3__onEntry( msg );
}
-void Capsule_Pinger::actionchain_____top__onPong__ActionChain5( const UMLRTMessage & msg )
+void Capsule_Pinger::actionchain_____top__onPong__ActionChain5( const UMLRTInMessage & msg )
{
transitionaction_____top__onPong__ActionChain5__onPong( msg );
}
-void Capsule_Pinger::actionchain_____top__onTimeout__ActionChain7( const UMLRTMessage & msg )
+void Capsule_Pinger::actionchain_____top__onTimeout__ActionChain7( const UMLRTInMessage & msg )
{
transitionaction_____top__onTimeout__ActionChain7__onTimeout( msg );
}
-Capsule_Pinger::State Capsule_Pinger::state_____top__Running( const UMLRTMessage & msg )
+Capsule_Pinger::State Capsule_Pinger::state_____top__Running( const UMLRTInMessage & msg )
{
switch( msg.destPort->role()->id )
{
case port_timerPort:
- switch( msg.signal.getId() )
+ switch( msg.getSignalId() )
{
case UMLRTTimerProtocol::signal_timeout:
actionchain_____top__onTimeout__ActionChain7( msg );
@@ -138,9 +157,10 @@
}
return currentState;
case port_PingPort:
- switch( msg.signal.getId() )
+ switch( msg.getSignalId() )
{
case PingPongProtocol::signal_pong:
+ msg.decodeInit(RTType_DataType1); // Assume this is the place where parameter types are known.
actionchain_____top__onPong__ActionChain5( msg );
return top__Running;
}
diff --git a/rts/test/rts-pingpong/Pinger.hh b/rts/test/rts-pingpong/Pinger.hh
index 98fcd44..2bebbf6 100644
--- a/rts/test/rts-pingpong/Pinger.hh
+++ b/rts/test/rts-pingpong/Pinger.hh
@@ -5,7 +5,7 @@
#include "PingPongProtocol.hh"
#include "umlrtcapsule.hh"
#include "umlrtcapsuleclass.hh"
-#include "umlrtmessage.hh"
+#include "umlrtinmessage.hh"
#include "umlrttimerprotocol.hh"
struct UMLRTCommsPort;
struct UMLRTSlot;
@@ -35,8 +35,8 @@
};
virtual void bindPort( bool isBorder, int portId, int index );
virtual void unbindPort( bool isBorder, int portId, int index );
- virtual void inject( const UMLRTMessage & msg );
- virtual void initialize( const UMLRTMessage & msg );
+ virtual void inject( const UMLRTInMessage & msg );
+ virtual void initialize( const UMLRTInMessage & msg );
private:
enum State
{
@@ -44,14 +44,16 @@
SPECIAL_INTERNAL_STATE_UNVISITED
};
State currentState;
- void entryaction_____top__initialise__ActionChain3__onEntry( const UMLRTMessage & msg );
- void transitionaction_____top__initialise__ActionChain3__onInit( const UMLRTMessage & msg );
- void transitionaction_____top__onPong__ActionChain5__onPong( const UMLRTMessage & msg );
- void transitionaction_____top__onTimeout__ActionChain7__onTimeout( const UMLRTMessage & msg );
- void actionchain_____top__initialise__ActionChain3( const UMLRTMessage & msg );
- void actionchain_____top__onPong__ActionChain5( const UMLRTMessage & msg );
- void actionchain_____top__onTimeout__ActionChain7( const UMLRTMessage & msg );
- State state_____top__Running( const UMLRTMessage & msg );
+ void entryaction_____top__initialise__ActionChain3__onEntry( const UMLRTInMessage & msg );
+ void transitionaction_____top__initialise__ActionChain3__onInit( const UMLRTInMessage & msg );
+ void transitionaction_____top__onPong__ActionChain5__onPong( const UMLRTInMessage & msg );
+ void transitionaction_____top__onTimeout__ActionChain7__onTimeout( const UMLRTInMessage & msg );
+ void actionchain_____top__initialise__ActionChain3( const UMLRTInMessage & msg );
+ void actionchain_____top__onPong__ActionChain5( const UMLRTInMessage & msg );
+ void actionchain_____top__onTimeout__ActionChain7( const UMLRTInMessage & msg );
+ State state_____top__Running( const UMLRTInMessage & msg );
+
+ int timeoutCount;
};
extern const UMLRTCapsuleClass Pinger;
diff --git a/rts/test/rts-pingpong/Ponger.cc b/rts/test/rts-pingpong/Ponger.cc
index 7f68194..ba871db 100644
--- a/rts/test/rts-pingpong/Ponger.cc
+++ b/rts/test/rts-pingpong/Ponger.cc
@@ -8,13 +8,14 @@
#include "umlrtcommsportfarend.hh"
#include "umlrtcommsportrole.hh"
#include "umlrtframeservice.hh"
-#include "umlrtmessage.hh"
+#include "umlrtinmessage.hh"
#include "umlrtsignal.hh"
#include "umlrtslot.hh"
#include <cstddef>
class UMLRTRtsInterface;
#include <iostream>
+#include <stdio.h>
Capsule_Ponger::Capsule_Ponger( UMLRTSlot * st, const UMLRTCommsPort * * border, const UMLRTCommsPort * internal, bool isStat )
: UMLRTCapsule( NULL, &Ponger, st, border, internal, isStat )
@@ -69,7 +70,7 @@
}
}
-void Capsule_Ponger::inject( const UMLRTMessage & msg )
+void Capsule_Ponger::inject( const UMLRTInMessage & msg )
{
switch( currentState )
{
@@ -79,7 +80,7 @@
}
}
-void Capsule_Ponger::initialize( const UMLRTMessage & msg )
+void Capsule_Ponger::initialize( const UMLRTInMessage & msg )
{
actionchain_____top__initial__ActionChain3( msg );
currentState = top__Running;
@@ -87,46 +88,65 @@
-void Capsule_Ponger::transitionaction_____top__initial__ActionChain3__onInit( const UMLRTMessage & msg )
+void Capsule_Ponger::transitionaction_____top__initial__ActionChain3__onInit( const UMLRTInMessage & msg )
{
void * rtdata = *(void * *)msg.signal.getPayload();
std::cout << "Ponger initialised" << std::endl;
}
-void Capsule_Ponger::transitionaction_____top__onBound__ActionChain6__onBound( const UMLRTMessage & msg )
+void Capsule_Ponger::transitionaction_____top__onBound__ActionChain6__onBound( const UMLRTInMessage & msg )
{
void * rtdata = *(void * *)msg.signal.getPayload();
printf( "%s onBound\n", getName() );
}
-void Capsule_Ponger::transitionaction_____top__onPing__ActionChain5__onPing( const UMLRTMessage & msg )
+void Capsule_Ponger::transitionaction_____top__onPing__ActionChain5__onPing( const UMLRTInMessage & msg )
{
- const DataType1 & rtdata = *(DataType1 * )msg.signal.getPayload();
- std::cout << "Ping received"
- << " field1:" << rtdata.field1_int
- << " field2:" << rtdata.field2_bool
- << " field3:" << rtdata.field3_double
- << std::endl;
- std::cout << "Sending Pong" << std::endl;
- PongPort().pong().send();
+ std::cout << getName() << ":received ping" << std::endl;
+ RTType_DataType1->fprintf(stdout, RTType_DataType1, msg.signal.getPayload(), 0/*nest*/, 2/*arraySize*/);
+
+ DataType1 rtdata[2];
+ msg.decode(&rtdata, 2);
+ std::cout << getName() <<
+ " rtdata[0].field1_int[1] " << rtdata[0].field1_int[1] <<
+ " rtdata[1].field1_int[1] " << rtdata[1].field1_int[1] <<
+ " rtdata[0].field3_double " << rtdata[0].field3_double <<
+ " rtdata[1].field3_double " << rtdata[1].field3_double <<
+ " rtdata[1].sst1.[2].name " << rtdata[1].field4_sst1[2].name <<
+ " rtdata[1].sst1.[2].integer " << rtdata[1].field4_sst1[2].integer <<
+ std::endl;
+ rtdata[0].field1_int[0]++;
+ rtdata[0].field1_int[1]++;
+ rtdata[1].field1_int[0]++;
+ rtdata[2].field1_int[1]++;
+ rtdata[0].field3_double += 1.;
+ rtdata[1].field3_double += 1.;
+ rtdata[0].field4_sst1[0].integer += 1;
+ rtdata[0].field4_sst1[1].integer += 1;
+ rtdata[0].field4_sst1[2].integer += 1;
+ rtdata[1].field4_sst1[0].integer += 1;
+ rtdata[1].field4_sst1[1].integer += 1;
+ rtdata[1].field4_sst1[2].integer += 1;
+ std::cout << "Sending pong" << std::endl;
+ PongPort().pong(rtdata).send();
}
-void Capsule_Ponger::actionchain_____top__initial__ActionChain3( const UMLRTMessage & msg )
+void Capsule_Ponger::actionchain_____top__initial__ActionChain3( const UMLRTInMessage & msg )
{
transitionaction_____top__initial__ActionChain3__onInit( msg );
}
-void Capsule_Ponger::actionchain_____top__onBound__ActionChain6( const UMLRTMessage & msg )
+void Capsule_Ponger::actionchain_____top__onBound__ActionChain6( const UMLRTInMessage & msg )
{
transitionaction_____top__onBound__ActionChain6__onBound( msg );
}
-void Capsule_Ponger::actionchain_____top__onPing__ActionChain5( const UMLRTMessage & msg )
+void Capsule_Ponger::actionchain_____top__onPing__ActionChain5( const UMLRTInMessage & msg )
{
transitionaction_____top__onPing__ActionChain5__onPing( msg );
}
-Capsule_Ponger::State Capsule_Ponger::state_____top__Running( const UMLRTMessage & msg )
+Capsule_Ponger::State Capsule_Ponger::state_____top__Running( const UMLRTInMessage & msg )
{
switch( msg.destPort->role()->id )
{
@@ -137,6 +157,7 @@
actionchain_____top__onBound__ActionChain6( msg );
return top__Running;
case PingPongProtocol::signal_ping:
+ msg.decodeInit(RTType_DataType1); // Assume this is the place where parameter types are known.
actionchain_____top__onPing__ActionChain5( msg );
return top__Running;
}
diff --git a/rts/test/rts-pingpong/Ponger.hh b/rts/test/rts-pingpong/Ponger.hh
index 3d165d3..3d9f4a4 100644
--- a/rts/test/rts-pingpong/Ponger.hh
+++ b/rts/test/rts-pingpong/Ponger.hh
@@ -5,7 +5,7 @@
#include "PingPongProtocol.hh"
#include "umlrtcapsule.hh"
#include "umlrtcapsuleclass.hh"
-#include "umlrtmessage.hh"
+#include "umlrtinmessage.hh"
struct UMLRTCommsPort;
struct UMLRTSlot;
@@ -31,8 +31,8 @@
};
virtual void bindPort( bool isBorder, int portId, int index );
virtual void unbindPort( bool isBorder, int portId, int index );
- virtual void inject( const UMLRTMessage & msg );
- virtual void initialize( const UMLRTMessage & msg );
+ virtual void inject( const UMLRTInMessage & msg );
+ virtual void initialize( const UMLRTInMessage & msg );
private:
enum State
{
@@ -40,13 +40,13 @@
SPECIAL_INTERNAL_STATE_UNVISITED
};
State currentState;
- void transitionaction_____top__initial__ActionChain3__onInit( const UMLRTMessage & msg );
- void transitionaction_____top__onBound__ActionChain6__onBound( const UMLRTMessage & msg );
- void transitionaction_____top__onPing__ActionChain5__onPing( const UMLRTMessage & msg );
- void actionchain_____top__initial__ActionChain3( const UMLRTMessage & msg );
- void actionchain_____top__onBound__ActionChain6( const UMLRTMessage & msg );
- void actionchain_____top__onPing__ActionChain5( const UMLRTMessage & msg );
- State state_____top__Running( const UMLRTMessage & msg );
+ void transitionaction_____top__initial__ActionChain3__onInit( const UMLRTInMessage & msg );
+ void transitionaction_____top__onBound__ActionChain6__onBound( const UMLRTInMessage & msg );
+ void transitionaction_____top__onPing__ActionChain5__onPing( const UMLRTInMessage & msg );
+ void actionchain_____top__initial__ActionChain3( const UMLRTInMessage & msg );
+ void actionchain_____top__onBound__ActionChain6( const UMLRTInMessage & msg );
+ void actionchain_____top__onPing__ActionChain5( const UMLRTInMessage & msg );
+ State state_____top__Running( const UMLRTInMessage & msg );
};
extern const UMLRTCapsuleClass Ponger;
diff --git a/rts/test/rts-pingpong/Top.cc b/rts/test/rts-pingpong/Top.cc
index 4c24490..59161fe 100644
--- a/rts/test/rts-pingpong/Top.cc
+++ b/rts/test/rts-pingpong/Top.cc
@@ -10,7 +10,7 @@
#include "umlrtcommsportfarend.hh"
#include "umlrtcommsportrole.hh"
#include "umlrtframeservice.hh"
-#include "umlrtmessage.hh"
+#include "umlrtinmessage.hh"
#include "umlrtslot.hh"
#include <cstddef>
class UMLRTRtsInterface;
@@ -73,7 +73,7 @@
}
}
-void Capsule_Top::inject( const UMLRTMessage & msg )
+void Capsule_Top::inject( const UMLRTInMessage & msg )
{
switch( currentState )
{
@@ -83,7 +83,7 @@
}
}
-void Capsule_Top::initialize( const UMLRTMessage & msg )
+void Capsule_Top::initialize( const UMLRTInMessage & msg )
{
actionchain_____top__Transition2__ActionChain3( msg );
currentState = top__State1;
@@ -91,7 +91,7 @@
-void Capsule_Top::transitionaction_____top__Transition2__ActionChain3__onInit( const UMLRTMessage & msg )
+void Capsule_Top::transitionaction_____top__Transition2__ActionChain3__onInit( const UMLRTInMessage & msg )
{
void * rtdata = *(void * *)msg.signal.getPayload();
std::cout << "Top initialised!\n";
@@ -99,16 +99,16 @@
UMLRTCapsuleId pongerId = FramePort().incarnate( ponger(), Ponger );
if( ! pongerId.isValid() )
context()->perror("ponger incarnate failed.");
- printf( "incarnated ponger valid:%d @%p\n",
- pongerId.isValid(), pongerId.getCapsule() );
+ printf( "incarnated ponger valid:%d @%p %s\n",
+ pongerId.isValid(), pongerId.getCapsule(), pongerId.getCapsule()->getName());
}
-void Capsule_Top::actionchain_____top__Transition2__ActionChain3( const UMLRTMessage & msg )
+void Capsule_Top::actionchain_____top__Transition2__ActionChain3( const UMLRTInMessage & msg )
{
transitionaction_____top__Transition2__ActionChain3__onInit( msg );
}
-Capsule_Top::State Capsule_Top::state_____top__State1( const UMLRTMessage & msg )
+Capsule_Top::State Capsule_Top::state_____top__State1( const UMLRTInMessage & msg )
{
switch( msg.destPort->role()->id )
{
diff --git a/rts/test/rts-pingpong/Top.hh b/rts/test/rts-pingpong/Top.hh
index 407f314..dc7cf75 100644
--- a/rts/test/rts-pingpong/Top.hh
+++ b/rts/test/rts-pingpong/Top.hh
@@ -5,7 +5,7 @@
#include "umlrtcapsule.hh"
#include "umlrtcapsuleclass.hh"
#include "umlrtframeprotocol.hh"
-#include "umlrtmessage.hh"
+#include "umlrtinmessage.hh"
struct UMLRTCapsulePart;
struct UMLRTCommsPort;
struct UMLRTSlot;
@@ -36,8 +36,8 @@
};
virtual void bindPort( bool isBorder, int portId, int index );
virtual void unbindPort( bool isBorder, int portId, int index );
- virtual void inject( const UMLRTMessage & msg );
- virtual void initialize( const UMLRTMessage & msg );
+ virtual void inject( const UMLRTInMessage & msg );
+ virtual void initialize( const UMLRTInMessage & msg );
private:
enum State
{
@@ -45,9 +45,9 @@
SPECIAL_INTERNAL_STATE_UNVISITED
};
State currentState;
- void transitionaction_____top__Transition2__ActionChain3__onInit( const UMLRTMessage & msg );
- void actionchain_____top__Transition2__ActionChain3( const UMLRTMessage & msg );
- State state_____top__State1( const UMLRTMessage & msg );
+ void transitionaction_____top__Transition2__ActionChain3__onInit( const UMLRTInMessage & msg );
+ void actionchain_____top__Transition2__ActionChain3( const UMLRTInMessage & msg );
+ State state_____top__State1( const UMLRTInMessage & msg );
};
extern const UMLRTCapsuleClass Top;
diff --git a/rts/umlrt/umlrtcontroller.cc b/rts/umlrt/umlrtcontroller.cc
index 55716d8..abc2a9e 100644
--- a/rts/umlrt/umlrtcontroller.cc
+++ b/rts/umlrt/umlrtcontroller.cc
@@ -24,7 +24,7 @@
#include "umlrtcommsportrole.hh"
#include "umlrtcontrollercommand.hh"
#include "umlrtframeservice.hh"
-#include "umlrtmessage.hh"
+#include "umlrtinmessage.hh"
#include "umlrtobjectclass.hh"
#include "umlrtprotocol.hh"
#include "umlrttimer.hh"
@@ -431,7 +431,7 @@
capsuleQueue.moveAll(incomingQueue);
// Inject all available messages, highest priority msgs first.
- UMLRTMessage * msg;
+ UMLRTInMessage * msg;
while (!abort && (msg = capsuleQueue.dequeueHighestPriority()) != NULL)
{
if (msg->isCommand)
@@ -460,7 +460,7 @@
base::debugLogData( BD_SIGNALDATA, msg->signal.getPayload(), msg->signal.getPayloadSize());
// Inject the signal into the capsule.
- msg->destPort->slot->capsule->inject((UMLRTMessage)*msg);
+ msg->destPort->slot->capsule->inject((UMLRTInMessage)*msg);
}
}
// Put the message back in the pool (handles signal allocation also).
@@ -497,7 +497,7 @@
FATAL("could not allocate memory for serialized data.");
}
// Encode the data.
- type->encode(type, userData, (*serializedDataP));
+ type->encode(type, userData, (*serializedDataP), 0);
}
// The controller frees the serialized data buffer after it's been copied to the initialize message.
}
@@ -701,7 +701,7 @@
{
const char * farEndSlotName = "(none)";
const char * farEndPortName = "(none)";
- const char * farEndSlotNoInstance = "(no instance)";
+ const char * farEndSlotClass = "(no instance)";
size_t farEndIndex = 0;
if (port->farEnds[j].port != NULL)
{
@@ -710,11 +710,11 @@
farEndIndex = port->farEnds[j].farEndIndex;
if (port->farEnds[j].port->slot->capsule != NULL)
{
- farEndSlotNoInstance = "";
+ farEndSlotClass = port->farEnds[j].port->slot->capsule->getClass()->name;
}
}
BDEBUG(BD_MODEL, " farEnd[%u] : -> { slot %s, port %s[%u] %s}\n",
- j, farEndSlotName, farEndPortName, farEndIndex, farEndSlotNoInstance );
+ j, farEndSlotName, farEndPortName, farEndIndex, farEndSlotClass );
}
debugOutputModelPortDeferQueue(port);
}
diff --git a/rts/umlrt/umlrtframeservice.cc b/rts/umlrt/umlrtframeservice.cc
index d43ef90..bc2009e 100644
--- a/rts/umlrt/umlrtframeservice.cc
+++ b/rts/umlrt/umlrtframeservice.cc
@@ -54,13 +54,18 @@
size_t * slotBoundCount = new size_t[slotClass->numPortRolesBorder]; // Will hold the number of bound instances on each slot port.
// Each of the bound slot ports have to be bound to a capsule border port.
- for (size_t i = 0; i < slotClass->numPortRolesBorder; ++i)
+ size_t slotPortBoundCount = 0; // Number of ports on the slot that have a bind - need at least this many capsule border ports.
+ for (size_t slot_i = 0; slot_i < slotClass->numPortRolesBorder; ++slot_i)
{
// Set all slotToBorderMap entries to 'capsule border port not mapped to this slot'.
- slotToBorderMap[i] = -1;
+ slotToBorderMap[slot_i] = -1;
- // The number of bound instances on each slot port are remembered as each is visited.
- slotBoundCount[i] = 0;
+ // Remember how many port instances were bound on the slot port.
+ if ((slotBoundCount[slot_i] = bindPortsCountBound( &slot->ports[slot_i])) > 0)
+ {
+ // Must have at least one capsule border port to accommodate every bound slot port. Checked below.
+ ++slotPortBoundCount;
+ }
}
// Initialize 'newBorderPorts' - the new border ports for the capsule if binding succeeds.
for (size_t i = 0; i < requestedClass->numPortRolesBorder; ++i)
@@ -86,20 +91,24 @@
size_t border_i = 0; // Port index on requesting class. We're searching the capsule's border ports for unbound ports to match bound slot ports.
+ // Go through each port on the slot. Quit if we fail to find a match for any bound slot port. Do the actual binding after we've proven the capsule fits.
bool compatible = true; // Assume compatibility until we fail.
- // Go through each port on the slot. Quit if we fail to find a match for any bound slot port. Do the actual binding after we've proven the capsule fits.
- bool done = false;
-
- for (size_t slot_i = 0; (slot_i < slotClass->numPortRolesBorder) && compatible && !done; ++slot_i)
+ // Before we start checking to see whether the capsule's border ports fit into the slot, we perform the trivial check
+ // of ensuring the capsule has at least as many border ports available as their are slot ports with bindings.
+ // The for-loop before is not entered if the requested class has no border ports, and we have to check this case.
+ // The trivial case of incarnating or importing into a slot with no ports will not enter the for-loop and allow compatibility.
+ if (requestedClass->numPortRolesBorder < slotPortBoundCount)
+ {
+ // Capsule doesn't have enough border ports to satisfy the slot.
+ compatible = false;
+ }
+ for (size_t slot_i = 0; (slot_i < slotClass->numPortRolesBorder) && compatible && (border_i < requestedClass->numPortRolesBorder); ++slot_i)
{
bool match = false;
- // Remember how many port instances were bound on the slot port.
- slotBoundCount[slot_i] = bindPortsCountBound( &slot->ports[slot_i]);
-
// Loop through the remaining requesting capsule border ports looking for a match to slot port slot_i.
- while (!done && !match)
+ while (compatible && !match)
{
// If port-name match.
if (!strcmp(slotClass->portRolesBorder[slot_i].name, requestedClass->portRolesBorder[border_i].name))
@@ -110,21 +119,21 @@
if (strcmp(slotClass->portRolesBorder[slot_i].protocol, requestedClass->portRolesBorder[border_i].protocol))
{
// protocol mismatch.
- done = !0;
+ compatible = false;
BDEBUG(BD_BINDFAIL, "BIND FAIL:%d %d:slot %s (class %s) port %s (protocol %s) has MISMATCHED PROTOCOL with capsule (class %s) (protocol %s).\n",
slot_i, border_i, slot->name, slot->capsuleClass, slotClass->portRolesBorder[slot_i].name, slotClass->portRolesBorder[slot_i].protocol, requestedClass->name, requestedClass->portRolesBorder[border_i].protocol);
}
else if (slotClass->portRolesBorder[slot_i].conjugated != requestedClass->portRolesBorder[border_i].conjugated)
{
// conjugation mismatch.
- done = !0;
+ compatible = false;
BDEBUG(BD_BINDFAIL, "BIND FAIL:%d %d:slot %s port %s (protocol %s) has MISMATCHED CONJUGATION with capsule (class %s)\n",
slot_i, border_i, slot->name, slotClass->portRolesBorder[slot_i].name, slotClass->portRolesBorder[slot_i].protocol, requestedClass->name);
}
else if ((requestedClass->portRolesBorder[border_i].numFarEnd - borderBoundCount) < slotBoundCount[slot_i])
{
// capsule border port unbound instances insufficient for binding
- done = !0;
+ compatible = false;
BDEBUG(BD_BINDFAIL, "BIND FAIL:%d %d:slot %s port %s (protocol %s) BOUND PORTS [%lu] EXCEEDS CAPSULE'S UNBOUND (class %s) port repl unbound instances [%lu].\n",
slot_i, border_i, slot->name, slotClass->portRolesBorder[slot_i].name, slotClass->portRolesBorder[slot_i].protocol, slotBoundCount[slot_i], requestedClass->name,
requestedClass->portRolesBorder[border_i].numFarEnd - borderBoundCount);
@@ -158,7 +167,7 @@
// Advance to next capsule border port - and quit if we've exhausted them.
if (++border_i >= requestedClass->numPortRolesBorder)
{
- done = !0;
+ compatible = false;
}
}
if (!match)
@@ -1491,7 +1500,7 @@
BDEBUG(BD_INSTANTIATE, "initialize capsule %s\n", capsule->getName());
- UMLRTMessage initializeMsg;
+ UMLRTInMessage initializeMsg;
initializeMsg.signal.initialize(sizeSerializedData);
diff --git a/rts/umlrt/umlrtinmessage.cc b/rts/umlrt/umlrtinmessage.cc
new file mode 100644
index 0000000..83fbce0
--- /dev/null
+++ b/rts/umlrt/umlrtinmessage.cc
@@ -0,0 +1,35 @@
+// umlrtinmessage.cc
+
+/*******************************************************************************
+* Copyright (c) 2015 Zeligsoft (2009) Limited and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*******************************************************************************/
+
+#include "umlrtapi.hh"
+#include "umlrtcontroller.hh"
+#include "umlrtinmessage.hh"
+#include "umlrtinsignal.hh"
+#include "umlrtqueue.hh"
+#include "basefatal.hh"
+
+// See umlrtinmessage.hh for documentation.
+
+void UMLRTInMessage::decodeInit ( const UMLRTObject_class * desc_ ) const
+{
+ desc = desc_;
+ decodeInfo = NULL;
+}
+
+void UMLRTInMessage::decode ( void * data, int arraySize ) const
+{
+ ((UMLRTInSignal &)signal).decode(&decodeInfo, desc, data, arraySize);
+}
+
+void UMLRTInMessage::decode ( int ptrIndirection, void * data, int arraySize ) const
+{
+ FATAL("UMLRTInMessage::decode ptrIndirection not supported.");
+}
+
diff --git a/rts/umlrt/umlrtinsignal.cc b/rts/umlrt/umlrtinsignal.cc
index 5142eb3..7376ca3 100644
--- a/rts/umlrt/umlrtinsignal.cc
+++ b/rts/umlrt/umlrtinsignal.cc
@@ -16,7 +16,7 @@
}
-UMLRTInSignal::UMLRTInSignal(const UMLRTInSignal &signal)
+UMLRTInSignal::UMLRTInSignal(const UMLRTInSignal &signal) : UMLRTSignal(signal)
{
}
@@ -33,7 +33,7 @@
}
// See documentation in UMLRTSignal.
-void UMLRTInSignal::decode( void * * decodeInfo, void * data, const UMLRTObject_class * desc, int arraySize ) const
+void UMLRTInSignal::decode( const void * * decodeInfo, const UMLRTObject_class * desc, void * data, int arraySize ) const
{
if (!element)
{
@@ -43,7 +43,7 @@
}
// See documentation in UMLRTSignal.
-void UMLRTInSignal::decode( void * * decodeInfo, int ptrIndirection, void * data, const UMLRTObject_class * desc, int arraySize ) const
+void UMLRTInSignal::decode( const void * * decodeInfo, const UMLRTObject_class * desc, int ptrIndirection, void * data, int arraySize ) const
{
FATAL("encode ptr indirection not supported");
}
diff --git a/rts/umlrt/umlrtlogprotocol.cc b/rts/umlrt/umlrtlogprotocol.cc
index dc9c738..2077372 100644
--- a/rts/umlrt/umlrtlogprotocol.cc
+++ b/rts/umlrt/umlrtlogprotocol.cc
@@ -218,11 +218,11 @@
return nchar;
}
-int UMLRTLogProtocol_baserole::log ( const void * userData, const UMLRTObject_class * type ) const
+int UMLRTLogProtocol_baserole::log ( const void * userData, const UMLRTObject_class * type, int arraySize ) const
{
int nchar;
- nchar = show(userData, type);
+ nchar = show(userData, type, arraySize);
nchar += log("");
return nchar;
@@ -406,14 +406,14 @@
return nchar;
}
-int UMLRTLogProtocol_baserole::show ( const void * userData, const UMLRTObject_class * type ) const
+int UMLRTLogProtocol_baserole::show ( const void * userData, const UMLRTObject_class * type, int arraySize ) const
{
int nchar = 0;
if (ostream != NULL)
{
UMLRTMutex * mutex = takeMutex();
- nchar = UMLRTObject_fprintf(ostream, type, userData);
+ nchar = UMLRTObject_fprintf(ostream, type, userData, 0/*nest*/, arraySize);
giveMutex(mutex);
}
return nchar;
diff --git a/rts/umlrt/umlrtobjectclass.cc b/rts/umlrt/umlrtobjectclass.cc
index 9ed4357..d9e4aa9 100644
--- a/rts/umlrt/umlrtobjectclass.cc
+++ b/rts/umlrt/umlrtobjectclass.cc
@@ -16,12 +16,16 @@
// Type descriptor used for encoding/decoding data of a given type.
// A number of UMLRTType_xxx descriptors are pre-defined by the library.
-// Default initializer - zeros the data and returns a pointer to next byte.
+// Default initializer - zeros the data and returns a pointer to the byte after the initialized data.
void * UMLRTObject_initialize( const UMLRTObject_class * desc, void * data )
{
uint8_t * s = (uint8_t *)data;
+ if (desc->super != NULL)
+ {
+ s = (uint8_t *)desc->super->initialize(desc->super, data); // Moves 's' past base type data.
+ }
if (desc->fields == NULL)
{
memset(s, 0, desc->size);
@@ -29,246 +33,373 @@
}
else
{
- for (size_t i = 0; i < desc->size; ++i)
+ for (int i = 0; i < desc->size; ++i)
{
- desc->fields[i].desc->initialize(desc->fields[i].desc, s + desc->fields[i].offset);
+ const UMLRTObject_class * fldDesc = desc->fields[i].desc;
+ for (int j = 0; j < desc->fields[i].arraySize; ++j)
+ {
+ s = (uint8_t *)fldDesc->initialize(fldDesc, s );
+ }
}
}
return (void *)s;
}
-// Default copy - copies the data and returns a pointer to the byte following the src data.
-// The return value is the byte following the last byte copied to the destination.
+// Default copy - currently is a memory copy of encoded data.
void * UMLRTObject_copy( const UMLRTObject_class * desc, const void * src, void * dst )
{
- uint8_t * s = (uint8_t *)src;
- uint8_t * end_p = (uint8_t *)dst;
- uint8_t * d = (uint8_t *)dst;
-
- if (desc->fields == NULL)
- {
- memcpy(d, s, desc->size);
- end_p += desc->size;
- }
- else
- {
- for (size_t i = 0; i < desc->size; ++i)
- {
- // overwrite end_p here - the return value for the last field is the one that is relevant.
- end_p = (uint8_t *)desc->fields[i].desc->copy(desc->fields[i].desc, s + desc->fields[i].offset, d + desc->fields[i].offset);
- }
- }
- return (void *)end_p;
+ memcpy(dst, src, desc->getSize(desc));
+ return (void *)((uint8_t *)dst + desc->getSize(desc));
}
-// Default decode is a copy (returns a pointer to the byte after the src data).
-// For now, we'll use the return value of the copy (a value relative to dst) to compute what the return value should be.
size_t UMLRTObject_getSize( const UMLRTObject_class * desc )
{
- size_t size = desc->size;
+ int size = desc->size;
if (desc->fields != NULL)
{
- size = desc->fields[desc->size - 1].offset +
- desc->fields[desc->size - 1].desc->getSize(desc->fields[desc->size - 1].desc);
+ size = 0;
+ for (int i = 0; i < desc->size; ++i)
+ {
+ size += desc->fields[i].desc->getSize(desc->fields[i].desc) * desc->fields[i].arraySize;
+ }
}
return size;
}
-void * UMLRTObject_decode( const UMLRTObject_class * desc, const void * src, void * dst )
+const void * UMLRTObject_decode( const UMLRTObject_class * desc, const void * src, void * dst, int nest )
{
- desc->copy(desc, src, dst); // ignore return value.
-
- return (void *)((uint8_t *)src + UMLRTObject_getSize(desc));
+ if (desc->fields == NULL)
+ {
+ memcpy(dst, src, desc->size);
+ src = (void *)((uint8_t *)src + desc->size);
+ }
+ else
+ {
+ for (int i = 0; i < desc->size; ++i)
+ {
+ const UMLRTObject_class * fldDesc = desc->fields[i].desc;
+ uint8_t * d = (uint8_t *)dst + desc->fields[i].offset;
+ for (int j = 0; j < desc->fields[i].arraySize; ++j)
+ {
+ src = fldDesc->decode(fldDesc, src, d, nest+1);
+ d += desc->fields[i].sizeDecoded;
+ }
+ }
+ }
+ return src;
}
+uint8_t * globalDst = 0; // For debugging - initialized in umlrtsignalelement.cc
+uint8_t * globalSrc = 0;
+
// Default encode is a copy (returns a pointer to the byte after the dst data).
-void * UMLRTObject_encode( const UMLRTObject_class * desc, const void * src, void * dst )
+void * UMLRTObject_encode( const UMLRTObject_class * desc, const void * src, void * dst, int nest )
{
- return desc->copy(desc, src, dst);
+ if (desc->fields == NULL)
+ {
+ for (int n = 0; n < nest; ++n)
+ {
+ BDEBUG(BD_SERIALIZE, " ");
+ }
+ BDEBUG(BD_SERIALIZE, "encode: desc(%s) size(%d) gs %ld gd %ld\n", desc->name, desc->size, (uint8_t *)src - globalSrc, (uint8_t *)dst - globalDst);
+ memcpy(dst, src, desc->size);
+ dst = (void *)((uint8_t *)dst + desc->size);
+ }
+ else
+ {
+ for (int n = 0; n < nest; ++n)
+ {
+ BDEBUG(BD_SERIALIZE, " ");
+ }
+ BDEBUG(BD_SERIALIZE, "encode: desc(%s) nfields(%d)\n", desc->name, desc->size);
+ for (int i = 0; i < desc->size; ++i)
+ {
+ const UMLRTObject_field * fld = &desc->fields[i];
+ uint8_t * s = (uint8_t *)src + fld->offset;
+ for (int j = 0; j < fld->arraySize; ++j)
+ {
+ BDEBUG(BD_SERIALIZE, " ");
+ for (int n = 0; n < nest; ++n)
+ {
+ BDEBUG(BD_SERIALIZE, " ");
+ }
+ BDEBUG(BD_SERIALIZE, "encode: fld[%d]<%s> offset(%d) sizeDecoded(%d) (elem[%d] elemoff %ld gs %ld gd %ld\n",
+ i, fld->name, fld->offset, fld->sizeDecoded, j, s - (uint8_t *)src, s - globalSrc, (uint8_t *)dst - globalDst);
+ dst = fld->desc->encode(fld->desc, s, dst, nest+1);
+ s += fld->sizeDecoded;
+ }
+ }
+ }
+ return dst;
}
// Default destroy does nothing (but returns a pointer to the byte after the data).
void * UMLRTObject_destroy( const UMLRTObject_class * desc, void * data )
{
- uint8_t * s = (uint8_t *)data;
- uint8_t * end_p = (uint8_t *)data;
-
- if (desc->fields != NULL)
- {
- for (size_t i = 0; i < desc->size; ++i)
- {
- end_p = (uint8_t *)desc->fields[i].desc->destroy(desc->fields[i].desc, s + desc->fields[i].offset);
- }
- }
- else
- {
- end_p += desc->size;
- }
- return (void *)end_p;
+ return (void *)((uint8_t *)data + desc->getSize(desc));
}
-int UMLRTObject_fprintf( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+int UMLRTObject_fprintf( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
uint8_t * s = (uint8_t *)data;
- if (desc->fields != NULL)
+ // Debug
+ if (nest == 0)
{
- nchar += fprintf(ostream, "{%s:", desc->name);
-
- for (size_t i = 0; i < desc->size; ++i)
+ globalSrc = s;
+ }
+ for (int ai = 0; ai < arraySize; ++ai)
+ {
+ if (desc->fields != NULL)
{
- nchar += fprintf(ostream, "{%s:", desc->fields[i].name);
- nchar += UMLRTObject_fprintf(ostream, desc->fields[i].desc, s + desc->fields[i].offset);
- nchar += fprintf(ostream, "}");
+ BDEBUG(BD_SERIALIZE, "\n");
+ }
+ for (int n = 0; n < nest; ++n)
+ {
+ BDEBUG(BD_SERIALIZE, " ");
+ }
+ nchar += fprintf(ostream, "{%s", desc->name);
+ if (arraySize > 1)
+ {
+ nchar += fprintf(ostream, "[%d]", ai);
+ }
+ nchar += fprintf(ostream, ":");
+ BDEBUG(BD_SERIALIZE, "\n");
+ if (desc->fields != NULL)
+ {
+ for (int fi = 0; fi < desc->size; ++fi)
+ {
+ const UMLRTObject_field * fld = &desc->fields[fi];
+ BDEBUG(BD_SERIALIZE, " ");
+ for (int n = 0; n < nest; ++n)
+ {
+ BDEBUG(BD_SERIALIZE, " ");
+ }
+ nchar += fprintf(ostream, "{%s:", fld->name);
+ BDEBUG(BD_SERIALIZE, "<desc(%s) arraySize %d elem %d field %d gs %ld>",
+ desc->name, arraySize, ai, fi, s - globalSrc);
+ for (int n = 0; n < nest; ++n)
+ {
+ BDEBUG(BD_SERIALIZE, " ");
+ }
+ nchar += fld->desc->fprintf(ostream, fld->desc, s, nest+1, fld->arraySize);
+ BDEBUG(BD_SERIALIZE, " ");
+ for (int n = 0; n < nest; ++n)
+ {
+ BDEBUG(BD_SERIALIZE, " ");
+ }
+ nchar += fprintf(ostream, "}");
+ BDEBUG(BD_SERIALIZE, "\n");
+ s += fld->desc->getSize(fld->desc) * fld->arraySize;
+ }
+ }
+ else if ((desc->fprintf != NULL) && (desc->fprintf != UMLRTObject_fprintf))
+ {
+ // Don't allow a recursive call with the same parameters.
+ nchar += desc->fprintf(ostream, desc, data, nest+1, arraySize);
+ }
+ else
+ {
+ nchar += fprintf(ostream, "(unable to print)"); // Either no fprintf defined or malformed descriptor.
+ BDEBUG(BD_SERIALIZE, "\n");
+ }
+ for (int n = 0; n < nest; ++n)
+ {
+ BDEBUG(BD_SERIALIZE, " ");
}
nchar += fprintf(ostream, "}");
- }
- else if (desc->fprintf != 0)
- {
- nchar += desc->fprintf(ostream, desc, data);
- }
- else
- {
- nchar += fprintf(ostream, "{%s: (unable to print)}", desc->name);
+ BDEBUG(BD_SERIALIZE, "\n");
}
return nchar;
}
-int UMLRTObject_fprintf_bool( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_bool( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
bool b;
- desc->copy(desc, data, &b);
- nchar += fprintf(ostream, "{bool %s}", b ? "true" : "false");
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(b)), &b);
+ nchar += fprintf(ostream, "{bool %s}", b ? "true" : "false");
+ }
return nchar;
}
-int UMLRTObject_fprintf_char( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_char( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
- char c;
- desc->copy(desc, data, &c);
- nchar += fprintf(ostream, "{char %c}", c);
+ nchar += fprintf(ostream, "{char ");
+ for (int i = 0; i < arraySize; ++i)
+ {
+ nchar += fprintf(ostream, "0x%02X ", *((char*)data + i));
+ }
+ nchar += fprintf(ostream, " '");
+ for (int i = 0; i < arraySize; ++i)
+ {
+ char c = *((char*)data + i);
+ nchar += fprintf(ostream, "%c", (c > 0x1F) && (c < 0x7F) ? c : '.');
+ }
+ nchar += fprintf(ostream, "'}");
return nchar;
}
-int UMLRTObject_fprintf_double( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_double( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
double d;
- desc->copy(desc, data, &d);
- nchar += fprintf(ostream, "{double %f}", d);
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(d)), &d);
+ nchar += fprintf(ostream, "{double %f}", d);
+ }
return nchar;
}
-int UMLRTObject_fprintf_float( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_float( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
float f;
- desc->copy(desc, data, &f);
- nchar += fprintf(ostream, "{float %f}", f);
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(f)), &f);
+ nchar += fprintf(ostream, "{float %f}", f);
+ }
return nchar;
}
-int UMLRTObject_fprintf_int( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_int( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
- int i;
- desc->copy(desc, data, &i);
- nchar += fprintf(ostream, "{int %d}", i);
+ int iv;
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(iv)), &iv);
+ nchar += fprintf(ostream, "{int %d}", iv);
+ }
return nchar;
}
-int UMLRTObject_fprintf_long( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_long( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
long l;
- desc->copy(desc, data, &l);
- nchar += fprintf(ostream, "{long %ld}", l);
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(l)), &l);
+ nchar += fprintf(ostream, "{long %ld}", l);
+ }
return nchar;
}
-int UMLRTObject_fprintf_longdouble( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_longdouble( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
- long double l;
- desc->copy(desc, data, &l);
- nchar += fprintf(ostream, "{longdouble %Lf}", l);
+ long double ld;
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(ld)), &ld);
+ nchar += fprintf(ostream, "{longdouble %Lf}", ld);
+ }
return nchar;
}
-int UMLRTObject_fprintf_longlong( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_longlong( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
long long ll;
- desc->copy(desc, data, &ll);
- nchar += fprintf(ostream, "{longlong %lld}", ll);
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(ll)), &ll);
+ nchar += fprintf(ostream, "{longlong %lld}", ll);
+ }
return nchar;
}
-int UMLRTObject_fprintf_ptr( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_ptr( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
void * p;
- desc->copy(desc, data, &p);
- // Pointer de-referencing tracked by Bug 97.
- nchar += fprintf(ostream, "{ptr %p}", p);
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(p)), &p);
+ // Pointer de-referencing tracked by Bug 97.
+ nchar += fprintf(ostream, "{ptr %p}", p);
+ }
return nchar;
}
-int UMLRTObject_fprintf_short( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_short( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
short sh;
- desc->copy(desc, data, &sh);
- nchar += fprintf(ostream, "{short %d}", sh);
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(sh)), &sh);
+ nchar += fprintf(ostream, "{short %d}", sh);
+ }
return nchar;
}
-int UMLRTObject_fprintf_uchar( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_uchar( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
- unsigned char c;
- desc->copy(desc, data, &c);
- nchar += fprintf(ostream, "{char %u}", c);
+ unsigned char uc;
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i), &uc);
+ nchar += fprintf(ostream, "{uchar %u}", uc);
+ }
return nchar;
}
-int UMLRTObject_fprintf_uint( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_uint( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
- unsigned int i;
- desc->copy(desc, data, &i);
- nchar += fprintf(ostream, "{uint %u}", i);
+ unsigned int ui;
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(ui)), &ui);
+ nchar += fprintf(ostream, "{uint %u}", ui);
+ }
return nchar;
}
-int UMLRTObject_fprintf_ulong( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_ulong( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
- unsigned long l;
- desc->copy(desc, data, &l);
- nchar += fprintf(ostream, "{ulong %lu}", l);
+ unsigned long ul;
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(ul)), &ul);
+ nchar += fprintf(ostream, "{ulong %lu}", ul);
+ }
return nchar;
}
-int UMLRTObject_fprintf_ulonglong( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_ulonglong( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
unsigned long long ll;
- desc->copy(desc, data, &ll);
- nchar += fprintf(ostream, "{ulonglong %llu}", ll);
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(ll)), &ll);
+ desc->copy(desc, data, &ll);
+ nchar += fprintf(ostream, "{ulonglong %llu}", ll);
+ }
return nchar;
}
-int UMLRTObject_fprintf_ushort( FILE *ostream, const UMLRTObject_class * desc, const void * data )
+static int UMLRTObject_fprintf_ushort( FILE *ostream, const UMLRTObject_class * desc, const void * data, int nest, int arraySize )
{
int nchar = 0;
- unsigned short sh;
- desc->copy(desc, data, &sh);
- nchar += fprintf(ostream, "{ushort %u}", sh);
+ unsigned short ush;
+ for (int i = 0; i < arraySize; ++i)
+ {
+ desc->copy(desc, ((uint8_t*)data + i*sizeof(ush)), &ush);
+ nchar += fprintf(ostream, "{ushort %u}", ush);
+ }
return nchar;
}
@@ -286,6 +417,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(bool),
+ sizeof(bool),
NULL // fields
};
@@ -304,6 +436,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(char),
+ sizeof(char),
NULL, // fields
};
@@ -321,6 +454,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(double),
+ sizeof(double),
NULL, // fields
};
@@ -338,6 +472,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(float),
+ sizeof(float),
NULL, // fields
};
@@ -355,6 +490,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(int),
+ sizeof(int),
NULL, // fields
};
@@ -372,6 +508,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(long),
+ sizeof(long),
NULL, // fields
};
@@ -389,6 +526,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(long double),
+ sizeof(long double),
NULL, // fields
};
@@ -406,6 +544,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(long long),
+ sizeof(long long),
NULL, // fields
};
@@ -423,6 +562,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(void *),
+ sizeof(void *),
NULL // fields
};
@@ -440,6 +580,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(short),
+ sizeof(short),
NULL, // fields
};
@@ -457,6 +598,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(unsigned char),
+ sizeof(unsigned char),
NULL, // fields
};
@@ -474,6 +616,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(unsigned int),
+ sizeof(unsigned int),
NULL, // fields
};
@@ -491,6 +634,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(unsigned long),
+ sizeof(unsigned long),
NULL, // fields
};
@@ -508,6 +652,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(unsigned long long),
+ sizeof(unsigned long long),
NULL, // fields
};
@@ -525,6 +670,7 @@
UMLRTOBJECTCLASS_DEFAULT_VERSION, // version
UMLRTOBJECTCLASS_DEFAULT_BACKWARDS, // backwards
sizeof(unsigned short),
+ sizeof(unsigned short),
NULL, // fields
};
diff --git a/rts/umlrt/umlrtoutsignal.cc b/rts/umlrt/umlrtoutsignal.cc
index 9a25c22..86f3afa 100644
--- a/rts/umlrt/umlrtoutsignal.cc
+++ b/rts/umlrt/umlrtoutsignal.cc
@@ -1,5 +1,13 @@
// umlrtoutsignal.cc
+/*******************************************************************************
+* Copyright (c) 2015 Zeligsoft (2009) Limited and others.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*******************************************************************************/
+
#include "umlrtcommsport.hh"
#include "umlrtcommsportfarend.hh"
#include "umlrtcontroller.hh"
@@ -10,20 +18,12 @@
#include "basedebugtype.hh"
#include "basedebug.hh"
-/*******************************************************************************
-* Copyright (c) 2015 Zeligsoft (2009) Limited and others.
-* All rights reserved. This program and the accompanying materials
-* are made available under the terms of the Eclipse Public License v1.0
-* which accompanies this distribution, and is available at
-* http://www.eclipse.org/legal/epl-v10.html
-*******************************************************************************/
-
UMLRTOutSignal::UMLRTOutSignal()
{
}
-UMLRTOutSignal::UMLRTOutSignal(const UMLRTOutSignal &signal)
+UMLRTOutSignal::UMLRTOutSignal(const UMLRTOutSignal &signal) : UMLRTSignal(signal)
{
}
@@ -39,9 +39,7 @@
}
-
-// See documentation in UMLRTSignal.
-void UMLRTOutSignal::encode( const void * data, const UMLRTObject_class * desc, int arraySize )
+void UMLRTOutSignal::encode( const UMLRTObject_class * desc, const void * data, int arraySize )
{
if (!element)
{
@@ -50,8 +48,7 @@
element->encode(desc, data, arraySize);
}
-// See documentation in UMLRTSignal.
-void UMLRTOutSignal::encode( int ptrIndirection, void * data, const UMLRTObject_class * desc, int arraySize )
+void UMLRTOutSignal::encode( const UMLRTObject_class * desc, int ptrIndirection, void * data, int arraySize )
{
FATAL("encode ptr indirection not supported");
}
diff --git a/rts/umlrt/umlrtprioritymessagequeue.cc b/rts/umlrt/umlrtprioritymessagequeue.cc
index f49ee11..f543281 100644
--- a/rts/umlrt/umlrtprioritymessagequeue.cc
+++ b/rts/umlrt/umlrtprioritymessagequeue.cc
@@ -116,14 +116,14 @@
// Get the highest priority message from the collection of queues.
-UMLRTMessage * UMLRTPriorityMessageQueue::dequeueHighestPriority()
+UMLRTInMessage * UMLRTPriorityMessageQueue::dequeueHighestPriority()
{
- UMLRTMessage * msg = 0;
+ UMLRTInMessage * msg = 0;
for (UMLRTSignalElement::Priority priority = (UMLRTSignalElement::PRIORITY_MAX-1);
(priority >= UMLRTSignalElement::PRIORITY_BACKGROUND) && (priority < (UMLRTSignalElement::PRIORITY_MAX)) && !msg; --priority)
{
- msg = (UMLRTMessage *)queue[priority].dequeue();
+ msg = (UMLRTInMessage *)queue[priority].dequeue();
}
if (msg != NULL)
diff --git a/rts/umlrt/umlrtsignalelement.cc b/rts/umlrt/umlrtsignalelement.cc
index 3b4f879..96220bc 100644
--- a/rts/umlrt/umlrtsignalelement.cc
+++ b/rts/umlrt/umlrtsignalelement.cc
@@ -167,14 +167,21 @@
}
}
+extern uint8_t * globalSrc;
+extern uint8_t * globalDst;
+
// See documentation in UMLRTSignal.
void UMLRTSignalElement::encode( const UMLRTObject_class * desc, const void * data, int arraySize )
{
// encodeInfo is intitialized to be 'payload' when the signal is initialized.
// It is moved forward during successive #encode calls.
+ globalSrc = (uint8_t *)data;
+ globalDst = (uint8_t *)encodeInfo;
+
for (int i = 0; i < arraySize; ++i)
{
- encodeInfo = desc->encode(desc, data, encodeInfo);
+ encodeInfo = desc->encode(desc, data, encodeInfo, 0);
+ data = ((uint8_t*)data + desc->sizeDecoded);
}
}
@@ -184,25 +191,25 @@
FATAL("encode ptr indirection not implemented.");
}
-// See documentation in UMLRTSignal.
-void UMLRTSignalElement::decode( void * * decodeInfo, const UMLRTObject_class * desc, void * data, int arraySize )
+void UMLRTSignalElement::decode( const void * * decodeInfo, const UMLRTObject_class * desc, void * data, int arraySize )
{
// decodeInfo is initialized to be NULL by a decoder - it is owned by the decoder and not by
// the signal (contrary to the encodeInfo, which can be owned by the signal, since there is always
// only ever one encoder).
- if (!(*decodeInfo))
+ if ((*decodeInfo) == NULL)
{
*decodeInfo = payload;
}
for (int i = 0; i < arraySize; ++i)
{
- *decodeInfo = desc->decode(desc, *decodeInfo, data);
+ *decodeInfo = desc->decode(desc, *decodeInfo, data, /*nest*/0);
+ data = (void *)((uint8_t*)data + desc->sizeDecoded);
}
}
// See documentation in UMLRTSignal.
-void UMLRTSignalElement::decode( void * * decodeInfo, const UMLRTObject_class * desc, int ptrIndirection, void * data, int arraySize )
+void UMLRTSignalElement::decode( const void * * decodeInfo, const UMLRTObject_class * desc, int ptrIndirection, void * data, int arraySize )
{
FATAL("decode ptr indirection not implemented.");
}
diff --git a/rts/umlrt/umlrttimerprotocol.cc b/rts/umlrt/umlrttimerprotocol.cc
index 6c7e293..f66df76 100644
--- a/rts/umlrt/umlrttimerprotocol.cc
+++ b/rts/umlrt/umlrttimerprotocol.cc
@@ -76,7 +76,7 @@
if (userData)
{
- timer->signal.encode(userData, type);
+ timer->signal.encode(type, userData);
}
}
return UMLRTTimerId(timer);