diff options
author | Andrei Vagin <avagin@google.com> | 2019-04-01 12:52:19 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-04-01 12:53:27 -0700 |
commit | a4b34e26372528ef60140acef0b7c1ab1934f82a (patch) | |
tree | 3d308e07c065191dd0c4f0e30553eb21666c6969 | |
parent | 0327931ca41de892dcdae4fd6a7123cea5b0b2f0 (diff) |
gvisor: convert ilist to ilist:generic_list
ilist:generic_list works faster (cl/240185278) and
the code looks cleaner without type casting.
PiperOrigin-RevId: 241381175
Change-Id: I8487ab1d73637b3e9733c253c56dce9e79f0d35f
-rw-r--r-- | pkg/sentry/fs/BUILD | 14 | ||||
-rw-r--r-- | pkg/sentry/fs/inotify.go | 14 | ||||
-rw-r--r-- | pkg/sentry/fs/inotify_event.go | 3 | ||||
-rw-r--r-- | pkg/sentry/kernel/pipe/BUILD | 15 | ||||
-rw-r--r-- | pkg/sentry/kernel/pipe/buffers.go | 6 | ||||
-rw-r--r-- | pkg/sentry/kernel/pipe/pipe.go | 8 | ||||
-rw-r--r-- | pkg/waiter/BUILD | 27 | ||||
-rw-r--r-- | pkg/waiter/waiter.go | 12 |
8 files changed, 66 insertions, 33 deletions
diff --git a/pkg/sentry/fs/BUILD b/pkg/sentry/fs/BUILD index 6957c1bbe..dda6a0c9f 100644 --- a/pkg/sentry/fs/BUILD +++ b/pkg/sentry/fs/BUILD @@ -14,6 +14,7 @@ go_library( "dirent_cache.go", "dirent_list.go", "dirent_state.go", + "event_list.go", "file.go", "file_operations.go", "file_overlay.go", @@ -46,7 +47,6 @@ go_library( deps = [ "//pkg/abi/linux", "//pkg/amutex", - "//pkg/ilist", "//pkg/log", "//pkg/metric", "//pkg/p9", @@ -83,6 +83,18 @@ go_template_instance( }, ) +go_template_instance( + name = "event_list", + out = "event_list.go", + package = "fs", + prefix = "event", + template = "//pkg/ilist:generic_list", + types = { + "Linker": "*Event", + "Element": "*Event", + }, +) + go_test( name = "fs_x_test", size = "small", diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go index 51ece5ed0..5d6a7074b 100644 --- a/pkg/sentry/fs/inotify.go +++ b/pkg/sentry/fs/inotify.go @@ -19,7 +19,6 @@ import ( "sync/atomic" "gvisor.googlesource.com/gvisor/pkg/abi/linux" - "gvisor.googlesource.com/gvisor/pkg/ilist" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" @@ -51,7 +50,7 @@ type Inotify struct { evMu sync.Mutex `state:"nosave"` // A list of pending events for this inotify instance. Protected by evMu. - events ilist.List + events eventList // A scratch buffer, use to serialize inotify events. Use allocate this // ahead of time and reuse performance. Protected by evMu. @@ -143,9 +142,7 @@ func (i *Inotify) Read(ctx context.Context, _ *File, dst usermem.IOSequence, _ i } var writeLen int64 - for e := i.events.Front(); e != nil; e = e.Next() { - event := e.(*Event) - + for event := i.events.Front(); event != nil; event = event.Next() { // Does the buffer have enough remaining space to hold the event we're // about to write out? if dst.NumBytes() < int64(event.sizeOf()) { @@ -160,7 +157,7 @@ func (i *Inotify) Read(ctx context.Context, _ *File, dst usermem.IOSequence, _ i // Linux always dequeues an available event as long as there's enough // buffer space to copy it out, even if the copy below fails. Emulate // this behaviour. - i.events.Remove(e) + i.events.Remove(event) // Buffer has enough space, copy event to the read buffer. n, err := event.CopyTo(ctx, i.scratch, dst) @@ -197,8 +194,7 @@ func (i *Inotify) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArg defer i.evMu.Unlock() var n uint32 for e := i.events.Front(); e != nil; e = e.Next() { - event := e.(*Event) - n += uint32(event.sizeOf()) + n += uint32(e.sizeOf()) } var buf [4]byte usermem.ByteOrder.PutUint32(buf[:], n) @@ -216,7 +212,7 @@ func (i *Inotify) queueEvent(ev *Event) { // Check if we should coalesce the event we're about to queue with the last // one currently in the queue. Events are coalesced if they are identical. if last := i.events.Back(); last != nil { - if ev.equals(last.(*Event)) { + if ev.equals(last) { // "Coalesce" the two events by simply not queuing the new one. We // don't need to raise a waiter.EventIn notification because no new // data is available for reading. diff --git a/pkg/sentry/fs/inotify_event.go b/pkg/sentry/fs/inotify_event.go index 9e3e9d816..f09928b68 100644 --- a/pkg/sentry/fs/inotify_event.go +++ b/pkg/sentry/fs/inotify_event.go @@ -18,7 +18,6 @@ import ( "bytes" "fmt" - "gvisor.googlesource.com/gvisor/pkg/ilist" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" ) @@ -31,7 +30,7 @@ const inotifyEventBaseSize = 16 // // +stateify savable type Event struct { - ilist.Entry + eventEntry wd int32 mask uint32 diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index 011a3f349..6b23117d9 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -1,10 +1,24 @@ package(licenses = ["notice"]) +load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +go_template_instance( + name = "buffer_list", + out = "buffer_list.go", + package = "pipe", + prefix = "buffer", + template = "//pkg/ilist:generic_list", + types = { + "Element": "*Buffer", + "Linker": "*Buffer", + }, +) + go_library( name = "pipe", srcs = [ + "buffer_list.go", "buffers.go", "device.go", "node.go", @@ -18,7 +32,6 @@ go_library( deps = [ "//pkg/abi/linux", "//pkg/amutex", - "//pkg/ilist", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/device", diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go index fa8045910..54e059f8b 100644 --- a/pkg/sentry/kernel/pipe/buffers.go +++ b/pkg/sentry/kernel/pipe/buffers.go @@ -14,16 +14,12 @@ package pipe -import ( - "gvisor.googlesource.com/gvisor/pkg/ilist" -) - // Buffer encapsulates a queueable byte buffer that can // easily be truncated. It is designed only for use with pipes. // // +stateify savable type Buffer struct { - ilist.Entry + bufferEntry data []byte } diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index fad077d2d..357d1162e 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -25,7 +25,6 @@ import ( "sync/atomic" "syscall" - "gvisor.googlesource.com/gvisor/pkg/ilist" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" @@ -51,7 +50,7 @@ type Pipe struct { Dirent *fs.Dirent // The buffered byte queue. - data ilist.List + data bufferList // Max size of the pipe in bytes. When this max has been reached, // writers will get EWOULDBLOCK. @@ -170,13 +169,12 @@ func (p *Pipe) read(ctx context.Context, dst usermem.IOSequence) (int64, error) return 0, syserror.ErrWouldBlock } var n int64 - for b := p.data.Front(); b != nil; b = p.data.Front() { - buffer := b.(*Buffer) + for buffer := p.data.Front(); buffer != nil; buffer = p.data.Front() { n0, err := dst.CopyOut(ctx, buffer.bytes()) n += int64(n0) p.size -= n0 if buffer.truncate(n0) == 0 { - p.data.Remove(b) + p.data.Remove(buffer) } dst = dst.DropFirst(n0) if dst.NumBytes() == 0 || err != nil { diff --git a/pkg/waiter/BUILD b/pkg/waiter/BUILD index b748246da..48ce063d7 100644 --- a/pkg/waiter/BUILD +++ b/pkg/waiter/BUILD @@ -1,13 +1,28 @@ package(licenses = ["notice"]) +load("//tools/go_generics:defs.bzl", "go_template_instance") load("//tools/go_stateify:defs.bzl", "go_library", "go_test") +go_template_instance( + name = "waiter_list", + out = "waiter_list.go", + package = "waiter", + prefix = "waiter", + template = "//pkg/ilist:generic_list", + types = { + "Element": "*Entry", + "Linker": "*Entry", + }, +) + go_library( name = "waiter", - srcs = ["waiter.go"], + srcs = [ + "waiter.go", + "waiter_list.go", + ], importpath = "gvisor.googlesource.com/gvisor/pkg/waiter", visibility = ["//visibility:public"], - deps = ["//pkg/ilist"], ) go_test( @@ -18,3 +33,11 @@ go_test( ], embed = [":waiter"], ) + +filegroup( + name = "autogen", + srcs = [ + "waiter_list.go", + ], + visibility = ["//:sandbox"], +) diff --git a/pkg/waiter/waiter.go b/pkg/waiter/waiter.go index 93390b299..fd429f733 100644 --- a/pkg/waiter/waiter.go +++ b/pkg/waiter/waiter.go @@ -59,8 +59,6 @@ package waiter import ( "sync" - - "gvisor.googlesource.com/gvisor/pkg/ilist" ) // EventMask represents io events as used in the poll() syscall. @@ -127,7 +125,7 @@ type Entry struct { // The following fields are protected by the queue lock. mask EventMask - ilist.Entry + waiterEntry } type channelCallback struct{} @@ -162,7 +160,7 @@ func NewChannelEntry(c chan struct{}) (Entry, chan struct{}) { // // +stateify savable type Queue struct { - list ilist.List `state:"zerovalue"` + list waiterList `state:"zerovalue"` mu sync.RWMutex `state:"nosave"` } @@ -186,8 +184,7 @@ func (q *Queue) EventUnregister(e *Entry) { // in common with the notification mask. func (q *Queue) Notify(mask EventMask) { q.mu.RLock() - for it := q.list.Front(); it != nil; it = it.Next() { - e := it.(*Entry) + for e := q.list.Front(); e != nil; e = e.Next() { if mask&e.mask != 0 { e.Callback.Callback(e) } @@ -201,8 +198,7 @@ func (q *Queue) Events() EventMask { ret := EventMask(0) q.mu.RLock() - for it := q.list.Front(); it != nil; it = it.Next() { - e := it.(*Entry) + for e := q.list.Front(); e != nil; e = e.Next() { ret |= e.mask } q.mu.RUnlock() |