1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "PstreamGlobals.H"
28 #include "IOstreams.H"
33 #include <linux/gamma/libgamma.h>
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
45 FixedList<List<List<char> >, 4> PstreamGlobals::recvBuf;
47 // Length of receive buffers
48 FixedList<labelList, 4> PstreamGlobals::recvBufLen;
50 labelList PstreamGlobals::recvIndex;
51 labelList PstreamGlobals::consumeIndex;
53 // These are all signalling nans and probably different from the ones that
54 // the fpu might ever generate.
55 uint64_t PstreamGlobals::resizeMessage[PstreamGlobals::resizeMessageLen] =
57 0x7ff7ffffffffffABllu,
58 0x7ff7ffffffffffCDllu,
59 0x7ff7ffffffffff12llu,
60 0x7ff7ffffffffff30llu,
61 0x7ff7ffffffffff19llu,
62 0x0000000000000000llu // this word gets overwritten with the length.
66 // Wrapper around gamma_wait
67 void PstreamGlobals::gammaWait(const label procNo)
69 // Last request. Block.
70 gamma_wait(procNo, 1);
72 // Currently unconsumed received message
73 label ready = PstreamGlobals::consumeIndex[procNo];
75 // Check received length
76 if (PstreamGlobals::recvBufLen[ready][procNo] == -2)
78 // Was resize message. Consume and rewait (is always followed by
83 Pout<< "PstreamGlobals::gammaWait : "
84 << "Resize event. consumeIndex:" << ready
85 << " Restarting receive from " << procNo << endl;
87 // Consume resize message
88 PstreamGlobals::recvBufLen[ready][procNo] = -1;
89 PstreamGlobals::consumeIndex[procNo] =
90 PstreamGlobals::recvBuf.fcIndex(ready);
92 gamma_wait(procNo, 1);
97 // Copies data from global receive buffer into buf.
98 label PstreamGlobals::copyReceive
105 // Get the ready buffer
106 label ready = consumeIndex[procNo];
109 label receivedLen = recvBufLen[ready][procNo];
113 Pout<< "copyReceive : for proc " << procNo
114 << " copying " << receivedLen << " bytes out of buffer " << ready
122 "Pstream::copyReceive(const label, char*, const label)"
123 ) << "Illegal message length "
125 << " received from proc " << procNo << " into buffer " << ready
127 << "This is probably caused by receiving more than is actually"
128 << " sent (e.g. gather without scatter)." << endl
129 << abort(FatalError);
132 if (receivedLen > bufSize)
136 "Pstream::copyReceive(const label, char*, const label)"
139 << ") not large enough for incomming message ("
140 << receivedLen << ')'
141 << " received from proc " << procNo << " into buffer " << ready
142 << abort(FatalError);
145 // Copy out of receive buffer
149 recvBuf[ready][procNo].begin(),
152 // Release receive buffer
153 recvBufLen[ready][procNo] = -1;
154 // Go to next buffer to consume
155 consumeIndex[procNo] = recvBuf.fcIndex(ready);
161 // Checks whether an incoming message is a resize message. If not returns -1,
162 // otherwise returns size read from header.
163 label PstreamGlobals::getSizeFromHeader(const char* buf, const label len)
165 if (len != resizeMessageLen*sizeof(uint64_t))
170 const uint64_t* dPtr = reinterpret_cast<const uint64_t*>(buf);
172 // Check all but the last word
173 for (label i = 0; i < resizeMessageLen-1; i++)
175 if (*dPtr++ != resizeMessage[i])
181 return *reinterpret_cast<const label*>(dPtr);
185 void PstreamGlobals::setResizeMessage(const label len)
187 reinterpret_cast<label&>(resizeMessage[resizeMessageLen-1]) = len;
191 label PstreamGlobals::getMaxBufSize(const int procNo)
197 maxSz = max(maxSz, recvBuf[i][procNo].size());
203 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
205 } // End namespace Foam
207 // ************************************************************************* //