src/Message/MessageFunctions.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // include files
00027 #include "Message/Message.h"
00028 #include "Message/Communicate.h"
00029 #include "Utility/Inform.h"
00030 #include "Utility/IpplInfo.h"
00031 #include "Utility/PAssert.h"
00032 #include "Profile/Profiler.h"
00033 
00034 #ifdef IPPL_USE_STANDARD_HEADERS
00035 #include <new>
00036 #include <memory>
00037 using namespace std;
00038 #else
00039 #include <new.h>
00040 #include <memory.h>
00041 #endif
00042 
00043 #include <stdlib.h>
00044 #include <stddef.h>
00045 
00046 
00048 // destructor: delete all items in this message, as if 'get' had been
00049 // called for all the items
00050 Message::~Message() {
00051   TAU_PROFILE("Message::~Message()", "void (void)", TAU_MESSAGE);
00052 
00053   // remove all unused items
00054   clear();
00055 
00056   // delete the storage in the existing items
00057   int n = MsgItemList.size();
00058   for (int i=0; i < n; ++i)
00059     MsgItemList[i].deleteData();
00060 
00061   // tell the communicate item to cleanup the provided data,
00062   // if necessary
00063   if (comm != 0)
00064     comm->cleanupMessage(commdata);
00065 }
00066 
00067 
00069 // remove the top MsgItem
00070 void Message::deleteMsgItem() {
00071   TAU_PROFILE("Message::deleteMsgItem()", "void (void)", TAU_MESSAGE);
00072 
00073   if (!empty())
00074     numRemoved++;
00075 }
00076 
00077 
00079 // general put routine; called by other cases
00080 // arguments are the item, its element size (in bytes),
00081 // and how many items total to copy
00082 Message& Message::putmsg(void *data, int s, int nelem) {
00083   TAU_PROFILE("Message::putmsg()", "Message (void *, int, int)", TAU_MESSAGE);
00084 
00085   // if this is a scalar, we always copy, and have one element
00086   if (nelem < 1) {
00087     nelem = 1;
00088     DoCopy = true;
00089   }
00090 
00091   // initialize new MsgItem
00092   //Inform dbgmsg("Message::putmsg", INFORM_ALL_NODES);
00093   //dbgmsg << "Putting data " << MsgItemList.size() << " at " << data;
00094   //dbgmsg << " with " << nelem;
00095   //dbgmsg << " elements, totbytes=" << s * nelem << ", copy=" << DoCopy;
00096   //dbgmsg << ", del=" << DoDelete << endl;
00097   MsgItem m(data, nelem, s * nelem, DoCopy, DoDelete);
00098 
00099   // add MsgItem to the pool
00100   MsgItemList.push_back(m);
00101 
00102   // reset copy and delete flags to default values
00103   DoCopy = DoDelete = true;
00104   return *this;
00105 }
00106 
00107 
00109 // General get routine; called by other cases.
00110 // Arguments are the location where to write the data.
00111 // If this is called with a 0 destination location, then it just
00112 // deletes the top MsgItem.
00113 Message& Message::getmsg(void *data) {
00114   TAU_PROFILE("Message::getmsg()", "Message (void *)", TAU_MESSAGE);
00115 
00116   // check to see if there is an item
00117   if (empty()) {
00118     ERRORMSG("Message::getmsg() no more items in Message" << endl);
00119     PAssert(!empty());
00120   } else {
00121     // get the next MsgItem off the top of the list
00122     MsgItem &m = item(0);
00123 
00124     // copy the data into the given location
00125     if (m.data() != 0 && data != 0) {
00126       //Inform dbgmsg("Message::getmsg", INFORM_ALL_NODES);
00127       //dbgmsg << "Getting item " << removed() << " from loc=" << m.data();
00128       //dbgmsg << " to loc=" << data << " with totbytes=" << m.numBytes();
00129       //dbgmsg << endl;
00130       memcpy(data, m.data(), m.numBytes());
00131     }
00132 
00133     // delete this top MsgItem
00134     deleteMsgItem();
00135   }
00136 
00137   return *this;
00138 }
00139 
00140 
00142 // clear the message; remove all the MsgItems
00143 Message& Message::clear(void) {
00144   TAU_PROFILE("Message::clear()", "Message ()", TAU_MESSAGE);
00145 
00146   while (!empty())
00147     deleteMsgItem();
00148 
00149   return *this;
00150 }
00151 
00152 
00154 // return and remove the next item from this message ... if the item
00155 // does not exist, NULL is returned.  This is similar to get, except that
00156 // just a void* pointer to the data is returned (instead of having the
00157 // data copied into given storage), and this data is DEFINITELY a malloced
00158 // block of data that the user must deallocate using 'free' (NOT delete).
00159 // Like 'get', after this is called, the top MsgItem is removed.
00160 // If you wish to just access the Nth item's item  pointer, use
00161 // item(N).item  .
00162 void *Message::remove() {
00163   TAU_PROFILE("Message::remove()", "void * ()", TAU_MESSAGE);
00164 
00165   // get the data out of the item
00166   MsgItem &m = item(0);
00167   void *retdata = m.data();
00168 
00169   // make a copy of it, or just return it if a delete is needed
00170   if (m.willNeedDelete()) {
00171     m.cancelDelete();
00172   } else if (retdata != 0) {
00173     retdata = malloc(m.numBytes());
00174     memcpy(retdata, m.data(), m.numBytes());
00175   }
00176 
00177   // delete the item
00178   deleteMsgItem();
00179 
00180   // return the data
00181   return retdata;
00182 }
00183 
00184 
00186 // use the << operator to print out a summary of the message
00187 ostream& operator<<(ostream& o, const Message& m) {
00188   TAU_PROFILE("operator<<()", "ostream& (ostream&, const Message&)", 
00189     TAU_MESSAGE | TAU_IO);
00190   o << "Message contains " << m.size() << " items (" << m.removed();
00191   o << " removed).  Contents:\n";
00192   for (size_t i = 0 ; i < m.size(); ++i) {
00193     const Message::MsgItem &mi = m.item(i);
00194     o << "  Item " << i << ": " << mi.numElems() << " elements, ";
00195     o << mi.numBytes() << " bytes total, needDelete = ";
00196     o << mi.willNeedDelete() << endl;
00197   }
00198   return o;
00199 }
00200 
00201 
00202 /***************************************************************************
00203  * $RCSfile: MessageFunctions.cpp,v $   $Author: adelmann $
00204  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:28 $
00205  * IPPL_VERSION_ID: $Id: MessageFunctions.cpp,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $ 
00206  ***************************************************************************/

Generated on Mon Jan 16 13:23:52 2006 for IPPL by  doxygen 1.4.6