Line data Source code
1 :
2 : /* Copyright (c) 2005-2016, Stefan Eilemann <eile@equalizergraphics.com>
3 : *
4 : * This file is part of Collage <https://github.com/Eyescale/Collage>
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 2.1 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "global.h"
21 :
22 : #include <limits>
23 : #include <stdlib.h>
24 :
25 : #include <sstream>
26 : #include <vector>
27 :
28 : namespace co
29 : {
30 : #define SEPARATOR '#'
31 :
32 : #ifndef Darwin
33 : #define BIG_SEND
34 : #endif
35 :
36 : namespace
37 : {
38 21 : static uint32_t _getObjectBufferSize()
39 : {
40 21 : const char* env = getenv("CO_OBJECT_BUFFER_SIZE");
41 21 : if (!env)
42 21 : return 60000;
43 :
44 0 : const int64_t size = atoi(env);
45 0 : if (size > 0)
46 0 : return size;
47 :
48 0 : return 60000;
49 : }
50 :
51 21 : static int32_t _getTimeout()
52 : {
53 21 : const char* env = getenv("CO_TIMEOUT");
54 21 : if (!env)
55 21 : return 300000; // == 5min
56 :
57 0 : const int32_t size = atoi(env);
58 0 : if (size <= 0)
59 0 : return 300000; // == 5min
60 :
61 0 : return size;
62 : }
63 :
64 : uint16_t _defaultPort = 0;
65 21 : uint32_t _objectBufferSize = _getObjectBufferSize();
66 : int32_t _iAttributes[Global::IATTR_ALL] = {
67 : 100, // INSTANCE_CACHE_SIZE
68 : 100, // NODE_SEND_QUEUE_SIZE
69 : 100, // NODE_SEND_QUEUE_AGE
70 : 10, // RSP_TIMEOUT
71 : 1, // RSP_ERROR_DOWNSCALE
72 : 5, // RSP_ERROR_UPSCALE
73 : 20, // RSP_ERROR_MAXSCALE
74 : 3, // RSP_MIN_SENDRATE_SHIFT
75 : #ifdef BIG_SEND
76 : 64, // RSP_NUM_BUFFERS
77 : 5, // RSP_ACK_FREQUENCY
78 : 65000, // UDP_MTU
79 : #else
80 : 1024, // RSP_NUM_BUFFERS
81 : 17, // RSP_ACK_FREQUENCY
82 : 1470, // UDP_MTU
83 : #endif
84 : 524288, // UDP_BUFFER_SIZE
85 : 1, // QUEUE_MIN_SIZE
86 : 1, // QUEUE_REFILL
87 : 8, // RDMA_RING_BUFFER_SIZE_MB
88 : 512, // RDMA_SEND_QUEUE_DEPTH
89 : 5000, // RDMA_RESOLVE_TIMEOUT_MS
90 : 1, // IATTR_ROBUSTNESS
91 21 : _getTimeout(), // IATTR_TIMEOUT_DEFAULT
92 : 1023, // IATTR_OBJECT_COMPRESSION
93 : 0, // IATTR_CMD_QUEUE_LIMIT
94 21 : };
95 : }
96 :
97 0 : bool Global::fromString(const std::string& data)
98 : {
99 0 : if (data.empty() || data[0] != SEPARATOR)
100 0 : return false;
101 :
102 0 : std::vector<uint32_t> newGlobals;
103 0 : newGlobals.reserve(IATTR_ALL);
104 :
105 0 : size_t endMarker(1u);
106 : while (true)
107 : {
108 0 : const size_t startMarker = data.find(SEPARATOR, endMarker);
109 0 : if (startMarker == std::string::npos)
110 0 : break;
111 :
112 0 : endMarker = data.find(SEPARATOR, startMarker + 1);
113 0 : if (endMarker == std::string::npos)
114 0 : break;
115 :
116 : const std::string sub =
117 0 : data.substr(startMarker + 1, endMarker - startMarker - 1);
118 0 : if (!sub.empty() && (isdigit(sub[0]) || sub[0] == '-'))
119 0 : newGlobals.push_back(atoi(sub.c_str()));
120 : else
121 0 : break;
122 0 : }
123 :
124 : // only apply a 'complete' global list
125 0 : if (newGlobals.size() != IATTR_ALL)
126 : {
127 0 : LBWARN << "Expected " << unsigned(IATTR_ALL) << " globals, got "
128 0 : << newGlobals.size() << std::endl;
129 0 : return false;
130 : }
131 :
132 0 : std::copy(newGlobals.begin(), newGlobals.end(), _iAttributes);
133 0 : return true;
134 : }
135 :
136 0 : std::string Global::toString()
137 : {
138 0 : std::stringstream stream;
139 0 : stream << SEPARATOR << SEPARATOR;
140 :
141 0 : for (uint32_t i = 0; i < IATTR_ALL; ++i)
142 0 : stream << _iAttributes[i] << SEPARATOR;
143 :
144 0 : stream << SEPARATOR;
145 0 : return stream.str();
146 : }
147 :
148 0 : void Global::setDefaultPort(const uint16_t port)
149 : {
150 0 : _defaultPort = port;
151 0 : }
152 :
153 0 : uint16_t Global::getDefaultPort()
154 : {
155 0 : return _defaultPort;
156 : }
157 :
158 2 : void Global::setObjectBufferSize(const uint32_t size)
159 : {
160 2 : _objectBufferSize = size;
161 2 : }
162 :
163 177 : uint32_t Global::getObjectBufferSize()
164 : {
165 177 : return _objectBufferSize;
166 : }
167 :
168 4 : void Global::setIAttribute(const IAttribute attr, const int32_t value)
169 : {
170 4 : _iAttributes[attr] = value;
171 4 : }
172 :
173 72551 : int32_t Global::getIAttribute(const IAttribute attr)
174 : {
175 72551 : return _iAttributes[attr];
176 : }
177 :
178 71 : uint32_t Global::getTimeout()
179 : {
180 71 : return getIAttribute(IATTR_ROBUSTNESS)
181 71 : ? getIAttribute(IATTR_TIMEOUT_DEFAULT)
182 71 : : LB_TIMEOUT_INDEFINITE;
183 : }
184 :
185 0 : uint32_t Global::getKeepaliveTimeout()
186 : {
187 0 : const char* env = getenv("CO_KEEPALIVE_TIMEOUT");
188 0 : if (!env)
189 0 : return 2000; // ms
190 :
191 0 : const int64_t size = atoi(env);
192 0 : if (size == 0)
193 0 : return 2000; // ms
194 :
195 0 : return size;
196 : }
197 :
198 53 : size_t Global::getCommandQueueLimit()
199 : {
200 53 : const int32_t limit = getIAttribute(IATTR_CMD_QUEUE_LIMIT);
201 53 : if (limit > 0)
202 0 : return size_t(limit) << 10;
203 53 : return std::numeric_limits<size_t>::max();
204 : }
205 63 : }
|