📄 doc
字号:
Here are some notes on the simulator.The simulator code is in simulator.c and the header file is simulator.h.The simulator uses three process: main: controls the simulation (this is the user process that calls start_simulator() function). M0: machine 0 (simulates one end: sender for protocols 2 and 3) M1: machine 1 (simulates the other end: receiver for protocols 2 and 3)The function start_simulator() starts the simulation. It first initializesall the simulation parameters, and then creates six pipes so the threeprocesses can communicate pairwise. The file descriptors created are named asfollows. M0 - M1 communication: w1, r1: M0 to M1 for frames w2, r2: M1 to M0 for frames Main - M0 communication: w3, r3: main to M0 for go-ahead w4, r4: M0 to main to signal readiness Main - M1 communication: w5, r5: main to M1 for go-ahead w6, r6: M1 to main to signal readinessAfter the pipes have been created, the main process forks off two children,M0 and M1. Each of these then calls the appropriate protocol as a subroutine.The name of this subroutine is passed as a parameter in start_simulator()function invocation.Each protocol runs and does its own initialization. Eventually it callswait_for_event() to get work. A brief description of this routine and allthe others that a protocol designer may use are given in protocol.h.Wait_for_event() sets some counters, the reads any pending frames from theother worker, M0 or M1. This is done to get them out of the pipe, to preventsthe pipes from clogging. The frames read are stored in the array queue[],and removed from there as needed. The pointers inp and outp point to thefirst empty slot in queue[] and the next frame to remove, respectively.Nframes keeps track of the number of queued frames.Once the input pipe is sucked dry, wait_for_event() sends a 4-bytemessage to main to tell main that it is prepared to process an event.At that point it waits for main to give it the go-ahead.Main picks a worker to run and sends it the current time on file descriptorsw3 or w5. This is the go-ahead signal. The worker sets its own time to thevalue read from the pipe, so the two workers remain synchronized in time.Then it calls pick_event() to determine which event to return. The list ofpotential events differs for each protocol simulated.Once the event has been returned, wait_for_event returns to the caller, oneof the protocol routines, which then executes. These routines can call thelibrary routines that are defined in the file protocol.h. They manage timers,write frames to the pipe, etc. The code is straightforward and full ofcomments.The rest of start_simulation function is simple. It picks a process andgives it the go-ahead by writing the time to its communication pipe as a4-byte integer. That process then checks to see if it is able to run. Ifit is, it returns the code OK. If it cannot run now and no timers are pending,it returns the code NOTHING. If both processes return NOTHING for DEADLOCKticks in a row, a deadlock is declared. DEADLOCK is set to 3 times thetimeout interval, which is probably overly conservative, but probablyeliminates false deadlock announcements.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -