func applyBloodBankDiscipline(sys *BloodBankSystem, queue *qsim.Queue, trashProcessor, transfusionProcessor *qsim.Processor) { // Assigns the youngest unit to the processor assigner := func(cbProc *qsim.Processor, cbJob *qsim.Job) { var i, iYoungest int var j *qsim.Job if queue.Length() == 0 { qsim.D("Aborted after Job", cbJob) if sys.statsStarted { sys.NumAborted++ } // Give the processor a dummy job until the next transfusion j = qsim.NewJob(-1) cbProc.Start(j) return } for i, j = range queue.Jobs { if j.ArrTime > queue.Jobs[iYoungest].ArrTime { iYoungest = i } } j = queue.Jobs[iYoungest] queue.Remove(j) cbProc.Start(j) qsim.D("Started Job", j) } transfusionProcessor.AfterFinish(assigner) }
// Arrive simulates the process of drawing new blood for the bank. // // We draw enough blood to fill the bank to its MaxOccupancy, unless we've already // drawn as much as we can safely draw for the day. func (arrProc *BloodBankArrProc) Arrive(clock int) (jobs []*qsim.Job, interval int) { arrProc.beforeArrive() sys := arrProc.Sys if clock-arrProc.lastDraw >= 1440 { var numToAppend int numToAppend = sys.MaxOccupancy - sys.queue.Length() if numToAppend > sys.MaxDrawRate*((clock-sys.lastDraw)/1440) { numToAppend = sys.MaxDrawRate * ((clock - sys.lastDraw) / 1440) } for i := 0; i < numToAppend; i++ { jobs = append(jobs, qsim.NewJob(clock)) } sys.lastDraw = clock } arrProc.afterArrive(jobs, 1440) return jobs, 1440 }
// BeforeRun runs right before the clock starts. func (sys *BloodBankSystem) BeforeFirstTick() { sys.transfusionProcessor.Start(qsim.NewJob(0)) }