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 <vector>
26 : #include <sstream>
27 :
28 : namespace co
29 : {
30 : #define SEPARATOR '#'
31 :
32 : #ifndef Darwin
33 : # define BIG_SEND
34 : #endif
35 :
36 : namespace
37 : {
38 :
39 22 : static uint32_t _getObjectBufferSize()
40 : {
41 22 : const char* env = getenv( "CO_OBJECT_BUFFER_SIZE" );
42 22 : if( !env )
43 22 : return 60000;
44 :
45 0 : const int64_t size = atoi( env );
46 0 : if( size > 0 )
47 0 : return size;
48 :
49 0 : return 60000;
50 : }
51 :
52 22 : static int32_t _getTimeout()
53 : {
54 22 : const char* env = getenv( "CO_TIMEOUT" );
55 22 : if( !env )
56 22 : return 300000; // == 5min
57 :
58 0 : const int32_t size = atoi( env );
59 0 : if( size <= 0 )
60 0 : return 300000; // == 5min
61 :
62 0 : return size;
63 : }
64 :
65 : uint16_t _defaultPort = 0;
66 22 : uint32_t _objectBufferSize = _getObjectBufferSize();
67 : int32_t _iAttributes[Global::IATTR_ALL] =
68 : {
69 : 100, // INSTANCE_CACHE_SIZE
70 : 100, // NODE_SEND_QUEUE_SIZE
71 : 100, // NODE_SEND_QUEUE_AGE
72 : 10, // RSP_TIMEOUT
73 : 1, // RSP_ERROR_DOWNSCALE
74 : 5, // RSP_ERROR_UPSCALE
75 : 20, // RSP_ERROR_MAXSCALE
76 : 3, // RSP_MIN_SENDRATE_SHIFT
77 : #ifdef BIG_SEND
78 : 64, // RSP_NUM_BUFFERS
79 : 5, // RSP_ACK_FREQUENCY
80 : 65000, // UDP_MTU
81 : #else
82 : 1024, // RSP_NUM_BUFFERS
83 : 17, // RSP_ACK_FREQUENCY
84 : 1470, // UDP_MTU
85 : #endif
86 : 524288, // UDP_BUFFER_SIZE
87 : 1, // QUEUE_MIN_SIZE
88 : 1, // QUEUE_REFILL
89 : 8, // RDMA_RING_BUFFER_SIZE_MB
90 : 512, // RDMA_SEND_QUEUE_DEPTH
91 : 5000, // RDMA_RESOLVE_TIMEOUT_MS
92 : 1, // IATTR_ROBUSTNESS
93 22 : _getTimeout(), // IATTR_TIMEOUT_DEFAULT
94 : 1023, // IATTR_OBJECT_COMPRESSION
95 : 0, // IATTR_CMD_QUEUE_LIMIT
96 22 : };
97 : }
98 :
99 0 : bool Global::fromString(const std::string& data )
100 : {
101 0 : if( data.empty() || data[0] != SEPARATOR )
102 0 : return false;
103 :
104 0 : std::vector< uint32_t > newGlobals;
105 0 : newGlobals.reserve( IATTR_ALL );
106 :
107 0 : size_t endMarker( 1u );
108 : while( true )
109 : {
110 0 : const size_t startMarker = data.find( SEPARATOR, endMarker );
111 0 : if( startMarker == std::string::npos )
112 0 : break;
113 :
114 0 : endMarker = data.find( SEPARATOR, startMarker + 1 );
115 0 : if( endMarker == std::string::npos )
116 0 : break;
117 :
118 : const std::string sub = data.substr( startMarker + 1,
119 0 : endMarker - startMarker - 1 );
120 0 : if( !sub.empty() && (isdigit( sub[0] ) || sub[0] == '-') )
121 0 : newGlobals.push_back( atoi( sub.c_str( )) );
122 : else
123 0 : break;
124 0 : }
125 :
126 : // only apply a 'complete' global list
127 0 : if( newGlobals.size() != IATTR_ALL )
128 : {
129 0 : LBWARN << "Expected " << unsigned( IATTR_ALL ) << " globals, got "
130 0 : << newGlobals.size() << std::endl;
131 0 : return false;
132 : }
133 :
134 0 : std::copy( newGlobals.begin(), newGlobals.end(), _iAttributes );
135 0 : return true;
136 : }
137 :
138 0 : std::string Global::toString()
139 : {
140 0 : std::stringstream stream;
141 0 : stream << SEPARATOR << SEPARATOR;
142 :
143 0 : for( uint32_t i = 0; i < IATTR_ALL; ++i )
144 0 : stream << _iAttributes[i] << SEPARATOR;
145 :
146 0 : stream << SEPARATOR;
147 0 : return stream.str();
148 : }
149 :
150 0 : void Global::setDefaultPort( const uint16_t port )
151 : {
152 0 : _defaultPort = port;
153 0 : }
154 :
155 0 : uint16_t Global::getDefaultPort()
156 : {
157 0 : return _defaultPort;
158 : }
159 :
160 2 : void Global::setObjectBufferSize( const uint32_t size )
161 : {
162 2 : _objectBufferSize = size;
163 2 : }
164 :
165 314414 : uint32_t Global::getObjectBufferSize()
166 : {
167 314414 : return _objectBufferSize;
168 : }
169 :
170 4 : void Global::setIAttribute( const IAttribute attr, const int32_t value )
171 : {
172 4 : _iAttributes[ attr ] = value;
173 4 : }
174 :
175 1886696 : int32_t Global::getIAttribute( const IAttribute attr )
176 : {
177 1886696 : return _iAttributes[ attr ];
178 : }
179 :
180 907090 : uint32_t Global::getTimeout()
181 : {
182 1814256 : return getIAttribute( IATTR_ROBUSTNESS ) ?
183 1814283 : getIAttribute( IATTR_TIMEOUT_DEFAULT ) : LB_TIMEOUT_INDEFINITE;
184 : }
185 :
186 0 : uint32_t Global::getKeepaliveTimeout()
187 : {
188 0 : const char* env = getenv( "CO_KEEPALIVE_TIMEOUT" );
189 0 : if( !env )
190 0 : return 2000; // ms
191 :
192 0 : const int64_t size = atoi( env );
193 0 : if( size == 0 )
194 0 : return 2000; // ms
195 :
196 0 : return size;
197 : }
198 :
199 55 : size_t Global::getCommandQueueLimit()
200 : {
201 55 : const int32_t limit = getIAttribute( IATTR_CMD_QUEUE_LIMIT );
202 55 : if( limit > 0 )
203 0 : return size_t( limit ) << 10;
204 55 : return std::numeric_limits< size_t >::max();
205 : }
206 :
207 66 : }
|