main f2d166b

reads.go RawHistoryFolder

1package drm
2
3import (
4	"os"
5	"time"
6
7	"golang.org/x/sys/unix"
8)
9
10// Fence holds: client buffers the GPU may still read.
11
12// dupFences duplicates the non-nil fences.
13func dupFences(fs ...*os.File) []*os.File {
14	var out []*os.File
15	for _, f := range fs {
16		if d := dupFence(f); d != nil {
17			out = append(out, d)
18		}
19	}
20	return out
21}
22
23// signalled reports whether every fence signalled (readable); an fd that
24// cannot be polled counts as signalled.
25func signalled(fs []*os.File) bool {
26	if len(fs) == 0 {
27		return true
28	}
29	pfds := make([]unix.PollFd, len(fs))
30	for i, f := range fs {
31		pfds[i] = unix.PollFd{Fd: int32(f.Fd()), Events: unix.POLLIN}
32	}
33	if _, err := unix.Poll(pfds, 0); err != nil {
34		return true
35	}
36	for _, p := range pfds {
37		if p.Revents == 0 {
38			return false
39		}
40	}
41	return true
42}
43
44// holdRead keeps the fences of a frame that was not committed. Reap old
45// completed reads even when no content publication asks for a report.
46func (o *Output) holdRead(fs ...*os.File) {
47	o.readDone()
48	o.readFences = append(o.readFences, dupFences(fs...)...)
49}
50
51// readDone reports whether no uncommitted frame may still read client
52// buffers, closing the fences that signalled.
53func (o *Output) readDone() bool {
54	kept := o.readFences[:0]
55	for _, f := range o.readFences {
56		if signalled([]*os.File{f}) {
57			f.Close()
58			continue
59		}
60		kept = append(kept, f)
61	}
62	clear(o.readFences[len(kept):])
63	o.readFences = kept
64	return len(kept) == 0
65}
66
67// dropRead closes the fences of uncommitted frames.
68func (o *Output) dropRead() {
69	for _, f := range o.readFences {
70		f.Close()
71	}
72	o.readFences = nil
73}
74
75// expire applies a lifecycle deadline and reports whether KMS needs a modeset.
76// Fence polling and logging stay at the output boundary, not in the value
77// transition; the lifecycle owns the decision and closes pending fences.
78func (o *Output) expire() bool {
79	now := time.Now()
80	serial, frame, age, busy, fences := o.frame.deadlineInfo(now)
81	ready := serial == 0 || !o.frame.deadlineReached(now) || signalled(fences)
82	switch o.frame.timeout(now, ready) {
83	case timeoutFence:
84		o.log.Warn().Str("connector", o.conn.name).Uint64("serial", serial).Dur("age", age).Msg("frame waits for GPU fence")
85	case timeoutBusy:
86		o.log.Warn().Str("connector", o.conn.name).Str("kind", "busy").Dur("age", busy).Msg("commits refused as busy; modeset")
87		return true
88	case timeoutMissing:
89		kind := "state"
90		if frame {
91			kind = "frame"
92		}
93		o.log.Warn().Str("connector", o.conn.name).Uint64("serial", serial).Str("kind", kind).Dur("age", age).Msg("commit event missing; modeset")
94		return true
95	}
96	return false
97}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close