Fairness
Fairness ensures actions eventually execute under certain conditions.
No guarantees - action may starve:
action MayStarve:
counter = counter + 1
# May never execute even if always enabled
Eventually executes if continuously enabled:
fair action EventuallyRuns:
if condition:
done = True
# Will execute if condition stays true
Use case: Actions that should run when persistently enabled
Eventually executes if infinitely often enabled:
fair<strong> action RunsEventually:
if toggle:
processed = True
# Will execute even if toggle alternates
Use case: Actions enabled intermittently
Fairness is required for liveness properties:
fair action Progress:
counter = counter + 1
eventually always assertion EventuallyDone:
return counter >= 10
# Passes because fair action ensures progress
Fairness can be combined with flow modifiers (remember: flow modifier comes first):
# Atomic + weak fairness
atomic fair action ProduceMessage:
require len(queue) < MAX_SIZE
message = create_message()
queue.append(message)
# Executes atomically AND eventually runs if continuously enabled
# Atomic + strong fairness
atomic fair<strong> action ConsumeMessage:
require len(queue) > 0
message = queue.pop(0)
process(message)
# Executes atomically AND eventually runs if infinitely often enabled
# Serial (default) + weak fairness
fair action BackgroundTask:
step1 = prepare() # Yield point
step2 = execute() # Yield point
# Can crash at yield points, but will eventually run if continuously enabled
Important: The modifier order is always atomic fair action, never fair atomic action.
Unfair actions may never execute even if enabled
Demonstrates: default unfair behavior, liveness can fail
|
|
Expected result (from fizz):
StateSpaceOptions: options:{max_actions:100 max_concurrent_actions:2}
Nodes: 7, queued: 0
Valid Nodes: 7 Unique states: 7
IsLive: true
PASSED: Model checker completed successfully
Weakly fair actions eventually execute if continuously enabled
Demonstrates: fair<weak> or fair (default fairness level)
|
|
Expected result (from fizz):
StateSpaceOptions: options:{max_actions:100 max_concurrent_actions:2}
Nodes: 7, queued: 0
Valid Nodes: 7 Unique states: 7
Checking eventually always EventuallyDone
IsLive: true
PASSED: Model checker completed successfully
Strongly fair actions execute if infinitely often enabled
Demonstrates: fair<strong> for intermittent enabling
|
|
Expected result (from fizz):
StateSpaceOptions: options:{max_actions:100 max_concurrent_actions:2}
Nodes: 4, queued: 0
Valid Nodes: 4 Unique states: 4
IsLive: true
PASSED: Model checker completed successfully