MCPcopy
hub / github.com/google/gvisor / combine

Method combine

pkg/sentry/pgalloc/save_restore.go:1516–1589  ·  view source on GitHub ↗

combine adds as much of the given load as possible to g.curOp and returns the number of bytes added. Preconditions: - fr.Length() > 0. - fr must be page-aligned.

(amfl *asyncMemoryFileLoad, fr memmap.FileRange, off uint64, tempRef bool)

Source from the content-addressed store, hash-verified

1514// - fr.Length() > 0.
1515// - fr must be page-aligned.
1516func (apfl *AsyncPagesFileLoad) combine(amfl *asyncMemoryFileLoad, fr memmap.FileRange, off uint64, tempRef bool) uint64 {
1517 op := apfl.curOp
1518 if op.total != 0 {
1519 if op.end != off {
1520 // Non-contiguous in the pages file.
1521 return 0
1522 }
1523 if op.amfl != amfl {
1524 // Differing MemoryFile.
1525 return 0
1526 }
1527 if len(op.frs) == cap(op.frs) && op.frs[len(op.frs)-1].End != fr.Start {
1528 // Non-contiguous in the MemoryFile, and we're out of space for
1529 // FileRanges.
1530 return 0
1531 }
1532 if op.tempRef != tempRef {
1533 // Incompatible reference-counting semantics. We could handle this
1534 // by making tempRef per-FileRange, but it's very unlikely that an
1535 // awaited load (tempRef=false) will happen to be followed by an
1536 // unawaited load (tempRef=true) at the correct offset.
1537 return 0
1538 }
1539 }
1540
1541 // Apply direct length limits.
1542 n := fr.Length()
1543 if op.total+n >= apfl.maxReadBytes {
1544 n = apfl.maxReadBytes - op.total
1545 }
1546 if n == 0 {
1547 return 0
1548 }
1549 fr.End = fr.Start + n
1550
1551 // Collect iovecs, which may further limit length.
1552 n = 0
1553 amfl.f.forEachMappingSlice(fr, func(bs []byte) {
1554 if len(op.iovecs) > 0 {
1555 if canMergeIovecAndSlice(op.iovecs[len(op.iovecs)-1], bs) {
1556 op.iovecs[len(op.iovecs)-1].Len += uint64(len(bs))
1557 n += uint64(len(bs))
1558 return
1559 }
1560 if len(op.iovecs) == cap(op.iovecs) {
1561 return
1562 }
1563 }
1564 op.iovecs = append(op.iovecs, unix.Iovec{
1565 Base: &bs[0],
1566 Len: uint64(len(bs)),
1567 })
1568 n += uint64(len(bs))
1569 })
1570 if n == 0 {
1571 return 0
1572 }
1573 fr.End = fr.Start + n

Callers 1

enqueueRangeMethod · 0.95

Calls 3

canMergeIovecAndSliceFunction · 0.85
forEachMappingSliceMethod · 0.80
LengthMethod · 0.45

Tested by

no test coverage detected