summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/seccheck/seccheck_fieldenum.go
blob: b193b2973f521e55f0dc5910a31d3e5154d1d508 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Generated by go_fieldenum.

package seccheck

import "sync/atomic"

// A CloneField represents a field in CloneInfo.
type CloneField uint

// CloneFieldX represents CloneInfo field X.
const (
	CloneFieldCredentials CloneField = iota
	CloneFieldArgs
)

// CloneFields represents a set of fields in CloneInfo in a literal-friendly form.
// The zero value of CloneFields represents an empty set.
type CloneFields struct {
	Invoker TaskFields
	Credentials bool
	Args bool
	Created TaskFields
}

// CloneFieldSet represents a set of fields in CloneInfo in a compact form.
// The zero value of CloneFieldSet represents an empty set.
type CloneFieldSet struct {
	Invoker TaskFieldSet
	Created TaskFieldSet
	fields [1]uint32
}

// Contains returns true if f is present in the CloneFieldSet.
func (fs CloneFieldSet) Contains(f CloneField) bool {
	return fs.fields[0] & (uint32(1) << uint(f)) != 0
}

// Add adds f to the CloneFieldSet.
func (fs *CloneFieldSet) Add(f CloneField) {
	fs.fields[0] |= uint32(1) << uint(f)
}

// Remove removes f from the CloneFieldSet.
func (fs *CloneFieldSet) Remove(f CloneField) {
	fs.fields[0] &^= uint32(1) << uint(f)
}

// Load returns a copy of the CloneFieldSet.
// Load is safe to call concurrently with AddFieldsLoadable, but not Add or Remove.
func (fs *CloneFieldSet) Load() (copied CloneFieldSet) {
	copied.Invoker = fs.Invoker.Load()
	copied.Created = fs.Created.Load()
	copied.fields[0] = atomic.LoadUint32(&fs.fields[0])
	return
}

// AddFieldsLoadable adds the given fields to the CloneFieldSet.
// AddFieldsLoadable is safe to call concurrently with Load, but not other methods (including other calls to AddFieldsLoadable).
func (fs *CloneFieldSet) AddFieldsLoadable(fields CloneFields) {
	fs.Invoker.AddFieldsLoadable(fields.Invoker)
	fs.Created.AddFieldsLoadable(fields.Created)
	if fields.Credentials {
		atomic.StoreUint32(&fs.fields[0], fs.fields[0] | (uint32(1) << uint(CloneFieldCredentials)))
	}
	if fields.Args {
		atomic.StoreUint32(&fs.fields[0], fs.fields[0] | (uint32(1) << uint(CloneFieldArgs)))
	}
}

// A TaskField represents a field in TaskInfo.
type TaskField uint

// TaskFieldX represents TaskInfo field X.
const (
	TaskFieldThreadID TaskField = iota
	TaskFieldThreadStartTime
	TaskFieldThreadGroupID
	TaskFieldThreadGroupStartTime
)

// TaskFields represents a set of fields in TaskInfo in a literal-friendly form.
// The zero value of TaskFields represents an empty set.
type TaskFields struct {
	ThreadID bool
	ThreadStartTime bool
	ThreadGroupID bool
	ThreadGroupStartTime bool
}

// TaskFieldSet represents a set of fields in TaskInfo in a compact form.
// The zero value of TaskFieldSet represents an empty set.
type TaskFieldSet struct {
	fields [1]uint32
}

// Contains returns true if f is present in the TaskFieldSet.
func (fs TaskFieldSet) Contains(f TaskField) bool {
	return fs.fields[0] & (uint32(1) << uint(f)) != 0
}

// Add adds f to the TaskFieldSet.
func (fs *TaskFieldSet) Add(f TaskField) {
	fs.fields[0] |= uint32(1) << uint(f)
}

// Remove removes f from the TaskFieldSet.
func (fs *TaskFieldSet) Remove(f TaskField) {
	fs.fields[0] &^= uint32(1) << uint(f)
}

// Load returns a copy of the TaskFieldSet.
// Load is safe to call concurrently with AddFieldsLoadable, but not Add or Remove.
func (fs *TaskFieldSet) Load() (copied TaskFieldSet) {
	copied.fields[0] = atomic.LoadUint32(&fs.fields[0])
	return
}

// AddFieldsLoadable adds the given fields to the TaskFieldSet.
// AddFieldsLoadable is safe to call concurrently with Load, but not other methods (including other calls to AddFieldsLoadable).
func (fs *TaskFieldSet) AddFieldsLoadable(fields TaskFields) {
	if fields.ThreadID {
		atomic.StoreUint32(&fs.fields[0], fs.fields[0] | (uint32(1) << uint(TaskFieldThreadID)))
	}
	if fields.ThreadStartTime {
		atomic.StoreUint32(&fs.fields[0], fs.fields[0] | (uint32(1) << uint(TaskFieldThreadStartTime)))
	}
	if fields.ThreadGroupID {
		atomic.StoreUint32(&fs.fields[0], fs.fields[0] | (uint32(1) << uint(TaskFieldThreadGroupID)))
	}
	if fields.ThreadGroupStartTime {
		atomic.StoreUint32(&fs.fields[0], fs.fields[0] | (uint32(1) << uint(TaskFieldThreadGroupStartTime)))
	}
}