| 219 | } |
| 220 | |
| 221 | void Socket::SharedPart::UpdateStatsEverySecond(int64_t now_ms) { |
| 222 | ExtendedSocketStat* stat = extended_stat; |
| 223 | if (stat == NULL) { |
| 224 | stat = new (std::nothrow) ExtendedSocketStat; |
| 225 | if (stat == NULL) { |
| 226 | return; |
| 227 | } |
| 228 | extended_stat = stat; |
| 229 | } |
| 230 | |
| 231 | // Save volatile counters. |
| 232 | const size_t in_sz = in_size.load(butil::memory_order_relaxed); |
| 233 | const size_t in_nmsg = in_num_messages.load(butil::memory_order_relaxed); |
| 234 | const size_t out_sz = out_size.load(butil::memory_order_relaxed); |
| 235 | const size_t out_nmsg = out_num_messages.load(butil::memory_order_relaxed); |
| 236 | |
| 237 | // Notice that we don't normalize any data, mainly because normalization |
| 238 | // often make data inaccurate and confuse users. This assumes that this |
| 239 | // function is called exactly every second. This may not be true when the |
| 240 | // running machine gets very busy. TODO(gejun): Figure out a method to |
| 241 | // selectively normalize data when the calling interval is far from 1 second. |
| 242 | stat->in_size_s = in_sz - stat->last_in_size; |
| 243 | stat->in_num_messages_s = in_nmsg - stat->last_in_num_messages; |
| 244 | stat->out_size_s = out_sz - stat->last_out_size; |
| 245 | stat->out_num_messages_s = out_nmsg - stat->last_out_num_messages; |
| 246 | |
| 247 | stat->last_in_size = in_sz; |
| 248 | stat->last_in_num_messages = in_nmsg; |
| 249 | stat->last_out_size = out_sz; |
| 250 | stat->last_out_num_messages = out_nmsg; |
| 251 | |
| 252 | ExtendedSocketStat::Sampled popped; |
| 253 | if (stat->in_size_s |/*bitwise or*/ |
| 254 | stat->in_num_messages_s | |
| 255 | stat->out_size_s | |
| 256 | stat->out_num_messages_s) { |
| 257 | ExtendedSocketStat::Sampled s = { |
| 258 | stat->in_size_s, stat->in_num_messages_s, |
| 259 | stat->out_size_s, stat->out_num_messages_s |
| 260 | }; |
| 261 | stat->in_size_m += s.in_size_s; |
| 262 | stat->in_num_messages_m += s.in_num_messages_s; |
| 263 | stat->out_size_m += s.out_size_s; |
| 264 | stat->out_num_messages_m += s.out_num_messages_s; |
| 265 | if (stat->_minute_counter.Add(now_ms, s, &popped)) { |
| 266 | stat->in_size_m -= popped.in_size_s; |
| 267 | stat->in_num_messages_m -= popped.in_num_messages_s; |
| 268 | stat->out_size_m -= popped.out_size_s; |
| 269 | stat->out_num_messages_m -= popped.out_num_messages_s; |
| 270 | } |
| 271 | } |
| 272 | while (stat->_minute_counter.TryPop(now_ms, &popped)) { |
| 273 | stat->in_size_m -= popped.in_size_s; |
| 274 | stat->in_num_messages_m -= popped.in_num_messages_s; |
| 275 | stat->out_size_m -= popped.out_size_s; |
| 276 | stat->out_num_messages_m -= popped.out_num_messages_s; |
| 277 | } |
| 278 | } |