1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "PstreamGlobals.H"
27 #include "IOstreams.H"
32 #include <linux/gamma/libgamma.h>
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
44 FixedList<List<List<char> >, 4> PstreamGlobals::recvBuf;
46 // Length of receive buffers
47 FixedList<labelList, 4> PstreamGlobals::recvBufLen;
49 labelList PstreamGlobals::recvIndex;
50 labelList PstreamGlobals::consumeIndex;
52 // These are all signalling nans and probably different from the ones that
53 // the fpu might ever generate.
54 uint64_t PstreamGlobals::resizeMessage[PstreamGlobals::resizeMessageLen] =
56 0x7ff7ffffffffffABllu,
57 0x7ff7ffffffffffCDllu,
58 0x7ff7ffffffffff12llu,
59 0x7ff7ffffffffff30llu,
60 0x7ff7ffffffffff19llu,
61 0x0000000000000000llu // this word gets overwritten with the length.
65 // Wrapper around gamma_wait
66 void PstreamGlobals::gammaWait(const label procNo)
68 // Last request. Block.
69 gamma_wait(procNo, 1);
71 // Currently unconsumed received message
72 label ready = PstreamGlobals::consumeIndex[procNo];
74 // Check received length
75 if (PstreamGlobals::recvBufLen[ready][procNo] == -2)
77 // Was resize message. Consume and rewait (is always followed by
82 Pout<< "PstreamGlobals::gammaWait : "
83 << "Resize event. consumeIndex:" << ready
84 << " Restarting receive from " << procNo << endl;
86 // Consume resize message
87 PstreamGlobals::recvBufLen[ready][procNo] = -1;
88 PstreamGlobals::consumeIndex[procNo] =
89 PstreamGlobals::recvBuf.fcIndex(ready);
91 gamma_wait(procNo, 1);
96 // Copies data from global receive buffer into buf.
97 label PstreamGlobals::copyReceive
104 // Get the ready buffer
105 label ready = consumeIndex[procNo];
108 label receivedLen = recvBufLen[ready][procNo];
112 Pout<< "copyReceive : for proc " << procNo
113 << " copying " << receivedLen << " bytes out of buffer " << ready
121 "Pstream::copyReceive(const label, char*, const label)"
122 ) << "Illegal message length "
124 << " received from proc " << procNo << " into buffer " << ready
126 << "This is probably caused by receiving more than is actually"
127 << " sent (e.g. gather without scatter)." << endl
128 << abort(FatalError);
131 if (receivedLen > bufSize)
135 "Pstream::copyReceive(const label, char*, const label)"
138 << ") not large enough for incomming message ("
139 << receivedLen << ')'
140 << " received from proc " << procNo << " into buffer " << ready
141 << abort(FatalError);
144 // Copy out of receive buffer
148 recvBuf[ready][procNo].begin(),
151 // Release receive buffer
152 recvBufLen[ready][procNo] = -1;
153 // Go to next buffer to consume
154 consumeIndex[procNo] = recvBuf.fcIndex(ready);
160 // Checks whether an incoming message is a resize message. If not returns -1,
161 // otherwise returns size read from header.
162 label PstreamGlobals::getSizeFromHeader(const char* buf, const label len)
164 if (len != resizeMessageLen*sizeof(uint64_t))
169 const uint64_t* dPtr = reinterpret_cast<const uint64_t*>(buf);
171 // Check all but the last word
172 for (label i = 0; i < resizeMessageLen-1; i++)
174 if (*dPtr++ != resizeMessage[i])
180 return *reinterpret_cast<const label*>(dPtr);
184 void PstreamGlobals::setResizeMessage(const label len)
186 reinterpret_cast<label&>(resizeMessage[resizeMessageLen-1]) = len;
190 label PstreamGlobals::getMaxBufSize(const int procNo)
196 maxSz = max(maxSz, recvBuf[i][procNo].size());
202 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
204 } // End namespace Foam
206 // ************************************************************************* //