#!/usr/bin/env python
### centralserver.py (was sip019 (from sms019)
from __future__ import generators
from SimPy.Simulation import *
from random import Random,random,expovariate,uniform
import unittest

"""
A time-shared computer consists of a single central processing unit
(CPU) and $n$ terminals. The operator of each terminal `thinks' for a
random time (exponential, mean $100.0$ sec) and then submits a taks to
the computer with a service time (exponential, mean $1.0$ sec). The
operator then remains idle until the taks completes service and returns
to him or her. The arriving tasks form a single FCFS queue in front of
the CPU.

Upon leaving the CPU a taks is either finished (probability $0.20$)
and returns to its operator to begin another `think' time, or
requires data from a disk drive (probability $0.8$). If a task
requires access to the disk, it joins a FCFS queue before service
(service time at the disk, exponential, mean $1.39$ sec). When
finished with the disk, a task returns to the CPU queue again for
another compute time (exp, mean $1.0$ sec).
"""

__version__ = '$Revision: 1.0 $ $Date: 2004-05-15 11:09:32+02 $'

cpu = Resource(name='cpu')
disk = Resource(name='disk')
pDisk = 0.8
MeanThinkTime=10.0
MeanCPUTime = 1.0
DiskProb = 0.8
MeanDiskTime= 1.39

g=Random(111113333)

class Task(Process):
    completed = 0
    DEBUG = 1
    def __init__(self, name="task", mx = 10):
        Process.__init__(self)
        self.name = name
        self.maxCompletions = mx
	
    def debug(self,message):
        if Task.DEBUG: print"%9.3f %s %s"%(now(),self.name,message)

    def execute(self):
        while Task.completed < self.maxCompletions:
            self.debug(" starts thinking")
            yield hold,self,g.expovariate(1.0/MeanThinkTime)
            self.debug(" request cpu")
            yield request,self,cpu
            self.debug(" got cpu")
            yield   hold,self,g.expovariate(1.0/MeanCPUTime)
            yield release,self,cpu
            self.debug(" finish cpu")
            while random() < pDisk:
                self.debug(" request disk")
                yield request,self,disk
                self.debug(" got disk")
                yield   hold,self,g.expovariate(1.0/MeanDiskTime)
                self.debug(" finish disk")
                yield release,self,disk
                self.debug(" request cpu")
                yield request,self,cpu
                self.debug(" got cpu")
                yield   hold,self,g.expovariate(1.0/MeanCPUTime)
                yield release,self,cpu
            Task.completed += 1
        self.debug(" completed %d tasks"%(Task.completed,))
 
            
    
def main():
     print "pyt019 time-shared computer. version " + __version__
     initialize()
     for i in range(3):
         t = Task(name="task"+`i`,mx = 10)
         activate(t,t.execute(),0.0)
     simulate(until = 200.0)
     print "Finished Test pyt019"

if __name__ == '__main__':
    main()
else:
    print "not main"

