Documentation ¶
Overview ¶
Package sim is a package that provides basic functionalities to build discrete event simulator.
Example (PingWithEvents) ¶
package main import ( "fmt" "reflect" "github.com/sarchlab/akita/v3/sim" ) type PingMsg struct { sim.MsgMeta SeqID int } func (p *PingMsg) Meta() *sim.MsgMeta { return &p.MsgMeta } type PingRsp struct { sim.MsgMeta SeqID int } func (p *PingRsp) Meta() *sim.MsgMeta { return &p.MsgMeta } type StartPingEvent struct { *sim.EventBase Dst sim.Port } type RspPingEvent struct { *sim.EventBase pingMsg *PingMsg } type PingAgent struct { *sim.ComponentBase Engine sim.Engine OutPort sim.Port startTime []sim.VTimeInSec nextSeqID int } func NewPingAgent(name string, engine sim.Engine) *PingAgent { agent := &PingAgent{Engine: engine} agent.ComponentBase = sim.NewComponentBase(name) agent.OutPort = sim.NewLimitNumMsgPort(agent, 4, name+".OutPort") return agent } func (p *PingAgent) Handle(e sim.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 sim.VTimeInSec, port sim.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 sim.VTimeInSec, msg *PingMsg) { rspEvent := RspPingEvent{ EventBase: sim.NewEventBase(now+2, p), pingMsg: msg, } p.Engine.Schedule(rspEvent) } func (p *PingAgent) processPingRsp(now sim.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(_ sim.VTimeInSec, _ sim.Port) { // Do nothing } func main() { engine := sim.NewSerialEngine() agentA := NewPingAgent("AgentA", engine) agentB := NewPingAgent("AgentB", engine) conn := sim.NewDirectConnection("Conn", engine, 1*sim.GHz) conn.PlugIn(agentA.OutPort, 1) conn.PlugIn(agentB.OutPort, 1) e1 := StartPingEvent{ EventBase: sim.NewEventBase(1, agentA), Dst: agentB.OutPort, } e2 := StartPingEvent{ EventBase: sim.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" "github.com/sarchlab/akita/v3/sim" ) type pingTransaction struct { req *PingMsg cycleLeft int } type TickingPingAgent struct { *sim.TickingComponent OutPort sim.Port currentTransactions []*pingTransaction startTime []sim.VTimeInSec numPingNeedToSend int nextSeqID int pingDst sim.Port } func NewTickingPingAgent( name string, engine sim.Engine, freq sim.Freq, ) *TickingPingAgent { a := &TickingPingAgent{} a.TickingComponent = sim.NewTickingComponent(name, engine, freq, a) a.OutPort = sim.NewLimitNumMsgPort(a, 4, a.Name()+".OutPort") return a } func (a *TickingPingAgent) Tick(now sim.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 sim.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 sim.VTimeInSec, ping *PingMsg, ) { trans := &pingTransaction{ req: ping, cycleLeft: 2, } a.currentTransactions = append(a.currentTransactions, trans) a.OutPort.Retrieve(now) } func (a *TickingPingAgent) processingPingRsp( now sim.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 sim.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 sim.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 := sim.NewSerialEngine() agentA := NewTickingPingAgent("AgentA", engine, 1*sim.Hz) agentB := NewTickingPingAgent("AgentB", engine, 1*sim.Hz) conn := sim.NewDirectConnection("Conn", engine, 1*sim.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 ¶
- Variables
- func BuildName(parentName, elementName string) string
- func BuildNameWithIndex(parentName, elementName string, index int) string
- func BuildNameWithMultiDimensionalIndex(parentName, elementName string, index []int) string
- func NameMustBeValid(name string)
- func UseParallelIDGenerator()
- func UseSequentialIDGenerator()
- type Buffer
- type BufferedSender
- type Component
- type ComponentBase
- type Connection
- type ControlMsg
- type ControlMsgBuilder
- func (c ControlMsgBuilder) Build() *ControlMsg
- func (c ControlMsgBuilder) WithClearPorts() ControlMsgBuilder
- func (c ControlMsgBuilder) WithDisable() ControlMsgBuilder
- func (c ControlMsgBuilder) WithDst(dst Port) ControlMsgBuilder
- func (c ControlMsgBuilder) WithEnable() ControlMsgBuilder
- func (c ControlMsgBuilder) WithReset() ControlMsgBuilder
- func (c ControlMsgBuilder) WithSendTime(sendTime VTimeInSec) ControlMsgBuilder
- func (c ControlMsgBuilder) WithSrc(src Port) ControlMsgBuilder
- func (c ControlMsgBuilder) WithTrafficBytes(trafficBytes int) ControlMsgBuilder
- func (c ControlMsgBuilder) WithTrafficClass(trafficClass int) ControlMsgBuilder
- type DirectConnection
- func (c *DirectConnection) CanSend(src Port) bool
- func (c *DirectConnection) NotifyAvailable(now VTimeInSec, _ Port)
- func (c *DirectConnection) PlugIn(port Port, sourceSideBufSize int)
- func (c *DirectConnection) Send(msg Msg) *SendError
- func (c *DirectConnection) Tick(now VTimeInSec) bool
- func (c *DirectConnection) Unplug(_ Port)
- type Domain
- type Engine
- type Event
- type EventBase
- type EventLogger
- type EventQueue
- type EventQueueImpl
- type EventScheduler
- type Freq
- func (f Freq) Cycle(time VTimeInSec) uint64
- func (f Freq) HalfTick(t VTimeInSec) VTimeInSec
- func (f Freq) NCyclesLater(n int, now VTimeInSec) VTimeInSec
- func (f Freq) NextTick(now VTimeInSec) VTimeInSec
- func (f Freq) NoEarlierThan(t VTimeInSec) VTimeInSec
- func (f Freq) Period() VTimeInSec
- func (f Freq) ThisTick(now VTimeInSec) VTimeInSec
- type GeneralRsp
- type GeneralRspBuilder
- func (c GeneralRspBuilder) Build() *GeneralRsp
- func (c GeneralRspBuilder) WithDst(dst Port) GeneralRspBuilder
- func (c GeneralRspBuilder) WithOriginalReq(originalReq Msg) GeneralRspBuilder
- func (c GeneralRspBuilder) WithSendTime(sendTime VTimeInSec) GeneralRspBuilder
- func (c GeneralRspBuilder) WithSrc(src Port) GeneralRspBuilder
- func (c GeneralRspBuilder) WithTrafficBytes(trafficBytes int) GeneralRspBuilder
- func (c GeneralRspBuilder) WithTrafficClass(trafficClass int) GeneralRspBuilder
- type Handler
- type Hook
- type HookCtx
- type HookPos
- type Hookable
- type HookableBase
- type IDGenerator
- type InsertionQueue
- type LimitNumMsgPort
- func (p *LimitNumMsgPort) CanSend() bool
- func (p *LimitNumMsgPort) Component() Component
- func (p *LimitNumMsgPort) Name() string
- func (p *LimitNumMsgPort) NotifyAvailable(now VTimeInSec)
- func (p *LimitNumMsgPort) Peek() Msg
- func (p *LimitNumMsgPort) Recv(msg Msg) *SendError
- func (p *LimitNumMsgPort) Retrieve(now VTimeInSec) Msg
- func (p *LimitNumMsgPort) Send(msg Msg) *SendError
- func (p *LimitNumMsgPort) SetConnection(conn Connection)
- type LogHook
- type LogHookBase
- type Msg
- type MsgMeta
- type Name
- type NameToken
- type Named
- type ParallelEngine
- func (e *ParallelEngine) Continue()
- func (e *ParallelEngine) CurrentTime() VTimeInSec
- func (e *ParallelEngine) Finished()
- func (e *ParallelEngine) Pause()
- func (e *ParallelEngine) RegisterSimulationEndHandler(handler SimulationEndHandler)
- func (e *ParallelEngine) Run() error
- func (e *ParallelEngine) Schedule(evt Event)
- type Port
- type PortMsgLogger
- type PortOwner
- type PortOwnerBase
- type Rsp
- type SendError
- type SerialEngine
- func (e *SerialEngine) Continue()
- func (e *SerialEngine) CurrentTime() VTimeInSec
- func (e *SerialEngine) Finished()
- func (e *SerialEngine) Pause()
- func (e *SerialEngine) RegisterSimulationEndHandler(handler SimulationEndHandler)
- func (e *SerialEngine) Run() error
- func (e *SerialEngine) Schedule(evt Event)
- type SimulationEndHandler
- type TickEvent
- type TickScheduler
- type Ticker
- type TickingComponent
- type TimeTeller
- type VTimeInSec
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var HookPosAfterEvent = &HookPos{Name: "AfterEvent"}
HookPosAfterEvent is a hook position that triggers after handling an event.
var HookPosBeforeEvent = &HookPos{Name: "BeforeEvent"}
HookPosBeforeEvent is a hook position that triggers before handling an event.
var HookPosBufPop = &HookPos{Name: "Buf Pop"}
HookPosBufPop marks when an element is popped from the buffer.
var HookPosBufPush = &HookPos{Name: "Buffer Push"}
HookPosBufPush marks when an element is pushed into the buffer.
var HookPosConnDeliver = &HookPos{Name: "Conn Deliver"}
HookPosConnDeliver marks a connection delivered a message.
var HookPosConnDoneTrans = &HookPos{Name: "Conn Done Trans"}
HookPosConnDoneTrans marks a connection complete transmitting a message.
var HookPosConnStartSend = &HookPos{Name: "Conn Start Send"}
HookPosConnStartSend marks a connection accept to send a message.
var HookPosConnStartTrans = &HookPos{Name: "Conn Start Trans"}
HookPosConnStartTrans marks a connection start to transmit a message.
var HookPosPortMsgRecvd = &HookPos{Name: "Port Msg Recv"}
HookPosPortMsgRecvd marks when an inbound message arrives at a the given port
var HookPosPortMsgRetrieve = &HookPos{Name: "Port Msg Retrieve"}
HookPosPortMsgRetrieve marks when an outbound message is sent over a connection
var HookPosPortMsgSend = &HookPos{Name: "Port Msg Send"}
HookPosPortMsgSend marks when a message is sent out from the port.
Functions ¶
func BuildNameWithIndex ¶
BuildNameWithIndex builds a name from a parent name, an element name and an index.
func BuildNameWithMultiDimensionalIndex ¶
BuildNameWithMultiDimensionalIndex builds a name from a parent name, an element name and a multi-dimensional index.
func NameMustBeValid ¶
func NameMustBeValid(name string)
NameMustBeValid panics if the name does not follow the naming convention. There are several rules that a name must follow.
- It must be organized in a hierarchical structure. For example, a name "A.B.C" is valid, but "A.B.C." is not.
- Individual names must not be empty. For example, "A..B" is not valid.
- Individual names must be named as capitalized CamelCase style. For example, "A.b" is not valid.
- Elements in a series must be named using square-bracket notation.
func UseParallelIDGenerator ¶
func UseParallelIDGenerator()
UseParallelIDGenerator configurs the ID generator to generate ID in parallel. The IDs generated will not be deterministic anymore.
func UseSequentialIDGenerator ¶
func UseSequentialIDGenerator()
UseSequentialIDGenerator configures the ID generator to generate IDs in sequential.
Types ¶
type Buffer ¶
type Buffer interface { Named Hookable CanPush() bool Push(e interface{}) Pop() interface{} Peek() interface{} Capacity() int Size() int // Remove all elements in the buffer Clear() }
A Buffer is a fifo queue for anything
type BufferedSender ¶
type BufferedSender interface { // CanSend checks if the buffer has enough space to hold "count" messages. CanSend(count int) bool // Send enqueues a message into the buffer and the message will be sent out // later with the Tick function. Send(msg Msg) // Clear removes all the messages to send Clear() // Tick tries to send one message out. If successful, Tick returns true. Tick(now VTimeInSec) bool }
BufferedSender can delegate the sending process.
The most common usage of BufferedSender is to be used as the send stage of an Akita Component. It is common that multiple sub-component in a component need to send messages out from a port. Another common pattern is that a large number of messages are generated in one cycle and the messages are sent out one per cycle. In both cases, the message generate can push the packet into a BufferedSender and the call the BufferedSender's Tick function to actually send the messages out.
func NewBufferedSender ¶
func NewBufferedSender(port Port, buffer Buffer) BufferedSender
NewBufferedSender creates a new BufferedSender with certain buffer capacity and send to a certain port.
type Component ¶
type Component interface { Named Handler Hookable PortOwner 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 { sync.Mutex HookableBase *PortOwnerBase // 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 CanSend(src Port) bool 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 ControlMsg ¶
ControlMsg is a special message that is used to manipulate the states of some components.
func (*ControlMsg) Meta ¶
func (c *ControlMsg) Meta() *MsgMeta
Meta returns the meta data of the control message.
type ControlMsgBuilder ¶
type ControlMsgBuilder struct {
Src, Dst Port
SendTime VTimeInSec
TrafficClass int
TrafficBytes int
Reset, Disable, Enable, ClearPorts bool
}
ControlMsgBuilder can build control messages.
func (ControlMsgBuilder) Build ¶
func (c ControlMsgBuilder) Build() *ControlMsg
Build creates a new control message.
func (ControlMsgBuilder) WithClearPorts ¶
func (c ControlMsgBuilder) WithClearPorts() ControlMsgBuilder
WithClearPorts sets the clear ports flag of the control message.
func (ControlMsgBuilder) WithDisable ¶
func (c ControlMsgBuilder) WithDisable() ControlMsgBuilder
WithDisable sets the disable flag of the control message.
func (ControlMsgBuilder) WithDst ¶
func (c ControlMsgBuilder) WithDst(dst Port) ControlMsgBuilder
WithDst sets the destination of the control message.
func (ControlMsgBuilder) WithEnable ¶
func (c ControlMsgBuilder) WithEnable() ControlMsgBuilder
WithEnable sets the enable flag of the control message.
func (ControlMsgBuilder) WithReset ¶
func (c ControlMsgBuilder) WithReset() ControlMsgBuilder
WithReset sets the reset flag of the control message.
func (ControlMsgBuilder) WithSendTime ¶
func (c ControlMsgBuilder) WithSendTime(sendTime VTimeInSec) ControlMsgBuilder
WithSendTime sets the send time of the control message.
func (ControlMsgBuilder) WithSrc ¶
func (c ControlMsgBuilder) WithSrc(src Port) ControlMsgBuilder
WithSrc sets the source of the control message.
func (ControlMsgBuilder) WithTrafficBytes ¶
func (c ControlMsgBuilder) WithTrafficBytes(trafficBytes int) ControlMsgBuilder
WithTrafficBytes sets the traffic bytes of the control message.
func (ControlMsgBuilder) WithTrafficClass ¶
func (c ControlMsgBuilder) WithTrafficClass(trafficClass int) ControlMsgBuilder
WithTrafficClass sets the traffic class of the control message.
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) CanSend ¶
func (c *DirectConnection) CanSend(src Port) bool
CanSend checks if the direct message can send a message from the port.
func (*DirectConnection) NotifyAvailable ¶
func (c *DirectConnection) NotifyAvailable(now VTimeInSec, _ 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 ¶
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)
Unplug marks the port no longer connects to this DirectConnection.
type Domain ¶
type Domain struct { *PortOwnerBase // contains filtered or unexported fields }
Domain is a group of components that are closely connected.
type Engine ¶
type Engine interface { Hookable TimeTeller EventScheduler // 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() // 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" "github.com/sarchlab/akita/v3/sim" ) type SplitEvent struct { time sim.VTimeInSec handler sim.Handler } func (e SplitEvent) Time() sim.VTimeInSec { return e.time } func (e SplitEvent) Handler() sim.Handler { return e.handler } func (e SplitEvent) IsSecondary() bool { return false } type SplitHandler struct { total int engine sim.Engine } func (h *SplitHandler) Handle(evt sim.Event) error { h.total++ now := evt.Time() nextTime := now + sim.VTimeInSec(rand.Float64()*2+0.5) if nextTime < 10.0 { nextEvt := SplitEvent{ time: nextTime, handler: h, } h.engine.Schedule(nextEvt) } nextTime = now + sim.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 := sim.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) IsSecondary ¶
IsSecondary returns true if the event is a secondary event.
func (EventBase) SetHandler ¶
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 ¶
EventQueue are a queue of event ordered by the time of events
type EventQueueImpl ¶
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 EventScheduler ¶
type EventScheduler interface {
Schedule(e Event)
}
EventScheduler can be used to schedule future events.
type Freq ¶
type Freq float64
Freq defines the type 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 GeneralRsp ¶
GeneralRsp is a general response message that is used to indicate the completion of a request.
func (*GeneralRsp) GetRspTo ¶
func (r *GeneralRsp) GetRspTo() string
GetRspTo returns the ID of the original request.
func (*GeneralRsp) Meta ¶
func (r *GeneralRsp) Meta() *MsgMeta
Meta returns the meta data of the message.
type GeneralRspBuilder ¶
type GeneralRspBuilder struct {
Src, Dst Port
SendTime VTimeInSec
TrafficClass int
TrafficBytes int
OriginalReq Msg
}
GeneralRspBuilder can build general response messages.
func (GeneralRspBuilder) Build ¶
func (c GeneralRspBuilder) Build() *GeneralRsp
Build creates a new general response message.
func (GeneralRspBuilder) WithDst ¶
func (c GeneralRspBuilder) WithDst(dst Port) GeneralRspBuilder
WithDst sets the destination of the general response message.
func (GeneralRspBuilder) WithOriginalReq ¶
func (c GeneralRspBuilder) WithOriginalReq(originalReq Msg) GeneralRspBuilder
WithOriginalReq sets the original request of the general response message.
func (GeneralRspBuilder) WithSendTime ¶
func (c GeneralRspBuilder) WithSendTime(sendTime VTimeInSec) GeneralRspBuilder
WithSendTime sets the send time of the general response message.
func (GeneralRspBuilder) WithSrc ¶
func (c GeneralRspBuilder) WithSrc(src Port) GeneralRspBuilder
WithSrc sets the source of the general response message.
func (GeneralRspBuilder) WithTrafficBytes ¶
func (c GeneralRspBuilder) WithTrafficBytes(trafficBytes int) GeneralRspBuilder
WithTrafficBytes sets the traffic bytes of the general response message.
func (GeneralRspBuilder) WithTrafficClass ¶
func (c GeneralRspBuilder) WithTrafficClass(trafficClass int) GeneralRspBuilder
WithTrafficClass sets the traffic class of the general response message.
type Handler ¶
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 ¶
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) // NumHooks returns the number of hooks registered. NumHooks() int // Hooks returns all the hooks registered. Hooks() []Hook }
Hookable defines an object that accept Hooks.
type HookableBase ¶
type HookableBase struct {
// contains filtered or unexported fields
}
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) Hooks ¶
func (h *HookableBase) Hooks() []Hook
Hooks returns all the hooks registered.
func (*HookableBase) InvokeHook ¶
func (h *HookableBase) InvokeHook(ctx HookCtx)
InvokeHook triggers the register Hooks.
func (*HookableBase) NumHooks ¶
func (h *HookableBase) NumHooks() int
NumHooks returns the number of hooks registered.
type IDGenerator ¶
type IDGenerator interface { // Generate an ID Generate() string }
IDGenerator can generate IDs
func GetIDGenerator ¶
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 ¶
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 ¶
func NewLimitNumMsgPort( comp Component, capacity int, name string, ) *LimitNumMsgPort
NewLimitNumMsgPort creates a new port that works for the provided component
func NewLimitNumMsgPortWithExternalBuffer ¶
func NewLimitNumMsgPortWithExternalBuffer( comp Component, buf Buffer, name string, ) *LimitNumMsgPort
NewLimitNumMsgPortWithExternalBuffer creates a new port that works for the provided component and uses the provided buffer.
func (*LimitNumMsgPort) CanSend ¶
func (p *LimitNumMsgPort) CanSend() bool
CanSend checks if the port can send a message without error.
func (*LimitNumMsgPort) Component ¶
func (p *LimitNumMsgPort) Component() Component
Component returns the owner component of the port.
func (*LimitNumMsgPort) Name ¶
func (p *LimitNumMsgPort) Name() string
Name returns the name of the port.
func (*LimitNumMsgPort) NotifyAvailable ¶
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 ¶
func (p *LimitNumMsgPort) Peek() Msg
Peek returns the first message in the port without removing it.
func (*LimitNumMsgPort) Recv ¶
func (p *LimitNumMsgPort) Recv(msg Msg) *SendError
Recv is used to deliver a message to a component
func (*LimitNumMsgPort) Retrieve ¶
func (p *LimitNumMsgPort) Retrieve(now VTimeInSec) Msg
Retrieve is used by the component to take a message from the incoming buffer
func (*LimitNumMsgPort) Send ¶
func (p *LimitNumMsgPort) Send(msg Msg) *SendError
Send is used to send a message out from a component
func (*LimitNumMsgPort) SetConnection ¶
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 ¶
LogHookBase proovides the common logic for all LogHooks
type Msg ¶
type Msg interface {
Meta() *MsgMeta
}
A Msg is a piece of information that is transferred between components.
type MsgMeta ¶
type MsgMeta struct { ID string Src, Dst Port SendTime, RecvTime VTimeInSec TrafficClass int TrafficBytes int }
MsgMeta contains the meta data that is attached to every message.
type Name ¶
type Name struct {
Tokens []NameToken
}
A Name is a hierarchical name that includes a series of tokens separated by dots.
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 ¶
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 ¶
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 CanSend() bool Send(msg Msg) *SendError Retrieve(now VTimeInSec) Msg Peek() Msg }
A Port is owned by a component and is used to plugin connections
type PortMsgLogger ¶
type PortMsgLogger struct { LogHookBase TimeTeller }
PortMsgLogger is a hook for logging messages as they go across a Port
func NewPortMsgLogger ¶
func NewPortMsgLogger( logger *log.Logger, timeTeller TimeTeller, ) *PortMsgLogger
NewPortMsgLogger returns a new PortMsgLogger which will write into the logger
func (*PortMsgLogger) Func ¶
func (h *PortMsgLogger) Func(ctx HookCtx)
Func writes the message information into the logger
type PortOwner ¶
type PortOwner interface { AddPort(name string, port Port) GetPortByName(name string) Port Ports() []Port }
A PortOwner is an element that can communicate with others through ports.
type PortOwnerBase ¶
type PortOwnerBase struct {
// contains filtered or unexported fields
}
PortOwnerBase provides an implementation of the PortOwner interface.
func NewPortOwnerBase ¶
func NewPortOwnerBase() *PortOwnerBase
NewPortOwnerBase creates a new PortOwnerBase
func (*PortOwnerBase) AddPort ¶
func (po *PortOwnerBase) AddPort(name string, port Port)
AddPort adds a new port with a given name.
func (PortOwnerBase) GetPortByName ¶
func (po PortOwnerBase) GetPortByName(name string) Port
GetPortByName returns the port according to the name of the port. This function panics when the given name is not found.
func (PortOwnerBase) Ports ¶
func (po PortOwnerBase) Ports() []Port
Ports returns a slices of all the ports owned by the PortOwner.
type SerialEngine ¶
type SerialEngine struct { HookableBase // contains filtered or unexported fields }
A SerialEngine is an Engine that always run events one after another.
func (*SerialEngine) Continue ¶
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 ¶
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 ¶
func MakeTickEvent(t VTimeInSec, handler Handler) TickEvent
MakeTickEvent creates a new TickEvent
type TickScheduler ¶
TickScheduler can help schedule tick events.
func NewSecondaryTickScheduler ¶
func NewSecondaryTickScheduler( handler Handler, engine Engine, freq Freq, ) *TickScheduler
NewSecondaryTickScheduler creates a scheduler that always schedule secondary tick events.
func NewTickScheduler ¶
func NewTickScheduler( handler Handler, engine Engine, freq Freq, ) *TickScheduler
NewTickScheduler creates a scheduler for tick events.
func (*TickScheduler) TickLater ¶
func (t *TickScheduler) TickLater(now VTimeInSec)
TickLater will schedule a tick event at the cycle after the now time.
func (*TickScheduler) TickNow ¶
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 ¶
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 ¶
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, )
NotifyPortFree triggers the TickingComponent to start ticking again.
func (*TickingComponent) NotifyRecv ¶
func (c *TickingComponent) NotifyRecv( now VTimeInSec, _ Port, )
NotifyRecv triggers the TickingComponent to start ticking again.
type TimeTeller ¶
type TimeTeller interface {
CurrentTime() VTimeInSec
}
TimeTeller can be used to get the current time.
type VTimeInSec ¶
type VTimeInSec float64
VTimeInSec defines the time in the simulated space in the unit of second