OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
MessageFunctions.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  *
22  * Visit http://people.web.psi.ch/adelmann/ for more details
23  *
24  ***************************************************************************/
25 
26 // include files
27 #include "Message/Message.h"
28 #include "Message/Communicate.h"
29 #include "Utility/Inform.h"
30 #include "Utility/IpplInfo.h"
31 #include "Utility/PAssert.h"
32 
33 
34 #include <new>
35 #include <memory>
36 using namespace std;
37 
38 #include <cstdlib>
39 #include <cstddef>
40 
42 // destructor: delete all items in this message, as if 'get' had been
43 // called for all the items
45 {
46 
47 
48  // remove all unused items
49  clear();
50 
51  // delete the storage in the existing items
52  int n = MsgItemList.size();
53  for (int i=0; i < n; ++i)
54  MsgItemList[i].deleteData();
55 
56  // tell the communicate item to cleanup the provided data,
57  // if necessary
58  if (comm != 0)
59  comm->cleanupMessage(commdata);
60 }
61 
62 
64 // remove the top MsgItem
66 {
67 
68 
69  if (!empty())
70  numRemoved++;
71 }
72 
73 
75 // general put routine; called by other cases
76 // arguments are the item, its element size (in bytes),
77 // and how many items total to copy
78 Message& Message::putmsg(void *data, int s, int nelem)
79 {
80 
81 
82  // if this is a scalar, we always copy, and have one element
83  if (nelem < 1)
84  {
85  nelem = 1;
86  DoCopy = true;
87  }
88 
89  // initialize new MsgItem
90  //Inform dbgmsg("Message::putmsg", INFORM_ALL_NODES);
91  //dbgmsg << "Putting data " << MsgItemList.size() << " at " << data;
92  //dbgmsg << " with " << nelem;
93  //dbgmsg << " elements, totbytes=" << s * nelem << ", copy=" << DoCopy;
94  //dbgmsg << ", del=" << DoDelete << endl;
95  MsgItem m(data, nelem, s * nelem, DoCopy, DoDelete);
96 
97  // add MsgItem to the pool
98  MsgItemList.push_back(m);
99 
100  // reset copy and delete flags to default values
101  DoCopy = DoDelete = true;
102  return *this;
103 }
104 
105 
107 // General get routine; called by other cases.
108 // Arguments are the location where to write the data.
109 // If this is called with a 0 destination location, then it just
110 // deletes the top MsgItem.
112 {
113 
114 
115  // check to see if there is an item
116  if (empty())
117  {
118  ERRORMSG("Message::getmsg() no more items in Message" << endl);
119  PAssert(!empty());
120  }
121  else
122  {
123  // get the next MsgItem off the top of the list
124  MsgItem &m = item(0);
125 
126  // copy the data into the given location
127  if (m.data() != 0 && data != 0)
128  {
129  //Inform dbgmsg("Message::getmsg", INFORM_ALL_NODES);
130  //dbgmsg << "Getting item " << removed() << " from loc=" << m.data();
131  //dbgmsg << " to loc=" << data << " with totbytes=" << m.numBytes();
132  //dbgmsg << endl;
133  memcpy(data, m.data(), m.numBytes());
134  }
135 
136  // delete this top MsgItem
137  deleteMsgItem();
138  }
139 
140  return *this;
141 }
142 
143 
145 // clear the message; remove all the MsgItems
147 {
148 
149 
150  while (!empty())
151  deleteMsgItem();
152 
153  return *this;
154 }
155 
156 
158 // return and remove the next item from this message ... if the item
159 // does not exist, NULL is returned. This is similar to get, except that
160 // just a void* pointer to the data is returned (instead of having the
161 // data copied into given storage), and this data is DEFINITELY a malloced
162 // block of data that the user must deallocate using 'free' (NOT delete).
163 // Like 'get', after this is called, the top MsgItem is removed.
164 // If you wish to just access the Nth item's item pointer, use
165 // item(N).item .
167 {
168 
169 
170  // get the data out of the item
171  MsgItem &m = item(0);
172  void *retdata = m.data();
173 
174  // make a copy of it, or just return it if a delete is needed
175  if (m.willNeedDelete())
176  {
177  m.cancelDelete();
178  }
179  else if (retdata != 0)
180  {
181  retdata = malloc(m.numBytes());
182  memcpy(retdata, m.data(), m.numBytes());
183  }
184 
185  // delete the item
186  deleteMsgItem();
187 
188  // return the data
189  return retdata;
190 }
191 
192 
194 // use the << operator to print out a summary of the message
195 std::ostream& operator<<(std::ostream& o, const Message& m)
196 {
197 
198  o << "Message contains " << m.size() << " items (" << m.removed();
199  o << " removed). Contents:\n";
200  for (size_t i = 0 ; i < m.size(); ++i)
201  {
202  const Message::MsgItem &mi = m.item(i);
203  o << " Item " << i << ": " << mi.numElems() << " elements, ";
204  o << mi.numBytes() << " bytes total, needDelete = ";
205  o << mi.willNeedDelete() << endl;
206  }
207  return o;
208 }
std::ostream & operator<<(std::ostream &os, const Attribute &attr)
Definition: Attribute.cpp:167
void deleteMsgItem()
void * remove()
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
unsigned int numBytes() const
Definition: Message.h:226
MsgItem & item(size_t n)
Definition: Message.h:316
void cancelDelete()
Definition: Message.h:246
size_t size() const
Definition: Message.h:300
Message & putmsg(void *, int, int=0)
unsigned int numElems() const
Definition: Message.h:230
size_t removed() const
Definition: Message.h:304
#define PAssert(c)
Definition: PAssert.h:117
Message & getmsg(void *)
Message & clear()
void * data()
Definition: Message.h:252
bool willNeedDelete() const
Definition: Message.h:240
Inform & endl(Inform &inf)
Definition: Inform.cpp:42