Skip to content

Commit

Permalink
improve API to allow triple lockstep schemes
Browse files Browse the repository at this point in the history
  • Loading branch information
abarisani committed Oct 30, 2024
1 parent e5acae8 commit e43b24e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 14 deletions.
10 changes: 7 additions & 3 deletions monitor/exec_arm.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,11 @@ func (ctx *ExecCtx) Mode() (current int, saved int) {
return
}

func (ctx *ExecCtx) schedule() (err error) {
// Schedule runs the execution context until an exception is caught.
//
// Unlike Run() the function does not invoke the context Handler(), there
// exceptions and system or monitor calls are not handled.
func (ctx *ExecCtx) Schedule() (err error) {
mux.Lock()
defer mux.Unlock()

Expand Down Expand Up @@ -236,12 +240,12 @@ func (ctx *ExecCtx) Run() (err error) {
}

for ctx.run {
if err = ctx.schedule(); err != nil {
if err = ctx.Schedule(); err != nil {
break
}

if ctx.Shadow != nil {
if err = ctx.Shadow.lockstep(); err != nil {
if err = ctx.Shadow.lockstep(ctx); err != nil {
break
}
}
Expand Down
16 changes: 8 additions & 8 deletions monitor/exec_lockstep.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,32 @@ import (
"errors"
)

// castShadow builds a shadow execution context suitable for lockstep()
func (ctx *ExecCtx) castShadow() *ExecCtx {
shadow := *ctx
shadow.Handler = nil
shadow.Shadow = ctx

return &shadow
}

// lockstep runs a shadow execution context for a single scheduling cycle, an
// error is raised when the resulting state differs from the primary execution
// context.
func (ctx *ExecCtx) lockstep() (err error) {
ctx.Lockstep(true)
defer ctx.Lockstep(false)
func (shadow *ExecCtx) lockstep(primary *ExecCtx) (err error) {
shadow.Lockstep(true)
defer shadow.Lockstep(false)

if err = ctx.schedule(); err != nil {
if err = shadow.Schedule(); err != nil {
return
}

if ctx.Handler != nil {
if err = ctx.Handler(ctx); err != nil {
if shadow.Handler != nil {
if err = shadow.Handler(primary); err != nil {
return
}
}

if !Equal(ctx, ctx.Shadow) {
if !Equal(primary, shadow) {
return errors.New("lockstep failure")
}

Expand Down
10 changes: 7 additions & 3 deletions monitor/exec_riscv64.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,11 @@ func (ctx *ExecCtx) Cause() (code uint64, irq bool) {
return
}

func (ctx *ExecCtx) schedule() (err error) {
// Schedule runs the execution context until an exception is caught.
//
// Unlike Run() the function does not invoke the context Handler(), there
// exceptions and system or monitor calls are not handled.
func (ctx *ExecCtx) Schedule() (err error) {
var pmpEntry int

mux.Lock()
Expand Down Expand Up @@ -227,12 +231,12 @@ func (ctx *ExecCtx) Run() (err error) {
}

for ctx.run {
if err = ctx.schedule(); err != nil {
if err = ctx.Schedule(); err != nil {
break
}

if ctx.Shadow != nil {
if err = ctx.Shadow.lockstep(); err != nil {
if err = ctx.Shadow.lockstep(ctx); err != nil {
break
}
}
Expand Down
6 changes: 6 additions & 0 deletions monitor/exec_stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ func (ctx *ExecCtx) Cause() (code uint64, irq bool)
// Mode (ARM) returns the processor mode.
func (ctx *ExecCtx) Mode() (current int, saved int)

// Schedule runs the execution context until an exception is caught.
//
// Unlike Run() the function does not invoke the context Handler(), there
// exceptions and system or monitor calls are not handled.
func (ctx *ExecCtx) Schedule() (err error) {

// Run starts the execution context and handles system or monitor calls. The
// execution yields back to the invoking Go runtime only when exceptions are
// caught.
Expand Down

0 comments on commit e43b24e

Please sign in to comment.