[Avida-SVN] r2961 - development/source/main
mmcgill at myxo.css.msu.edu
mmcgill at myxo.css.msu.edu
Fri Nov 21 13:57:42 PST 2008
Author: mmcgill
Date: 2008-11-21 16:57:42 -0500 (Fri, 21 Nov 2008)
New Revision: 2961
Modified:
development/source/main/cAvidaConfig.h
development/source/main/cOrganism.cc
development/source/main/cOrganism.h
Log:
Added configuration variables offering more control over
the behavior of message passing.
ORGANISMS_REMEMBER_MESSAGES
* Setting to 1 (the default) preserves the current behavior; the "sent" and
"received" message lists in each organism track every message sent or received
in that organism's lifetime.
* Setting to 0 has the effect that (a) no messages are stored in "sent", and
"received" stores only those messages that have not yet been retrieved; retrieved
messages are discarded.
MESSAGE_QUEUE_SIZE
* Setting to -1 (the default) preserves the current behavior; an unbounded
number of messages can queue up in an organism's "received" message list.
* Setting to a non-negative value caps the number of unretrieved messages
that can queue up in an organism's "receives" list. When one organism
sends a message to another organism whose message queue is full, the
behavior is determined by the variable:
MESSAGE_QUEUE_BEHAVIOR_WHEN_FULL
* Setting to 0 (the default) causes incoming messages to be dropped when
an organism's message queue is full.
* Setting to 1 causes the oldest unretrieved message to be dropped and the
incoming message placed at the end of the message queue, when a message
is received and the message queue is full.
Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h 2008-11-21 21:45:48 UTC (rev 2960)
+++ development/source/main/cAvidaConfig.h 2008-11-21 21:57:42 UTC (rev 2961)
@@ -469,6 +469,9 @@
CONFIG_ADD_GROUP(ORGANISM_MESSAGING_GROUP, "Organism Message-Based Communication");
CONFIG_ADD_VAR(MESSAGE_TYPE, int, 0, "Messaging Style. 0=Receiver Facing, 1=Broadcast");
CONFIG_ADD_VAR(MESSAGE_BCAST_RADIUS, int, 1, "Broadcast message radius (cells)");
+ CONFIG_ADD_VAR(ORGANISMS_REMEMBER_MESSAGES, bool, 1, "Does an organism remember all messages it has sent or received? 0=false, 1=true (default)");
+ CONFIG_ADD_VAR(MESSAGE_QUEUE_SIZE, int, -1, "Maximum number of unretrieved messages an organism can store (-1 for no limit is the default)");
+ CONFIG_ADD_VAR(MESSAGE_QUEUE_BEHAVIOR_WHEN_FULL, int, 0, "0 = Drop incoming message (default), 1 = Drop oldest unretrieved message");
CONFIG_ADD_GROUP(BUY_SELL_GROUP, "Buying and Selling Parameters");
CONFIG_ADD_VAR(SAVE_RECEIVED, bool, 0, "Enable storage of all inputs bought from other orgs");
Modified: development/source/main/cOrganism.cc
===================================================================
--- development/source/main/cOrganism.cc 2008-11-21 21:45:48 UTC (rev 2960)
+++ development/source/main/cOrganism.cc 2008-11-21 21:57:42 UTC (rev 2961)
@@ -711,16 +711,19 @@
m_interface->GetDeme()->IncMessageSent();
// If we're able to succesfully send the message...
if(m_interface->SendMessage(msg)) {
- // save it...
- m_msg->sent.push_back(msg);
+ // If we're remembering messages
+ if (m_world->GetConfig().ORGANISMS_REMEMBER_MESSAGES.Get()) {
+ // save it...
+ m_msg->sent.push_back(msg);
+ // and set the receiver-pointer of this message to NULL. We don't want to
+ // walk this list later thinking that the receivers are still around.
+ m_msg->sent.back().SetReceiver(0);
+ }
// stat-tracking...
m_world->GetStats().SentMessage(msg);
m_interface->GetDeme()->MessageSuccessfullySent();
// check to see if we've performed any tasks...
DoOutput(ctx);
- // and set the receiver-pointer of this message to NULL. We don't want to
- // walk this list later thinking that the receivers are still around.
- m_msg->sent.back().SetReceiver(0);
return true;
}
m_interface->GetDeme()->messageSendFailed();
@@ -736,12 +739,14 @@
// If we're able to succesfully send the message...
if(m_interface->BroadcastMessage(msg)) {
- // save it...
- m_msg->sent.push_back(msg);
- // and set the receiver-pointer of this message to NULL. We don't want to
- // walk this list later thinking that the receivers are still around.
- // Also, a broadcast message may have >1 receiver
- m_msg->sent.back().SetReceiver(0);
+ // If we're remembering messages
+ if (m_world->GetConfig().ORGANISMS_REMEMBER_MESSAGES.Get()) {
+ // save it...
+ m_msg->sent.push_back(msg);
+ // and set the receiver-pointer of this message to NULL. We don't want to
+ // walk this list later thinking that the receivers are still around.
+ m_msg->sent.back().SetReceiver(0);
+ }
// stat-tracking... NOTE: this has receiver not specified, so may be a problem for predicates
m_world->GetStats().SentMessage(msg);
// check to see if we've performed any tasks...NOTE: this has receiver not specified, so may be a problem for tasks that care
@@ -756,8 +761,42 @@
void cOrganism::ReceiveMessage(cOrgMessage& msg)
{
InitMessaging();
- msg.SetReceiver(this);
- m_msg->received.push_back(msg);
+ msg.SetReceiver(this);
+ int msg_queue_size = m_world->GetConfig().MESSAGE_QUEUE_SIZE.Get();
+ // are message queues unbounded?
+ if (msg_queue_size >= 0) {
+ // if the message queue size is zero, the incoming message is always dropped
+ if (msg_queue_size == 0) {
+ return;
+ }
+
+ // how many messages in the queue?
+ int num_unretrieved_msgs = m_msg->received.size()-m_msg->retrieve_index;
+ if (num_unretrieved_msgs == msg_queue_size) {
+ // look up message queue behavior
+ int bhvr = m_world->GetConfig().MESSAGE_QUEUE_BEHAVIOR_WHEN_FULL.Get();
+ if (bhvr == 0) {
+ // drop incoming message
+ return;
+ } else if (bhvr == 1 ) {
+ // drop the oldest unretrieved message
+ m_msg->received.erase(m_msg->received.begin()+m_msg->retrieve_index);
+ } else {
+ assert(false);
+ cerr << "ERROR: MESSAGE_QUEUE_BEHAVIOR_WHEN_FULL was set to " << bhvr << "," << endl;
+ cerr << "legal values are:" << endl;
+ cerr << "\t0: drop incoming message if message queue is full (default)" << endl;
+ cerr << "\t1: drop oldest unretrieved message if message queue is full" << endl;
+
+ // TODO: is there a more gracefull way to fail?
+ exit(1);
+ }
+ } // end if message queue is full
+ m_msg->received.push_back(msg);
+ } else {
+ // unbounded message queues
+ m_msg->received.push_back(msg);
+ }
}
@@ -765,11 +804,23 @@
{
InitMessaging();
- if(m_msg->retrieve_index < m_msg->received.size()) {
+ assert(m_msg->retrieve_index <= m_msg->received.size());
+
+ // Return null if no new messages have been received
+ if (m_msg->retrieve_index == m_msg->received.size())
+ return 0;
+
+ if (m_world->GetConfig().ORGANISMS_REMEMBER_MESSAGES.Get()) {
+ // Return the next unretrieved message and incrememt retrieve_index
return &m_msg->received.at(m_msg->retrieve_index++);
+ } else {
+ // Not remembering messages, return the front of the message queue.
+ // Notice that retrieve_index will always equal 0 if
+ // ORGANISMS_REMEMBER_MESSAGES is false.
+ const cOrgMessage* msg = &m_msg->received.front();
+ m_msg->received.pop_front();
+ return msg;
}
-
- return 0;
}
Modified: development/source/main/cOrganism.h
===================================================================
--- development/source/main/cOrganism.h 2008-11-21 21:45:48 UTC (rev 2960)
+++ development/source/main/cOrganism.h 2008-11-21 21:57:42 UTC (rev 2961)
@@ -29,6 +29,7 @@
#include <iostream>
#include <string>
#include <vector>
+#include <deque>
#ifndef cCPUMemory_h
#include "cCPUMemory.h"
@@ -349,7 +350,10 @@
// -------- Messaging support --------
public:
- typedef std::vector<cOrgMessage> message_list_type; //!< Container-type for cOrgMessages.
+ // Use a deque instead of vector for amortized constant-time removal
+ // from the front of the list, to efficiently support message list
+ // size caps
+ typedef std::deque<cOrgMessage> message_list_type; //!< Container-type for cOrgMessages.
//! Called when this organism attempts to send a message.
bool SendMessage(cAvidaContext& ctx, cOrgMessage& msg);
@@ -370,6 +374,7 @@
struct cMessagingSupport
{
cMessagingSupport() : retrieve_index(0) { }
+
message_list_type sent; //!< List of all messages sent by this organism.
message_list_type received; //!< List of all messages received by this organism.
message_list_type::size_type retrieve_index; //!< Index of next message that can be retrieved.
More information about the Avida-cvs
mailing list