mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add fs.AsyncWithContext and call it in fs/gofer/inodeOperations.Release.
fs/gofer/inodeOperations.Release does some asynchronous work. Previously it was calling fs.Async with an anonymous function, which caused the function to be allocated on the heap. Because Release is relatively hot, this results in a lot of small allocations and increased GC pressure, noticeable in perf profiles. This CL adds a new function, AsyncWithContext, which is just like Async, but passes a context to the async function. It avoids the need for an extra anonymous function in fs/gofer/inodeOperations.Release. The Async function itself still requires a single anonymous function. PiperOrigin-RevId: 233141763 Change-Id: I1dce4a883a7be9a8a5b884db01e654655f16d19c
This commit is contained in:
committed by
Shentubot
parent
e884168e1e
commit
f17692d807
@@ -57,6 +57,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"gvisor.googlesource.com/gvisor/pkg/log"
|
||||
"gvisor.googlesource.com/gvisor/pkg/sentry/context"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -87,6 +88,17 @@ func Async(f func()) {
|
||||
}()
|
||||
}
|
||||
|
||||
// AsyncWithContext is just like Async, except that it calls the asynchronous
|
||||
// function with the given context as argument. This function exists to avoid
|
||||
// needing to allocate an extra function on the heap in a hot path.
|
||||
func AsyncWithContext(ctx context.Context, f func(context.Context)) {
|
||||
workMu.RLock()
|
||||
go func() { // S/R-SAFE: AsyncBarrier must be called.
|
||||
defer workMu.RUnlock() // Ensure RUnlock in case of panic.
|
||||
f(ctx)
|
||||
}()
|
||||
}
|
||||
|
||||
// AsyncErrorBarrier waits for all outstanding asynchronous work to complete, or
|
||||
// the first async error to arrive. Other unfinished async executions will
|
||||
// continue in the background. Other past and future async errors are ignored.
|
||||
|
||||
@@ -352,9 +352,10 @@ func (i *inodeOperations) Release(ctx context.Context) {
|
||||
// Releasing the fileState may make RPCs to the gofer. There is
|
||||
// no need to wait for those to return, so we can do this
|
||||
// asynchronously.
|
||||
fs.Async(func() {
|
||||
i.fileState.Release(ctx)
|
||||
})
|
||||
//
|
||||
// We use AsyncWithContext to avoid needing to allocate an extra
|
||||
// anonymous function on the heap.
|
||||
fs.AsyncWithContext(ctx, i.fileState.Release)
|
||||
}
|
||||
|
||||
// Mappable implements fs.InodeOperations.Mappable.
|
||||
|
||||
Reference in New Issue
Block a user