aboutsummaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-05-29 14:33:50 +0200
committerGitHub <noreply@github.com>2017-05-29 14:33:50 +0200
commitbaf825803c72cdc02bed92a5f84ec43482aa35d3 (patch)
treec9594f9450bb91ce03a5f671f53755c193077ef3 /sys
parent145e067777cb0d21644412548e67dcb934f1da5e (diff)
parenteaf1f711fc42235d0b9a73c6877d14b1b5244194 (diff)
Merge pull request #196 from dvyukov/executor-fault-inject3
fault injection and faster tests
Diffstat (limited to 'sys')
-rw-r--r--sys/align.go2
-rw-r--r--sys/decl.go110
-rw-r--r--sys/decl_test.go2
3 files changed, 102 insertions, 12 deletions
diff --git a/sys/align.go b/sys/align.go
index e1ce27d56..00d464bcb 100644
--- a/sys/align.go
+++ b/sys/align.go
@@ -32,7 +32,7 @@ func initAlign() {
}
}
- for _, s := range Structs {
+ for _, s := range keyedStructs {
rec(s)
}
}
diff --git a/sys/decl.go b/sys/decl.go
index 270ae4582..28c18d488 100644
--- a/sys/decl.go
+++ b/sys/decl.go
@@ -430,7 +430,86 @@ func (t *UnionType) Align() uintptr {
return align
}
-var ctors = make(map[string][]*Call)
+var (
+ CallMap = make(map[string]*Call)
+ structs map[string]Type
+ keyedStructs map[structKey]Type
+ Resources map[string]*ResourceDesc
+ ctors = make(map[string][]*Call)
+)
+
+type structKey struct {
+ name string
+ field string
+ dir Dir
+}
+
+func getStruct(key structKey) Type {
+ if structs == nil {
+ structs = make(map[string]Type)
+ keyedStructs = make(map[structKey]Type)
+ for _, str := range structArray {
+ structs[str.Name()] = str
+ }
+ }
+ str := keyedStructs[key]
+ if str == nil {
+ proto := structs[key.name]
+ if proto == nil {
+ panic(fmt.Sprintf("missing struct prototype for %v", key.name))
+ }
+ switch typed := proto.(type) {
+ case *StructType:
+ newStr := new(StructType)
+ *newStr = *typed
+ newStr.FldName = key.field
+ newStr.ArgDir = key.dir
+ str = newStr
+ case *UnionType:
+ newStr := new(UnionType)
+ *newStr = *typed
+ newStr.FldName = key.field
+ newStr.ArgDir = key.dir
+ str = newStr
+ default:
+ panic(fmt.Sprintf("unexpected type of struct prototype for %v: %+v", key.name, proto))
+ }
+ keyedStructs[key] = str
+ }
+ return str
+}
+
+func initStructFields() {
+ missed := 0
+ for _, f := range structFields {
+ untyped := keyedStructs[f.key]
+ if untyped == nil {
+ missed++
+ continue
+ }
+ switch str := untyped.(type) {
+ case *StructType:
+ str.Fields = f.fields
+ case *UnionType:
+ str.Options = f.fields
+ default:
+ panic(fmt.Sprintf("unexpected type of struct prototype for %v: %+v", f.key.name, untyped))
+ }
+ }
+ fmt.Printf("missed %v/%v\n", missed, len(structFields))
+}
+
+func resource(name string) *ResourceDesc {
+ if Resources == nil {
+ // This is first called during init of sys package, so does not need to be thread-safe.
+ // resourceArray is in sys_GOARCH.go (generated by sysgen).
+ Resources = make(map[string]*ResourceDesc)
+ for _, res := range resourceArray {
+ Resources[res.Name] = res
+ }
+ }
+ return Resources[name]
+}
// ResourceConstructors returns a list of calls that can create a resource of the given kind.
func ResourceConstructors(name string) []*Call {
@@ -438,8 +517,9 @@ func ResourceConstructors(name string) []*Call {
}
func initResources() {
- for name, res := range Resources {
- ctors[name] = resourceCtors(res.Kind, false)
+ resource("") // init resources, if it's not done yet
+ for _, res := range resourceArray {
+ ctors[res.Name] = resourceCtors(res.Kind, false)
}
}
@@ -521,14 +601,26 @@ func TransitivelyEnabledCalls(enabled map[*Call]bool) map[*Call]bool {
for c := range enabled {
supported[c] = true
}
+ inputResources := make(map[*Call][]*ResourceType)
+ ctors := make(map[string][]*Call)
+ for c := range supported {
+ inputs := c.InputResources()
+ inputResources[c] = inputs
+ for _, res := range inputs {
+ if _, ok := ctors[res.Desc.Name]; ok {
+ continue
+ }
+ ctors[res.Desc.Name] = resourceCtors(res.Desc.Kind, true)
+ }
+ }
for {
n := len(supported)
haveGettime := supported[CallMap["clock_gettime"]]
for c := range supported {
canCreate := true
- for _, res := range c.InputResources() {
+ for _, res := range inputResources[c] {
noctors := true
- for _, ctor := range resourceCtors(res.Desc.Kind, true) {
+ for _, ctor := range ctors[res.Desc.Name] {
if supported[ctor] {
noctors = false
break
@@ -599,16 +691,12 @@ func ForeachType(meta *Call, f func(Type)) {
}
}
-var (
- Calls []*Call
- CallMap = make(map[string]*Call)
-)
-
func init() {
- initCalls()
initStructFields()
initResources()
initAlign()
+ keyedStructs = nil
+ structs = nil
for i, c := range Calls {
c.ID = i
diff --git a/sys/decl_test.go b/sys/decl_test.go
index c41a95e43..18385c321 100644
--- a/sys/decl_test.go
+++ b/sys/decl_test.go
@@ -8,6 +8,7 @@ import (
)
func TestTransitivelyEnabledCalls(t *testing.T) {
+ t.Parallel()
calls := make(map[*Call]bool)
for _, c := range Calls {
calls[c] = true
@@ -37,6 +38,7 @@ func TestTransitivelyEnabledCalls(t *testing.T) {
}
func TestClockGettime(t *testing.T) {
+ t.Parallel()
calls := make(map[*Call]bool)
for _, c := range Calls {
calls[c] = true