| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_packet_creator.h" | 5 #include "net/quic/quic_packet_creator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 size_t iov_offset, | 340 size_t iov_offset, |
| 341 size_t length, | 341 size_t length, |
| 342 char* buffer) { | 342 char* buffer) { |
| 343 int iovnum = 0; | 343 int iovnum = 0; |
| 344 while (iovnum < iov.iov_count && iov_offset >= iov.iov[iovnum].iov_len) { | 344 while (iovnum < iov.iov_count && iov_offset >= iov.iov[iovnum].iov_len) { |
| 345 iov_offset -= iov.iov[iovnum].iov_len; | 345 iov_offset -= iov.iov[iovnum].iov_len; |
| 346 ++iovnum; | 346 ++iovnum; |
| 347 } | 347 } |
| 348 DCHECK_LE(iovnum, iov.iov_count); | 348 DCHECK_LE(iovnum, iov.iov_count); |
| 349 DCHECK_LE(iov_offset, iov.iov[iovnum].iov_len); | 349 DCHECK_LE(iov_offset, iov.iov[iovnum].iov_len); |
| 350 if (FLAGS_quic_packet_creator_prefetch) { | 350 if (iovnum >= iov.iov_count || length == 0) { |
| 351 if (iovnum >= iov.iov_count || length == 0) { | 351 return; |
| 352 return; | 352 } |
| 353 |
| 354 // Unroll the first iteration that handles iov_offset. |
| 355 const size_t iov_available = iov.iov[iovnum].iov_len - iov_offset; |
| 356 size_t copy_len = min(length, iov_available); |
| 357 |
| 358 // Try to prefetch the next iov if there is at least one more after the |
| 359 // current. Otherwise, it looks like an irregular access that the hardware |
| 360 // prefetcher won't speculatively prefetch. Only prefetch one iov because |
| 361 // generally, the iov_offset is not 0, input iov consists of 2K buffers and |
| 362 // the output buffer is ~1.4K. |
| 363 if (copy_len == iov_available && iovnum + 1 < iov.iov_count) { |
| 364 // TODO(ckrasic) - this is unused without prefetch() |
| 365 // char* next_base = static_cast<char*>(iov.iov[iovnum + 1].iov_base); |
| 366 // char* next_base = static_cast<char*>(iov.iov[iovnum + 1].iov_base); |
| 367 // Prefetch 2 cachelines worth of data to get the prefetcher started; leave |
| 368 // it to the hardware prefetcher after that. |
| 369 // TODO(ckrasic) - investigate what to do about prefetch directives. |
| 370 // prefetch(next_base, PREFETCH_HINT_T0); |
| 371 if (iov.iov[iovnum + 1].iov_len >= 64) { |
| 372 // TODO(ckrasic) - investigate what to do about prefetch directives. |
| 373 // prefetch(next_base + CACHELINE_SIZE, PREFETCH_HINT_T0); |
| 353 } | 374 } |
| 375 } |
| 354 | 376 |
| 355 // Unroll the first iteration that handles iov_offset. | 377 const char* src = static_cast<char*>(iov.iov[iovnum].iov_base) + iov_offset; |
| 356 const size_t iov_available = iov.iov[iovnum].iov_len - iov_offset; | 378 while (true) { |
| 357 size_t copy_len = min(length, iov_available); | 379 memcpy(buffer, src, copy_len); |
| 358 | 380 length -= copy_len; |
| 359 // Try to prefetch the next iov if there is at least one more after the | 381 buffer += copy_len; |
| 360 // current. Otherwise, it looks like an irregular access that the hardware | 382 if (length == 0 || ++iovnum >= iov.iov_count) { |
| 361 // prefetcher won't speculatively prefetch. Only prefetch one iov because | 383 break; |
| 362 // generally, the iov_offset is not 0, input iov consists of 2K buffers and | |
| 363 // the output buffer is ~1.4K. | |
| 364 if (copy_len == iov_available && iovnum + 1 < iov.iov_count) { | |
| 365 // TODO(ckrasic) - this is unused without prefetch() | |
| 366 // char* next_base = static_cast<char*>(iov.iov[iovnum + 1].iov_base); | |
| 367 // Prefetch 2 cachelines worth of data to get the prefetcher started; | |
| 368 // leave it to the hardware prefetcher after that. | |
| 369 // TODO(ckrasic) - investigate what to do about prefetch directives. | |
| 370 // prefetch(next_base, PREFETCH_HINT_T0); | |
| 371 if (iov.iov[iovnum + 1].iov_len >= 64) { | |
| 372 // TODO(ckrasic) - investigate what to do about prefetch directives. | |
| 373 // prefetch(next_base + CACHELINE_SIZE, PREFETCH_HINT_T0); | |
| 374 } | |
| 375 } | 384 } |
| 376 | 385 src = static_cast<char*>(iov.iov[iovnum].iov_base); |
| 377 const char* src = static_cast<char*>(iov.iov[iovnum].iov_base) + iov_offset; | 386 copy_len = min(length, iov.iov[iovnum].iov_len); |
| 378 while (true) { | |
| 379 memcpy(buffer, src, copy_len); | |
| 380 length -= copy_len; | |
| 381 buffer += copy_len; | |
| 382 if (length == 0 || ++iovnum >= iov.iov_count) { | |
| 383 break; | |
| 384 } | |
| 385 src = static_cast<char*>(iov.iov[iovnum].iov_base); | |
| 386 copy_len = min(length, iov.iov[iovnum].iov_len); | |
| 387 } | |
| 388 } else { | |
| 389 while (iovnum < iov.iov_count && length > 0) { | |
| 390 const size_t copy_len = min(length, iov.iov[iovnum].iov_len - iov_offset); | |
| 391 memcpy(buffer, static_cast<char*>(iov.iov[iovnum].iov_base) + iov_offset, | |
| 392 copy_len); | |
| 393 iov_offset = 0; | |
| 394 length -= copy_len; | |
| 395 buffer += copy_len; | |
| 396 ++iovnum; | |
| 397 } | |
| 398 } | 387 } |
| 399 LOG_IF(DFATAL, length > 0) << "Failed to copy entire length to buffer."; | 388 LOG_IF(DFATAL, length > 0) << "Failed to copy entire length to buffer."; |
| 400 } | 389 } |
| 401 | 390 |
| 402 SerializedPacket QuicPacketCreator::ReserializeAllFrames( | 391 SerializedPacket QuicPacketCreator::ReserializeAllFrames( |
| 403 const RetransmittableFrames& frames, | 392 const RetransmittableFrames& frames, |
| 404 EncryptionLevel original_encryption_level, | 393 EncryptionLevel original_encryption_level, |
| 405 QuicPacketNumberLength original_length, | 394 QuicPacketNumberLength original_length, |
| 406 char* buffer, | 395 char* buffer, |
| 407 size_t buffer_len) { | 396 size_t buffer_len) { |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 hash_map<QuicPathId, QuicPacketNumber>::iterator it = | 806 hash_map<QuicPathId, QuicPacketNumber>::iterator it = |
| 818 multipath_packet_number_.find(path_id); | 807 multipath_packet_number_.find(path_id); |
| 819 // If path_id is not in the map, it's a new path. Set packet_number to 0. | 808 // If path_id is not in the map, it's a new path. Set packet_number to 0. |
| 820 packet_number_ = it == multipath_packet_number_.end() ? 0 : it->second; | 809 packet_number_ = it == multipath_packet_number_.end() ? 0 : it->second; |
| 821 current_path_ = path_id; | 810 current_path_ = path_id; |
| 822 // Switching path needs to update packet number length. | 811 // Switching path needs to update packet number length. |
| 823 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight); | 812 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight); |
| 824 } | 813 } |
| 825 | 814 |
| 826 } // namespace net | 815 } // namespace net |
| OLD | NEW |