diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-05-29 14:33:50 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-05-29 14:33:50 +0200 |
| commit | baf825803c72cdc02bed92a5f84ec43482aa35d3 (patch) | |
| tree | c9594f9450bb91ce03a5f671f53755c193077ef3 /sys | |
| parent | 145e067777cb0d21644412548e67dcb934f1da5e (diff) | |
| parent | eaf1f711fc42235d0b9a73c6877d14b1b5244194 (diff) | |
Merge pull request #196 from dvyukov/executor-fault-inject3
fault injection and faster tests
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/align.go | 2 | ||||
| -rw-r--r-- | sys/decl.go | 110 | ||||
| -rw-r--r-- | sys/decl_test.go | 2 |
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 |
