Bug fix supplied by Niklas Nordin:
[OpenFOAM-1.5.x.git] / src / Pstream / gamma / PstreamGlobals.C
blobd233709234f30c9aea2112d9e3689fd5284a8be2
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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"
29 #include "Pstream.H"
31 extern "C" {
33 #include <linux/gamma/libgamma.h>
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 namespace Foam
42 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
44 // Receive buffers
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)
77     {
78         // Was resize message. Consume and rewait (is always followed by
79         // real message)
81         if (Pstream::debug)
82         {
83             Pout<< "PstreamGlobals::gammaWait : "
84                 << "Resize event. consumeIndex:" << ready
85                 << " Restarting receive from " << procNo << endl;
86         }
87         // Consume resize message
88         PstreamGlobals::recvBufLen[ready][procNo] = -1;
89         PstreamGlobals::consumeIndex[procNo] =
90             PstreamGlobals::recvBuf.fcIndex(ready);
91         // And rewait
92         gamma_wait(procNo, 1);
93     }
97 // Copies data from global receive buffer into buf.
98 label PstreamGlobals::copyReceive
100     const label procNo,
101     char* buf,
102     const label bufSize
105     // Get the ready buffer
106     label ready = consumeIndex[procNo];
108     // Actually received
109     label receivedLen = recvBufLen[ready][procNo];
111     if (Pstream::debug)
112     {
113         Pout<< "copyReceive : for proc " << procNo
114             << " copying " << receivedLen << " bytes out of buffer " << ready
115             << endl;
116     }
118     if (receivedLen < 0)
119     {
120         FatalErrorIn
121         (
122             "Pstream::copyReceive(const label, char*, const label)"
123         )   << "Illegal message length "
124             << receivedLen
125             << " received from proc " << procNo << " into buffer " << ready
126             << endl
127             << "This is probably caused by receiving more than is actually"
128             << " sent (e.g. gather without scatter)." << endl
129             << abort(FatalError);
130     }
132     if (receivedLen > bufSize)
133     {
134         FatalErrorIn
135         (
136             "Pstream::copyReceive(const label, char*, const label)"
137         )   << "buffer ("
138             << bufSize
139             << ") not large enough for incomming message ("
140             << receivedLen << ')'
141             << " received from proc " << procNo << " into buffer " << ready
142             << abort(FatalError);
143     }
145     // Copy out of receive buffer
146     memcpy
147     (
148         buf,
149         recvBuf[ready][procNo].begin(),
150         receivedLen
151     );
152     // Release receive buffer
153     recvBufLen[ready][procNo] = -1;
154     // Go to next buffer to consume
155     consumeIndex[procNo] = recvBuf.fcIndex(ready);
157     return receivedLen;
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))
166     {
167         return -1;
168     }
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++)
174     {
175         if (*dPtr++ != resizeMessage[i])
176         {
177             return -1;
178         }
179     }
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)
193     label maxSz = 0;
195     forAll(recvBuf, i)
196     {
197         maxSz = max(maxSz, recvBuf[i][procNo].size());
198     }
199     return maxSz;
203 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
205 } // End namespace Foam
207 // ************************************************************************* //