本篇描述QualNet中离散事件仿真的实现细节:事件类型、实现事件的数据结构和类以及用于事件操作的API函数。
1. 事件和消息
在QualNet中,用于表示事件的类称为消息。消息保存有关事件的信息,例如事件的类型和相关的数据。在QualNet的文本中,术语事件和消息经常被交替使用。QualNet中有两种类型的事件:数据包事件和定时器事件。数据包事件被用来仿真层间或节点之间数据包的交换,也用于对同一层不同实体之间的通信进行建模。定时器事件用于发起或取消某项工作,使整个过程在时间线上完美呈现。在本节中,我们将描述Message类和其API函数。
1.1 消息类
~/include/message.h中定义的消息类用于实现事件,数据包和定时器事件都使用消息类。
class Message
{
private:
static const UInt8 SENT = 0x01; // Message is being sent
static const UInt8 FREED = 0x02; // MESSAGE_Free has been called
static const UInt8 DELETED = 0x04; // Deleted using "delete"
UInt8 m_flags;
public:
Message();
Message(const Message& m);
Message(PartitionData *partition,
int layerType,
int protocol,
int eventType,
bool isMT = false);
virtual ~Message();
void operator = (const Message &p);
// 用默认值初始化消息
void initialize(PartitionData* partition);
Message* next;
PartitionData* m_partitionData;
// 以下为仿真相关信息
short layerType; /// Layer which will receive the message
short protocolType; /// Protocol which will receive the message in the layer.
short instanceId; /// Which instance to give message to (for multiple
/// copies of a protocol or application).
short m_radioId; /// which radio this belongs to (if any)
short eventType; /// Message's Event type.
unsigned int naturalOrder; /// used to maintain natural ordering
/// for events at same time & node
char error; /// Does the packet contain errors?
bool mtWasMT; // Messages handed to the worker thread
// can't participate in the message recycling.
// As the partitionData->msgFreeList isn't
// locked.
bool getSent() { return (m_flags & SENT) != 0; }
void setSent(bool v);
bool getFreed() { return (m_flags & FREED) != 0; }
void setFreed(bool v);
bool getDeleted() { return (m_flags & DELETED) != 0; }
void setDeleted(bool v);
bool allowLoose; // used only by the parallel code
NodeId nodeId; // used only by the parallel code
clocktype eventTime; // used only by the parallel code
clocktype eot; // used only by the parallel code
int sourcePartitionId; // used only by the parallel code
// 消息的信息字段
double smallInfoSpace[SMALL_INFO_SPACE_SIZE / sizeof(double)];
// 消息的数据包
int packetSize;
char *packet;
char *payload;
int payloadSize;
int virtualPayloadSize;
// 消息的创建和网络发送时间.
clocktype packetCreationTime;
clocktype pktNetworkSendTime;
bool cancelled;
// 包追踪相关信息.
NodeAddress originatingNodeId;
int sequenceNumber;
int originatingProtocol;
int numberOfHeaders;
int headerProtocols[MAX_HEADERS];
int headerSizes[MAX_HEADERS];
NodeAddress relayNodeAddr;
std::vector<MessageInfoHeader> infoArray;
std::vector<MessageInfoBookKeeping> infoBookKeeping;
// 常用类方法
// 添加和删除虚拟负载
void addVirtualPayload(int size) { virtualPayloadSize += size; }
void removeVirtualPayload(int size)
{
virtualPayloadSize -= size;
ERROR_Assert(virtualPayloadSize >= 0, "invalid virtual payload size");
}
// 返回消息的数据包指针.
char* returnPacket() const { return packet; }
int returnPacketSize() const { return packetSize + virtualPayloadSize; }
int returnActualSize() const { return (isPacked)? actualPktSize : packetSize;}
int returnVirtualSize() const { return virtualPayloadSize; }
void setLayer(int layer, int protocol) {
layerType = layer;
protocolType = protocol;
}
int getLayer() const { return layerType; }
int getProtocol() const { return protocolType; }
void setEvent(int event) { eventType = event; }
int getEvent() const { return eventType; }
void setInstanceId(int instance) { instanceId = ins