# HG changeset patch # User Merten Sach # Date 1331145997 -3600 # Node ID 29d8b41926f0583d82028c3cf5d069fd26e67219 Initial commit - compiles but has still the wrong name diff -r 000000000000 -r 29d8b41926f0 LossyCom.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LossyCom.c Wed Mar 07 19:46:37 2012 +0100 @@ -0,0 +1,101 @@ + +/* + * For a detailed description see header file. + */ + +#include "LossyCom.h" + +#include "VMS_Implementations/VMS_impl/vmalloc.h" + +/* + * Initializes the central exchange structure. + * Allocates memory to fit the number of endpoints. + * Returns NULL if an error occurs. + */ +lossyCom__exchange_t* lossyCom__initialize(uint16_t numEndpoints) +{ + lossyCom__exchange_t* exchange; + + exchange = VMS_WL__malloc(sizeof(lossyCom__exchange_t)); + if(exchange == NULL) + return NULL; + + exchange->triggerCounter = 0; + exchange->numEndpoints = numEndpoints; + exchange->outboxArray = VMS_WL__malloc(sizeof(lossyCom__msg_t)*numEndpoints); + if(exchange->outboxArray == NULL){ + VMS_WL__free(exchange); + return NULL; + } + + return exchange; +} + +void lossyCom__initialize_endpoint(lossyCom__endpoint_t* localEndpoint, + lossyCom__exchange_t* centralExchange, + lossyCom__endpointID_t endpointID, + lossyCom__msgHandler* msgHandler) +{ + localEndpoint->localTriggerCopy = 0; + localEndpoint->endpointID = endpointID; + localEndpoint->centralExchangePtr = centralExchange; + localEndpoint->msgHandler = msgHandler; +} + +void inline lossyCom__broadcastMsg(lossyCom__endpoint_t* localEndpoint, + lossyCom__msgBody_t msg) +{ + lossyCom__sendMsg(localEndpoint, + BROADCAST_ID, + msg); +} + +void inline lossyCom__sendMsg(lossyCom__endpoint_t* localEndpoint, + lossyCom__endpointID_t receiverEndpointID, + lossyCom__msgBody_t msg) +{ + lossyCom__msg_t msgDraft; + uint16_t triggerCopy; + + msgDraft = (0 | msg); + msgDraft |= ((lossyCom__msg_t)receiverEndpointID << ENDPOINT_ID_SHIFT); + + triggerCopy = localEndpoint->centralExchangePtr->triggerCounter +1; + msgDraft |= ((lossyCom__msg_t)triggerCopy << TRIGGER_SHIFT); + + //write msg to central exchange + localEndpoint->centralExchangePtr->outboxArray[localEndpoint->endpointID] = + msgDraft; + + localEndpoint->centralExchangePtr->triggerCounter = triggerCopy; +} + +void inline lossyCom__receiveMsg(lossyCom__endpoint_t* localEndpoint) +{ + uint16_t remoteTriggerCopy; + lossyCom__endpointID_t senderEndpointID; + lossyCom__msg_t msgCopy; + uint16_t msgTrigger; + lossyCom__msgBody_t msgBody; + + senderEndpointID = 0; + remoteTriggerCopy = localEndpoint->centralExchangePtr->triggerCounter; + //new message arrived if trigger counter is higher than the last time read + while(senderEndpointID < localEndpoint->centralExchangePtr->numEndpoints) + { + if(senderEndpointID != localEndpoint->endpointID) + { + msgCopy = localEndpoint->centralExchangePtr->outboxArray[senderEndpointID]; + msgTrigger = 0xFFFF & (msgCopy >> TRIGGER_SHIFT); + if(msgTrigger > localEndpoint->localTriggerCopy && + msgTrigger <= remoteTriggerCopy) + { + msgBody = 0xFFFFFFFF & msgCopy; + (*(localEndpoint->msgHandler))(senderEndpointID, msgBody); + } + } + senderEndpointID++; + } + //save last parsed msg + localEndpoint->localTriggerCopy = remoteTriggerCopy; +} \ No newline at end of file diff -r 000000000000 -r 29d8b41926f0 LossyCom.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LossyCom.h Wed Mar 07 19:46:37 2012 +0100 @@ -0,0 +1,89 @@ +/* + * This describes a best effort communication channel. Mainly designed for + * communication between Core-Controllers, so they can inform each other about + * their status and pass work around. This is to avoid idling cores that occupy + * the Masterlock. + * + * The communication entities poll a central trigger counter that increases when + * there are new messages. However it's not guaranteed that the increase of the + * counter reflects the number of new messages. + * + * The messages consist of a single 64bit word so it can be written in one + * operation and therefore avoiding inconsistent messages. + * + * The messages are handled with a handler function provided by the receiver + * when acquiring the communication endpoint. + * + * The message passing is handled by a central struct that is used w/o any lock. + * It consists of a array messages for the number of communicating entities. The + * number of entities is fixed at initialization. + */ + +#include + + + +/*********************************** + * Type Definitions + ***********************************/ + +#define BROADCAST_ID 65535 +#define ENDPOINT_ID_SHIFT 32 +#define TRIGGER_SHIFT 48 + +/* + * A message consists of the + * 16bit saved trigger value when the message was sent + * 16bit receiver identifier, this is the index of the slot in the array + * 65536 is the broadcast identifier + * 32bit message body, the message format is defined by the endpoints + */ +typedef uint64_t lossyCom__msg_t; +typedef uint32_t lossyCom__msgBody_t; +typedef uint16_t lossyCom__endpointID_t; + +/* + * Message Handler that has two arguments the sender endpoint ID and the Msg + * Example: + * void handler_func(lossyCom__endpointID_t senderID, lossyCom__msgBody_t msg); + */ +typedef void (*lossyCom__msgHandler) (lossyCom__endpointID_t, lossyCom__msgBody_t); + +/* + * Central communication structure. + */ +typedef struct{ + uint16_t triggerCounter; + uint16_t numEndpoints; + lossyCom__msg_t* outboxArray; +}lossyCom__exchange_t; + +/* + * Endpoint data structure. + */ +typedef struct { + uint16_t localTriggerCopy; + lossyCom__endpointID_t endpointID; + lossyCom__exchange_t* centralExchangePtr; + lossyCom__msgHandler* msgHandler; +} lossyCom__endpoint_t; + +/*********************************** + * Function Declarations + ***********************************/ + +lossyCom__exchange_t* lossyCom__initialize(uint16_t numEndpoints); + +void lossyCom__initialize_endpoint(lossyCom__endpoint_t* localEndpoint, + lossyCom__exchange_t* exchange, + lossyCom__endpointID_t endpointID, + lossyCom__msgHandler* msgHandler); + +void lossyCom__broadcastMsg(lossyCom__endpoint_t* localEndpoint, + lossyCom__msgBody_t msg); + +void lossyCom__sendMsg(lossyCom__endpoint_t* localEndpoint, + lossyCom__endpointID_t receiverEndpointID, + lossyCom__msgBody_t msg); + +void lossyCom__receiveMsg(lossyCom__endpoint_t* localEndpoint); \ No newline at end of file