akita

package module
v1.12.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2021 License: MIT Imports: 10 Imported by: 68

README

Project Akita

Project Akita is a framework for computer architecture simulators. This repository is an architecture-agnostic simulator framework that defines essential concepts like Component and Events.

Please see here for detailed documentations.

Documentation

Overview

Package akita is a package that provides basic functionalities to build discrete event simulator.

Example (PingWithEvents)
package main

import (
	"fmt"
	"reflect"

	"gitlab.com/akita/akita"
)

type PingMsg struct {
	akita.MsgMeta

	SeqID int
}

func (p *PingMsg) Meta() *akita.MsgMeta {
	return &p.MsgMeta
}

type PingRsp struct {
	akita.MsgMeta

	SeqID int
}

func (p *PingRsp) Meta() *akita.MsgMeta {
	return &p.MsgMeta
}

type StartPingEvent struct {
	*akita.EventBase
	Dst akita.Port
}

type RspPingEvent struct {
	*akita.EventBase
	pingMsg *PingMsg
}

type PingAgent struct {
	*akita.ComponentBase

	Engine  akita.Engine
	OutPort akita.Port

	startTime []akita.VTimeInSec
	nextSeqID int
}

func NewPingAgent(name string, engine akita.Engine) *PingAgent {
	agent := &PingAgent{Engine: engine}
	agent.ComponentBase = akita.NewComponentBase(name)
	agent.OutPort = akita.NewLimitNumMsgPort(agent, 4, name+".OutPort")
	return agent
}

func (p *PingAgent) Handle(e akita.Event) error {
	p.Lock()
	defer p.Unlock()

	switch e := e.(type) {
	case StartPingEvent:
		p.StartPing(e)
	case RspPingEvent:
		p.RspPing(e)
	default:
		panic("cannot handle event of type " + reflect.TypeOf(e).String())
	}
	return nil
}

func (p *PingAgent) StartPing(evt StartPingEvent) {
	pingMsg := &PingMsg{
		SeqID: p.nextSeqID,
	}

	pingMsg.Src = p.OutPort
	pingMsg.Dst = evt.Dst
	pingMsg.SendTime = evt.Time()

	p.OutPort.Send(pingMsg)

	p.startTime = append(p.startTime, evt.Time())

	p.nextSeqID++
}

func (p *PingAgent) RspPing(evt RspPingEvent) {
	msg := evt.pingMsg
	rsp := &PingRsp{
		SeqID: msg.SeqID,
	}
	rsp.SendTime = evt.Time()
	rsp.Src = p.OutPort
	rsp.Dst = msg.Src

	p.OutPort.Send(rsp)
}

func (p *PingAgent) NotifyRecv(now akita.VTimeInSec, port akita.Port) {
	p.Lock()
	defer p.Unlock()

	msg := port.Retrieve(now)
	switch msg := msg.(type) {
	case *PingMsg:
		p.processPingMsg(now, msg)
	case *PingRsp:
		p.processPingRsp(now, msg)
	default:
		panic("cannot process msg of type " + reflect.TypeOf(msg).String())
	}
}

func (p *PingAgent) processPingMsg(now akita.VTimeInSec, msg *PingMsg) {
	rspEvent := RspPingEvent{
		EventBase: akita.NewEventBase(now+2, p),
		pingMsg:   msg,
	}
	p.Engine.Schedule(rspEvent)
}

func (p *PingAgent) processPingRsp(now akita.VTimeInSec, msg *PingRsp) {
	seqID := msg.SeqID
	startTime := p.startTime[seqID]
	duration := now - startTime

	fmt.Printf("Ping %d, %.2f\n", seqID, duration)
}

func (p PingAgent) NotifyPortFree(now akita.VTimeInSec, port akita.Port) {
	// Do nothing
}

func main() {
	engine := akita.NewSerialEngine()
	agentA := NewPingAgent("AgentA", engine)
	agentB := NewPingAgent("AgentB", engine)
	conn := akita.NewDirectConnection("Conn", engine, 1*akita.GHz)

	conn.PlugIn(agentA.OutPort, 1)
	conn.PlugIn(agentB.OutPort, 1)

	e1 := StartPingEvent{
		EventBase: akita.NewEventBase(1, agentA),
		Dst:       agentB.OutPort,
	}
	e2 := StartPingEvent{
		EventBase: akita.NewEventBase(3, agentA),
		Dst:       agentB.OutPort,
	}
	engine.Schedule(e1)
	engine.Schedule(e2)

	engine.Run()
}
Output:

Ping 0, 2.00
Ping 1, 2.00
Example (PingWithTicking)
package main

import (
	"fmt"

	"gitlab.com/akita/akita"
)

type pingTransaction struct {
	req       *PingMsg
	cycleLeft int
}

type TickingPingAgent struct {
	*akita.TickingComponent

	OutPort akita.Port

	currentTransactions []*pingTransaction
	startTime           []akita.VTimeInSec
	numPingNeedToSend   int
	nextSeqID           int
	pingDst             akita.Port
}

func NewTickingPingAgent(
	name string,
	engine akita.Engine,
	freq akita.Freq,
) *TickingPingAgent {
	a := &TickingPingAgent{}
	a.TickingComponent = akita.NewTickingComponent(name, engine, freq, a)
	a.OutPort = akita.NewLimitNumMsgPort(a, 4, a.Name()+".OutPort")
	return a
}

func (a *TickingPingAgent) Tick(now akita.VTimeInSec) bool {
	madeProgress := false

	madeProgress = a.sendRsp(now) || madeProgress
	madeProgress = a.sendPing(now) || madeProgress
	madeProgress = a.countDown() || madeProgress
	madeProgress = a.processInput(now) || madeProgress

	return madeProgress
}

func (a *TickingPingAgent) processInput(now akita.VTimeInSec) bool {
	msg := a.OutPort.Peek()
	if msg == nil {
		return false
	}

	switch msg := msg.(type) {
	case *PingMsg:
		a.processingPingMsg(now, msg)
	case *PingRsp:
		a.processingPingRsp(now, msg)
	default:
		panic("unknown message type")
	}

	return true
}

func (a *TickingPingAgent) processingPingMsg(
	now akita.VTimeInSec,
	ping *PingMsg,
) {
	trans := &pingTransaction{
		req:       ping,
		cycleLeft: 2,
	}
	a.currentTransactions = append(a.currentTransactions, trans)
	a.OutPort.Retrieve(now)
}

func (a *TickingPingAgent) processingPingRsp(
	now akita.VTimeInSec,
	msg *PingRsp,
) {
	seqID := msg.SeqID
	startTime := a.startTime[seqID]
	duration := now - startTime

	fmt.Printf("Ping %d, %.2f\n", seqID, duration)
	a.OutPort.Retrieve(now)
}

func (a *TickingPingAgent) countDown() bool {
	madeProgress := false
	for _, trans := range a.currentTransactions {
		if trans.cycleLeft > 0 {
			trans.cycleLeft--
			madeProgress = true
		}
	}
	return madeProgress
}

func (a *TickingPingAgent) sendRsp(now akita.VTimeInSec) bool {
	if len(a.currentTransactions) == 0 {
		return false
	}

	trans := a.currentTransactions[0]
	if trans.cycleLeft > 0 {
		return false
	}

	rsp := &PingRsp{
		SeqID: trans.req.SeqID,
	}
	rsp.SendTime = now
	rsp.Src = a.OutPort
	rsp.Dst = trans.req.Src

	err := a.OutPort.Send(rsp)
	if err != nil {
		return false
	}

	a.currentTransactions = a.currentTransactions[1:]

	return true
}

func (a *TickingPingAgent) sendPing(now akita.VTimeInSec) bool {
	if a.numPingNeedToSend == 0 {
		return false
	}

	pingMsg := &PingMsg{
		SeqID: a.nextSeqID,
	}
	pingMsg.Src = a.OutPort
	pingMsg.Dst = a.pingDst
	pingMsg.SendTime = now

	err := a.OutPort.Send(pingMsg)
	if err != nil {
		return false
	}

	a.startTime = append(a.startTime, now)
	a.numPingNeedToSend--
	a.nextSeqID++

	return true
}

func main() {
	engine := akita.NewSerialEngine()
	agentA := NewTickingPingAgent("AgentA", engine, 1*akita.Hz)
	agentB := NewTickingPingAgent("AgentB", engine, 1*akita.Hz)
	conn := akita.NewDirectConnection("Conn", engine, 1*akita.GHz)

	conn.PlugIn(agentA.OutPort, 1)
	conn.PlugIn(agentB.OutPort, 1)

	agentA.pingDst = agentB.OutPort
	agentA.numPingNeedToSend = 2

	agentA.TickLater(0)

	engine.Run()
}
Output:

Ping 0, 5.00
Ping 1, 5.00

Index

Examples

Constants

This section is empty.

Variables

View Source
var HookPosAfterEvent = &HookPos{Name: "AfterEvent"}

HookPosAfterEvent is a hook position that triggers after handling an event

View Source
var HookPosBeforeEvent = &HookPos{Name: "BeforeEvent"}

HookPosBeforeEvent is a hook position that triggers before handling an event

View Source
var HookPosConnDeliver = &HookPos{Name: "Conn Deliver"}

HookPosConnDeliver marks a connection delivered a message.

View Source
var HookPosConnDoneTrans = &HookPos{Name: "Conn Done Trans"}

HookPosConnDoneTrans marks a connection complete transmitting a message.

View Source
var HookPosConnStartSend = &HookPos{Name: "Conn Start Send"}

HookPosConnStartSend marks a connection accept to send a message.

View Source
var HookPosConnStartTrans = &HookPos{Name: "Conn Start Trans"}

HookPosConnStartTrans marks a connection start to transmit a message.

View Source
var HookPosPortMsgRecvd = &HookPos{Name: "Port Msg Recv"}

HookPosPortMsgRecvd marks when an inbound message arrives at a the given port

View Source
var HookPosPortMsgRetrieve = &HookPos{Name: "Port Msg  Retrieve"}

HookPosPortMsgRetrieve marks when an outbound message is sent over a connection

Functions

func UseParallelIDGenerator added in v1.4.1

func UseParallelIDGenerator()

UseParallelIDGenerator configurs the ID generator to generate ID in parallel. The IDs generated will not be deterministic anymore.

func UseSequentialIDGenerator added in v1.4.1

func UseSequentialIDGenerator()

UseSequentialIDGenerator configures the ID generator to generate IDs in sequential.

Types

type Component

type Component interface {
	Named
	Handler
	Hookable

	NotifyRecv(now VTimeInSec, port Port)
	NotifyPortFree(now VTimeInSec, port Port)
}

A Component is a element that is being simulated in Akita.

type ComponentBase

type ComponentBase struct {
	HookableBase
	sync.Mutex
	// contains filtered or unexported fields
}

ComponentBase provides some functions that other component can use

func NewComponentBase

func NewComponentBase(name string) *ComponentBase

NewComponentBase creates a new ComponentBase

func (*ComponentBase) Name

func (c *ComponentBase) Name() string

Name returns the name of the BasicComponent

type Connection

type Connection interface {
	Hookable

	Send(msg Msg) *SendError

	// PlugIn connects a port to the connection. The connection should reserve
	// a buffer that can hold `sourceSideBufSize` messages.
	PlugIn(port Port, sourceSideBufSize int)
	Unplug(port Port)
	NotifyAvailable(now VTimeInSec, port Port)
}

A Connection is responsible for delivering messages to its destination.

type DirectConnection

type DirectConnection struct {
	*TickingComponent
	// contains filtered or unexported fields
}

DirectConnection connects two components without latency

func NewDirectConnection

func NewDirectConnection(
	name string,
	engine Engine,
	freq Freq,
) *DirectConnection

NewDirectConnection creates a new DirectConnection object

func (*DirectConnection) NotifyAvailable

func (c *DirectConnection) NotifyAvailable(now VTimeInSec, port Port)

NotifyAvailable is called by a port to notify that the connection can deliver to the port again.

func (*DirectConnection) PlugIn

func (c *DirectConnection) PlugIn(port Port, sourceSideBufSize int)

PlugIn marks the port connects to this DirectConnection.

func (*DirectConnection) Send

func (c *DirectConnection) Send(msg Msg) *SendError

Send of a DirectConnection schedules a DeliveryEvent immediately

func (*DirectConnection) Tick added in v1.8.0

func (c *DirectConnection) Tick(now VTimeInSec) bool

Tick updates the states of the connection and delivers messages.

func (*DirectConnection) Unplug

func (c *DirectConnection) Unplug(port Port)

Unplug marks the port no longer connects to this DirectConnection.

type Engine

type Engine interface {
	Hookable

	// Schedule registers an event to happen in the future
	Schedule(e Event)

	// Run will process all the events until the simulation finishes
	Run() error

	// Pause will pause the simulation until continue is called.
	Pause()

	// Continue will continue the paused simulation
	Continue()

	// CurrentTime will return the time at which the engine is at.
	CurrentTime() VTimeInSec

	// RegisterSimulationEndHandler registers a handler that perform some
	// actions after the simulation is finished.
	RegisterSimulationEndHandler(handler SimulationEndHandler)

	// Finished invokes all the registered SimulationEndHandler
	Finished()
}

An Engine is a unit that keeps the discrete event simulation run.

type Event

type Event interface {
	// Return the time that the event should happen
	Time() VTimeInSec

	// Returns the handler that can should handle the event
	Handler() Handler

	// IsSecondary tells if the event is a secondary event. Secondary event are
	// handled after all same-time primary events are handled.
	IsSecondary() bool
}

An Event is something going to happen in the future.

Example
package main

import (
	"fmt"
	"math/rand"

	"gitlab.com/akita/akita"
)

type SplitEvent struct {
	time    akita.VTimeInSec
	handler akita.Handler
}

func (e SplitEvent) Time() akita.VTimeInSec {
	return e.time
}
func (e SplitEvent) Handler() akita.Handler {
	return e.handler
}
func (e SplitEvent) IsSecondary() bool {
	return false
}

type SplitHandler struct {
	total  int
	engine akita.Engine
}

func (h *SplitHandler) Handle(evt akita.Event) error {
	h.total++
	now := evt.Time()
	nextTime := now + akita.VTimeInSec(rand.Float64()*2+0.5)
	if nextTime < 10.0 {
		nextEvt := SplitEvent{
			time:    nextTime,
			handler: h,
		}
		h.engine.Schedule(nextEvt)
	}
	nextTime = now + akita.VTimeInSec(rand.Float64()*2+0.5)
	if nextTime < 10.0 {
		nextEvt := SplitEvent{
			time:    nextTime,
			handler: h,
		}
		h.engine.Schedule(nextEvt)
	}
	return nil
}

func main() {
	rand.Seed(1)
	engine := akita.NewSerialEngine()
	splitHandler := SplitHandler{
		total:  0,
		engine: engine,
	}
	engine.Schedule(SplitEvent{
		time:    0,
		handler: &splitHandler,
	})
	engine.Run()
	fmt.Printf("Total number at time 10: %d\n", splitHandler.total)
}
Output:

Total number at time 10: 185

type EventBase

type EventBase struct {
	ID string
	// contains filtered or unexported fields
}

EventBase provides the basic fields and getters for other events

func NewEventBase

func NewEventBase(t VTimeInSec, handler Handler) *EventBase

NewEventBase creates a new EventBase

func (EventBase) Handler

func (e EventBase) Handler() Handler

Handler returns the handler to handle the event.

func (EventBase) IsSecondary added in v1.8.0

func (e EventBase) IsSecondary() bool

IsSecondary returns true if the event is a secondary event.

func (EventBase) SetHandler

func (e EventBase) SetHandler(h Handler)

SetHandler sets which handler that handles the event.

Akita requires all the components can only schedule event for themselves. Therefore, the handler in this function must be the component who schedule the event. The only exception is process of kicking starting of the simulation, where the kick starter can schedule to all components.

func (EventBase) Time

func (e EventBase) Time() VTimeInSec

Time return the time that the event is going to happen

type EventLogger

type EventLogger struct {
	LogHookBase
}

EventLogger is an hook that prints the event information

func NewEventLogger

func NewEventLogger(logger *log.Logger) *EventLogger

NewEventLogger returns a new LogEventHook which will write in to the logger

func (*EventLogger) Func

func (h *EventLogger) Func(ctx HookCtx)

Func writes the event information into the logger

type EventQueue

type EventQueue interface {
	Push(evt Event)
	Pop() Event
	Len() int
	Peek() Event
}

EventQueue are a queue of event ordered by the time of events

type EventQueueImpl

type EventQueueImpl struct {
	sync.Mutex
	// contains filtered or unexported fields
}

EventQueueImpl provides a thread safe event queue

func NewEventQueue

func NewEventQueue() *EventQueueImpl

NewEventQueue creates and returns a newly created EventQueue

func (*EventQueueImpl) Len

func (q *EventQueueImpl) Len() int

Len returns the number of event in the queue

func (*EventQueueImpl) Peek

func (q *EventQueueImpl) Peek() Event

Peek returns the event in front of the queue without removing it from the queue

func (*EventQueueImpl) Pop

func (q *EventQueueImpl) Pop() Event

Pop returns the next earliest event

func (*EventQueueImpl) Push

func (q *EventQueueImpl) Push(evt Event)

Push adds an event to the event queue

type Freq

type Freq float64

Freq defines the type of frequency

const (
	Hz  Freq = 1
	KHz Freq = 1e3
	MHz Freq = 1e6
	GHz Freq = 1e9
)

Defines the unit of frequency

func (Freq) Cycle

func (f Freq) Cycle(time VTimeInSec) uint64

Cycle converts a time to the number of cycles passed since time 0.

func (Freq) HalfTick

func (f Freq) HalfTick(t VTimeInSec) VTimeInSec

HalfTick returns the time in middle of two ticks

           Input
           (          ]
|----------|----------|----------|----->
                           |
                           Output

func (Freq) NCyclesLater

func (f Freq) NCyclesLater(n int, now VTimeInSec) VTimeInSec

NCyclesLater returns the time after N cycles

This function will always return a time of an integer number of cycles

func (Freq) NextTick

func (f Freq) NextTick(now VTimeInSec) VTimeInSec

NextTick returns the next tick time.

           Input
           [          )
|----------|----------|----------|----->
                      |
                      Output

func (Freq) NoEarlierThan

func (f Freq) NoEarlierThan(t VTimeInSec) VTimeInSec

NoEarlierThan returns the tick time that is at or right after the given time

func (Freq) Period

func (f Freq) Period() VTimeInSec

Period returns the time between two consecutive ticks

func (Freq) ThisTick

func (f Freq) ThisTick(now VTimeInSec) VTimeInSec

ThisTick returns the current tick time

           Input
           (          ]
|----------|----------|----------|----->
                      |
                      Output

type Handler

type Handler interface {
	Handle(e Event) error
}

A Handler defines a domain for the events.

One event is always constraint to one Handler, which means the event can only be scheduled by one handler and can only directly modify that handler.

type Hook

type Hook interface {
	// Func determines what to do if hook is invoked.
	Func(ctx HookCtx)
}

Hook is a short piece of program that can be invoked by a hookable object.

type HookCtx added in v1.3.0

type HookCtx struct {
	Domain Hookable
	Now    VTimeInSec
	Pos    *HookPos
	Item   interface{}
	Detail interface{}
}

HookCtx is the context that holds all the information about the site that a hook is triggered

type HookPos

type HookPos struct {
	Name string
}

HookPos defines the enum of possible hooking positions

type Hookable

type Hookable interface {
	// AcceptHook registers a hook
	AcceptHook(hook Hook)
}

Hookable defines an object that accept Hooks

type HookableBase

type HookableBase struct {
	Hooks []Hook
}

A HookableBase provides some utility function for other type that implement the Hookable interface.

func NewHookableBase

func NewHookableBase() *HookableBase

NewHookableBase creates a HookableBase object

func (*HookableBase) AcceptHook

func (h *HookableBase) AcceptHook(hook Hook)

AcceptHook register a hook

func (*HookableBase) InvokeHook

func (h *HookableBase) InvokeHook(ctx HookCtx)

InvokeHook triggers the register Hooks

type IDGenerator added in v1.4.1

type IDGenerator interface {
	// Generate an ID
	Generate() string
}

IDGenerator can generate IDs

func GetIDGenerator added in v1.4.1

func GetIDGenerator() IDGenerator

GetIDGenerator returns the ID generator used in the current simulation

type InsertionQueue

type InsertionQueue struct {
	// contains filtered or unexported fields
}

InsertionQueue is a queue that is based on insertion sort

func NewInsertionQueue

func NewInsertionQueue() *InsertionQueue

NewInsertionQueue returns a new InsertionQueue

func (*InsertionQueue) Len

func (q *InsertionQueue) Len() int

Len return the number of events in the queue

func (*InsertionQueue) Peek

func (q *InsertionQueue) Peek() Event

Peek returns the event at the front of the queue without removing it from the queue.

func (*InsertionQueue) Pop

func (q *InsertionQueue) Pop() Event

Pop returns the event with the smallest time, and removes it from the queue

func (*InsertionQueue) Push

func (q *InsertionQueue) Push(evt Event)

Push add an event to the event queue

type LimitNumMsgPort added in v1.4.0

type LimitNumMsgPort struct {
	HookableBase
	// contains filtered or unexported fields
}

LimitNumMsgPort is a type of port that can hold at most a certain number of messages.

func NewLimitNumMsgPort added in v1.4.0

func NewLimitNumMsgPort(
	comp Component,
	capacity int,
	name string,
) *LimitNumMsgPort

NewLimitNumMsgPort creates a new port that works for the provided component

func (*LimitNumMsgPort) Component added in v1.4.0

func (p *LimitNumMsgPort) Component() Component

Component returns the owner component of the port.

func (*LimitNumMsgPort) Name added in v1.5.0

func (p *LimitNumMsgPort) Name() string

Name returns the name of the port.

func (*LimitNumMsgPort) NotifyAvailable added in v1.4.0

func (p *LimitNumMsgPort) NotifyAvailable(now VTimeInSec)

NotifyAvailable is called by the connection to notify the port that the connection is available again

func (*LimitNumMsgPort) Peek added in v1.4.0

func (p *LimitNumMsgPort) Peek() Msg

Peek returns the first message in the port without removing it.

func (*LimitNumMsgPort) Recv added in v1.4.0

func (p *LimitNumMsgPort) Recv(msg Msg) *SendError

Recv is used to deliver a message to a component

func (*LimitNumMsgPort) Retrieve added in v1.4.0

func (p *LimitNumMsgPort) Retrieve(now VTimeInSec) Msg

Retrieve is used by the component to take a message from the incoming buffer

func (*LimitNumMsgPort) Send added in v1.4.0

func (p *LimitNumMsgPort) Send(msg Msg) *SendError

Send is used to send a message out from a component

func (*LimitNumMsgPort) SetConnection added in v1.4.0

func (p *LimitNumMsgPort) SetConnection(conn Connection)

SetConnection sets which connection plugged in to this port.

type LogHook

type LogHook interface {
	Hook
}

A LogHook is a hook that is resonsible for recording information from the simulation

type LogHookBase

type LogHookBase struct {
	*log.Logger
}

LogHookBase proovides the common logic for all LogHooks

type Msg added in v1.4.0

type Msg interface {
	Meta() *MsgMeta
}

A Msg is a piece of information that is transferred between components.

type MsgMeta added in v1.4.0

type MsgMeta struct {
	ID                 string
	Src, Dst           Port
	SendTime, RecvTime VTimeInSec
	EventTime          VTimeInSec
	TrafficClass       int
	TrafficBytes       int
}

MsgMeta contains the meta data that is attached to every message.

func (MsgMeta) IsSecondary added in v1.8.0

func (m MsgMeta) IsSecondary() bool

IsSecondary always returns true. Message-based events are all primary events.

type Named

type Named interface {
	Name() string
}

A Named object is an object that has a name

type ParallelEngine

type ParallelEngine struct {
	HookableBase
	// contains filtered or unexported fields
}

A ParallelEngine is an event engine that is capable for scheduling event in a parallel fashion

func NewParallelEngine

func NewParallelEngine() *ParallelEngine

NewParallelEngine creates a ParallelEngine

func (*ParallelEngine) Continue added in v1.2.0

func (e *ParallelEngine) Continue()

Continue allows the engine to continue to make progress.

func (*ParallelEngine) CurrentTime

func (e *ParallelEngine) CurrentTime() VTimeInSec

CurrentTime returns the current time at which the engine is at. Specifically, the run time of the current event.

func (*ParallelEngine) Finished

func (e *ParallelEngine) Finished()

Finished should be called after the simulation compeletes. It calls all the registered SimulationEndHandler

func (*ParallelEngine) Pause added in v1.2.0

func (e *ParallelEngine) Pause()

Pause will prevent the engine to move forward. For events that is scheduled at the same time, they may still be triggered.

func (*ParallelEngine) RegisterSimulationEndHandler

func (e *ParallelEngine) RegisterSimulationEndHandler(
	handler SimulationEndHandler,
)

RegisterSimulationEndHandler registers a handler to be called after the simulation ends.

func (*ParallelEngine) Run

func (e *ParallelEngine) Run() error

Run processes all the events scheduled in the SerialEngine

func (*ParallelEngine) Schedule

func (e *ParallelEngine) Schedule(evt Event)

Schedule register an event to be happen in the future

type Port

type Port interface {
	// Embed interface
	Named
	Hookable

	SetConnection(conn Connection)
	Component() Component

	// For connection
	Recv(msg Msg) *SendError
	NotifyAvailable(now VTimeInSec)

	// For component
	Send(msg Msg) *SendError
	Retrieve(now VTimeInSec) Msg
	Peek() Msg
}

A Port is owned by a component and is used to plugin connections

type PortEndSimulationChecker

type PortEndSimulationChecker struct {
	Port Port
}

PortEndSimulationChecker checks if the port buffer is empty at the end of the simulation. If the port is not empty, there is something wrong in the simulation.

func (*PortEndSimulationChecker) Handle

func (c *PortEndSimulationChecker) Handle(e Event) error

Handle checks if the port is empty or not.

type PortMsgLogger added in v1.6.0

type PortMsgLogger struct {
	LogHookBase
}

PortMsgLogger is a hook for logging messages as they go across a Port

func NewPortMsgLogger added in v1.6.0

func NewPortMsgLogger(logger *log.Logger) *PortMsgLogger

NewPortMsgLogger returns a new PortMsgLogger which will write into the logger

func (*PortMsgLogger) Func added in v1.6.0

func (h *PortMsgLogger) Func(ctx HookCtx)

Func writes the message information into the logger

type SendError

type SendError struct{}

SendError marks a failure send or receive

func NewSendError

func NewSendError() *SendError

NewSendError creates a SendError

type SerialEngine

type SerialEngine struct {
	HookableBase
	// contains filtered or unexported fields
}

A SerialEngine is an Engine that always run events one after another.

func NewSerialEngine

func NewSerialEngine() *SerialEngine

NewSerialEngine creates a SerialEngine

func (*SerialEngine) Continue added in v1.2.0

func (e *SerialEngine) Continue()

Continue allows the SerialEngine to trigger more events.

func (*SerialEngine) CurrentTime

func (e *SerialEngine) CurrentTime() VTimeInSec

CurrentTime returns the current time at which the engine is at. Specifically, the run time of the current event.

func (*SerialEngine) Finished

func (e *SerialEngine) Finished()

Finished should be called after the simulation ends. This function calls all the registered SimulationEndHandler.

func (*SerialEngine) Pause added in v1.2.0

func (e *SerialEngine) Pause()

Pause prevents the SerialEngine to trigger more events.

func (*SerialEngine) RegisterSimulationEndHandler

func (e *SerialEngine) RegisterSimulationEndHandler(
	handler SimulationEndHandler,
)

RegisterSimulationEndHandler invokes all the registered simulation end handler.

func (*SerialEngine) Run

func (e *SerialEngine) Run() error

Run processes all the events scheduled in the SerialEngine

func (*SerialEngine) Schedule

func (e *SerialEngine) Schedule(evt Event)

Schedule register an event to be happen in the future

type SimulationEndHandler

type SimulationEndHandler interface {
	Handle(now VTimeInSec)
}

A SimulationEndHandler is a handler that is called after the simulation ends.

type TickEvent

type TickEvent struct {
	EventBase
}

TickEvent is a generic event that almost all the component can use to update their status.

func MakeTickEvent added in v1.8.0

func MakeTickEvent(t VTimeInSec, handler Handler) TickEvent

MakeTickEvent creates a new TickEvent

type TickScheduler added in v1.8.0

type TickScheduler struct {
	Freq   Freq
	Engine Engine
	// contains filtered or unexported fields
}

TickScheduler can help schedule tick events.

func NewSecondaryTickScheduler added in v1.8.0

func NewSecondaryTickScheduler(
	handler Handler,
	engine Engine,
	freq Freq,
) *TickScheduler

NewSecondaryTickScheduler creates a scheduler that always schedule secondary tick events.

func NewTickScheduler added in v1.8.0

func NewTickScheduler(
	handler Handler,
	engine Engine,
	freq Freq,
) *TickScheduler

NewTickScheduler creates a scheduler for tick events.

func (*TickScheduler) TickLater added in v1.8.0

func (t *TickScheduler) TickLater(now VTimeInSec)

TickLater will schedule a tick event at the cycle after the now time.

func (*TickScheduler) TickNow added in v1.8.0

func (t *TickScheduler) TickNow(now VTimeInSec)

TickNow schedule a Tick event at the current time.

type Ticker

type Ticker interface {
	Tick(now VTimeInSec) bool
}

A Ticker is an object that updates states with ticks.

type TickingComponent

type TickingComponent struct {
	*ComponentBase
	*TickScheduler
	// contains filtered or unexported fields
}

TickingComponent is a type of component that update states from cycle to cycle. A programmer would only need to program a tick function for a ticking component.

func NewSecondaryTickingComponent added in v1.8.0

func NewSecondaryTickingComponent(
	name string,
	engine Engine,
	freq Freq,
	ticker Ticker,
) *TickingComponent

NewSecondaryTickingComponent creates a new ticking component

func NewTickingComponent

func NewTickingComponent(
	name string,
	engine Engine,
	freq Freq,
	ticker Ticker,
) *TickingComponent

NewTickingComponent creates a new ticking component

func (*TickingComponent) Handle added in v1.8.0

func (c *TickingComponent) Handle(e Event) error

Handle triggers the tick function of the TickingComponent

func (*TickingComponent) NotifyPortFree

func (c *TickingComponent) NotifyPortFree(
	now VTimeInSec,
	port Port,
)

NotifyPortFree triggers the TickingComponent to start ticking again.

func (*TickingComponent) NotifyRecv

func (c *TickingComponent) NotifyRecv(
	now VTimeInSec,
	port Port,
)

NotifyRecv triggers the TickingComponent to start ticking again.

type VTimeInSec

type VTimeInSec float64

VTimeInSec defines the time in the simulated space in the unit of second

Directories

Path Synopsis
Package monitoring provides a solution that allows monitoring simulation externally.
Package monitoring provides a solution that allows monitoring simulation externally.
web
Package web includes the static web pages for the monitoring tool.
Package web includes the static web pages for the monitoring tool.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL