From 526709ff0442e985edd498e14c736de8302dc867 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Tue, 3 Sep 2019 17:02:04 +0200 Subject: prog: move all flag mutation logic into flags() (#1362) This makes it a bit easier to understand. Also fix an issue with using flag value as bit number. --- prog/mutation.go | 22 +--------------------- prog/rand.go | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/prog/mutation.go b/prog/mutation.go index 8a33c3e2e..6c356c4b4 100644 --- a/prog/mutation.go +++ b/prog/mutation.go @@ -236,29 +236,9 @@ func (t *IntType) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Ca func (t *FlagsType) mutate(r *randGen, s *state, arg Arg, ctx ArgCtx) (calls []*Call, retry, preserve bool) { a := arg.(*ConstArg) - for oldVal := a.Val; oldVal == a.Val; { - // Generate a new value. - if r.nOutOf(1, 5) { - a.Val = r.flags(t.Vals, t.BitMask, 0) - continue - } - - if !t.BitMask || (t.BitMask && r.nOutOf(1, 4)) { - a.Val = r.flags(t.Vals, t.BitMask, a.Val) - continue - } - - for stop := false; !stop; stop = r.oneOf(3) { - idx := r.rand(len(t.Vals)) - if r.bin() { - a.Val |= 1 << t.Vals[idx] - } else { - a.Val &= ^(1 << t.Vals[idx]) - } - } + a.Val = r.flags(t.Vals, t.BitMask, a.Val) } - return } diff --git a/prog/rand.go b/prog/rand.go index 819b1104f..cbfc960a8 100644 --- a/prog/rand.go +++ b/prog/rand.go @@ -140,13 +140,31 @@ func (r *randGen) randPageCount() (n uint64) { // Change a flag value or generate a new one. func (r *randGen) flags(vv []uint64, bitmask bool, oldVal uint64) (v uint64) { v = oldVal + if r.oneOf(5) { + // Ignore the old value sometimes. + v = 0 + } switch { case (bitmask && r.nOutOf(7, 10)) || (!bitmask && r.nOutOf(1, 5)): - for stop := false; !stop; stop = r.bin() { - v |= vv[r.rand(len(vv))] // prioritized when bitmask = true + // Try flipping randomly chosen flags. + // Prioritized when bitmask == true. + for stop := false; !stop; stop = r.oneOf(3) { + flag := vv[r.rand(len(vv))] + if r.oneOf(5) { + // Try choosing adjacent bit values in case we forgot + // to add all relevant flags to the descriptions. + if r.bin() { + flag >>= 1 + } else { + flag <<= 1 + } + } + v ^= flag } case (bitmask && r.nOutOf(2, 3)) || (!bitmask && r.nOutOf(7, 8)): - v = vv[r.rand(len(vv))] // prioritized when bitmask = false + // Chose a random flag. + // Prioritized when bitmask == false. + v = vv[r.rand(len(vv))] case r.bin(): v = 0 default: -- cgit mrf-deployment