| 401 | } |
| 402 | |
| 403 | static void launch() { |
| 404 | if (ctx.queue.size() && ctx.outstanding < FLOW_KNOBS->MAX_OUTSTANDING - FLOW_KNOBS->MIN_SUBMIT) { |
| 405 | ctx.submitMetric = true; |
| 406 | |
| 407 | double begin = timer_monotonic(); |
| 408 | if (!ctx.outstanding) |
| 409 | ctx.ioStallBegin = begin; |
| 410 | |
| 411 | IOBlock* toStart[FLOW_KNOBS->MAX_OUTSTANDING]; |
| 412 | int n = std::min<size_t>(FLOW_KNOBS->MAX_OUTSTANDING - ctx.outstanding, ctx.queue.size()); |
| 413 | |
| 414 | int64_t previousTruncateCount = ctx.countPreSubmitTruncate; |
| 415 | int64_t previousTruncateBytes = ctx.preSubmitTruncateBytes; |
| 416 | int64_t largestTruncate = 0; |
| 417 | |
| 418 | double start = timer(); |
| 419 | for (int i = 0; i < n; i++) { |
| 420 | auto io = ctx.queue.top(); |
| 421 | |
| 422 | KAIOLogBlockEvent(io, OpLogEntry::LAUNCH); |
| 423 | |
| 424 | ctx.queue.pop(); |
| 425 | toStart[i] = io; |
| 426 | io->startTime = start; |
| 427 | |
| 428 | if (ctx.ioTimeout > 0) { |
| 429 | ctx.appendToRequestList(io); |
| 430 | } |
| 431 | |
| 432 | if (io->owner->lastFileSize != io->owner->nextFileSize) { |
| 433 | ++ctx.countPreSubmitTruncate; |
| 434 | int64_t truncateSize = io->owner->nextFileSize - io->owner->lastFileSize; |
| 435 | ASSERT(truncateSize > 0); |
| 436 | ctx.preSubmitTruncateBytes += truncateSize; |
| 437 | largestTruncate = std::max(largestTruncate, truncateSize); |
| 438 | io->owner->truncate(io->owner->nextFileSize); |
| 439 | } |
| 440 | } |
| 441 | double truncateComplete = timer_monotonic(); |
| 442 | int rc = io_submit(ctx.iocx, n, (linux_iocb**)toStart); |
| 443 | double end = timer_monotonic(); |
| 444 | |
| 445 | if (end - begin > FLOW_KNOBS->SLOW_LOOP_CUTOFF) { |
| 446 | ctx.slowAioSubmitMetric->submitDuration = end - truncateComplete; |
| 447 | ctx.slowAioSubmitMetric->truncateDuration = truncateComplete - begin; |
| 448 | ctx.slowAioSubmitMetric->numTruncates = ctx.countPreSubmitTruncate - previousTruncateCount; |
| 449 | ctx.slowAioSubmitMetric->truncateBytes = ctx.preSubmitTruncateBytes - previousTruncateBytes; |
| 450 | ctx.slowAioSubmitMetric->largestTruncate = largestTruncate; |
| 451 | ctx.slowAioSubmitMetric->log(); |
| 452 | |
| 453 | if (nondeterministicRandom()->random01() < end - begin) { |
| 454 | TraceEvent("SlowKAIOLaunch") |
| 455 | .detail("IOSubmitTime", end - truncateComplete) |
| 456 | .detail("TruncateTime", truncateComplete - begin) |
| 457 | .detail("TruncateCount", ctx.countPreSubmitTruncate - previousTruncateCount) |
| 458 | .detail("TruncateBytes", ctx.preSubmitTruncateBytes - previousTruncateBytes) |
| 459 | .detail("LargestTruncate", largestTruncate); |
| 460 | } |
nothing calls this directly
no test coverage detected