[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);