home | OO Richards Bench

Psyco Python #99

Register values v1 v2 are held in Task classes, which implement scheduler function fn as a method.

Python language Psyco Python version 2.3.3

import psyco
psyco.full()
import sys, array
from time import clock
from array import array

# task id constants
IDLE = 0  
WORKER = 1  
HANDLERA = 2  
HANDLERB = 3  
DEVICEA = 4  
DEVICEB = 5    
    
layout = 50

def main(count=10000):
   startTicks = clock()
   s = Scheduler();
   s.addIdleTask(IDLE, 0, [], count)
     
   s.addWorkerTask(WORKER, 1000, [
      Packet(WORKER, Packet.WORK),
      Packet(WORKER, Packet.WORK)
      ])
    
   s.addHandlerTask(HANDLERA, 2000, [
      Packet(DEVICEA, Packet.DEVICE),
      Packet(DEVICEA, Packet.DEVICE),
      Packet(DEVICEA, Packet.DEVICE)
      ])   

   s.addHandlerTask(HANDLERB, 3000, [
      Packet(DEVICEB, Packet.DEVICE),
      Packet(DEVICEB, Packet.DEVICE),
      Packet(DEVICEB, Packet.DEVICE)
      ])  
   
   s.addDeviceTask(DEVICEA, 4000, []) 
   s.addDeviceTask(DEVICEB, 5000, [])     
      
   s.schedule()     
              
   stopTicks = clock()     
   frequency = 1000000
    
   f=open('testrun-times.xml', 'a')    
   f.write('<ExternalStat>');
   f.write('<size>')
   f.write(str(count));
   f.write('</size>')    
   f.write('<ticks>')
   f.write(str(int((stopTicks - startTicks)*frequency)));
   f.write('</ticks>')    
   f.write('<ticksPerSecond>')
   f.write(str(frequency));
   f.write('</ticksPerSecond>')    
   f.write('</ExternalStat>\n'); 
   f.close()       
    
   print 'QueueCount = %d\nHoldCount = %d' % (s.queueCount, s.holdCount)  
   

def trace(c):
   global layout   
   if layout <= 0:
      sys.stdout.write('\n')
      layout = 50
   layout -= 1
   sys.stdout.write(c) 
   

        
class Scheduler:
   def __init__(self):
      self.table = [None, None, None, None, None, None]
      self.list = None
      self.queueCount = 0
      self.holdCount = 0      

   def addDeviceTask(self, id, pri, wkq): 
      self.addTask(id, pri, wkq, DeviceTask(self))
      
   def addHandlerTask(self, id, pri, wkq): 
      self.addTask(id, pri, wkq, HandlerTask(self))      

   def addIdleTask(self, id, pri, wkq, count): 
      self.addRunningTask(id, pri, wkq, IdleTask(self, 1, count))

   def addWorkerTask(self, id, pri, wkq): 
      self.addTask(id, pri, wkq, WorkerTask(self, HANDLERA, 0))

   def addTask(self, id, pri, wkq, task):
      self.currentTcb = Tcb(self.list, id, pri, wkq, task)
      self.list = self.currentTcb
      self.table[id] = self.currentTcb
      
   def addRunningTask(self, id, pri, wkq, task):
      self.addTask(id, pri, wkq, task)
      self.currentTcb.setRunning()
      
   def schedule(self):         
      self.currentTcb = self.list
      while self.currentTcb is not None:
         if self.currentTcb.isHeldOrSuspended():
            self.currentTcb = self.currentTcb.getLink()
         else:
            self.currentId = self.currentTcb.getId()
            # if __debug__:
            #   trace(str(self.currentId + 1))      
            self.currentTcb = self.currentTcb.run()
      
   def queue(self, packet):
      tcb = self.table[packet.getId()]
      self.queueCount += 1
      packet.setId(self.currentId)
      return tcb.checkPriorityAdd(self.currentTcb,packet)
      
   def release(self,id):
      tcb = self.table[id]                                   
      tcb.notHeld()
      if tcb.getPriority() > self.currentTcb.getPriority():
         return tcb
      else:
         return self.currentTcb
         
   def holdCurrent(self):
      self.holdCount += 1
      self.currentTcb.held()
      return self.currentTcb.getLink()
      
   def suspendCurrent(self):
      self.currentTcb.suspended()
      return self.currentTcb                     



class DeviceTask:
   def __init__(self, scheduler):
      self.scheduler = scheduler
      self.v1 = None
      self.v2 = None 
        
   def run(self, packet):        
      if packet is None:
         if self.v1 is None:
            return self.scheduler.suspendCurrent()    
         else:
            pkt = self.v1
            self.v1 = None            
            return self.scheduler.queue(pkt)
      else:
         self.v1 = packet
         # if __debug__:
         #    trace(str(packet.a1))
         return self.scheduler.holdCurrent()
         
         
         
class HandlerTask:
   def __init__(self, scheduler):
      self.scheduler = scheduler
      self.v1 = []
      self.v2 = [] 
        
   def run(self, packet):     
      if packet is not None:
         if packet.kind == Packet.WORK:
            self.v1.append(packet)  
         else:
            self.v2.append(packet) 
             
      if self.v1: # not empty
         workPacket = self.v1[0]
         count = workPacket.getA1()
         if count > 3:
            del self.v1[0]
            return self.scheduler.queue(workPacket) 
         else:   
            if self.v2: # not empty
               devicePacket = self.v2.pop(0)
               devicePacket.setA1(workPacket.a2[count])
               workPacket.setA1(count + 1)
               return self.scheduler.queue(devicePacket) 
                                            
      return self.scheduler.suspendCurrent()
         
                  
                  
class IdleTask:
   def __init__(self, scheduler, v1, v2):
      self.scheduler = scheduler
      self.v1 = v1
      self.v2 = v2 
        
   def run(self, packet):     
      self.v2 -= 1
      if self.v2 == 0:
         return self.scheduler.holdCurrent()    
      else:
         if (self.v1 & 1) == 0:
            self.v1 = self.v1 >> 1
            return self.scheduler.release(DEVICEA)
         else:
            self.v1 = (self.v1 >> 1) ^ 0xD008
            return self.scheduler.release(DEVICEB)       
            
            
            
class WorkerTask:
   ALPHA = '0ABCDEFGHIJKLMNOPQRSTUVWXYZ'
   def __init__(self, scheduler, v1, v2):
      self.scheduler = scheduler
      self.v1 = v1
      self.v2 = v2 
        
   def run(self, packet):     
      if packet is None:
         return self.scheduler.suspendCurrent()    
      else:
         if self.v1 == HANDLERA:
            self.v1 = HANDLERB
         else:
            self.v1 = HANDLERA 
            
         packet.setId(self.v1)       
         packet.setA1(0)         
         for i in range(4):
            self.v2 += 1
            if self.v2 > 26:
               self.v2 = 1
            packet.getA2()[i] = WorkerTask.ALPHA[self.v2]
                      
         return self.scheduler.queue(packet)         
         
         
                                     
class Tcb:
   RUNNING = 0   
   RUNNABLE = 1 
   SUSPENDED = 2   
   HELD = 4   
   SUSPENDED_RUNNABLE = SUSPENDED | RUNNABLE
   NOT_HELD = ~HELD 
   
   def __init__(self, link, id, pri, wkq, task):
      self.link = link    
      self.id = id
      self.pri = pri
      self.wkq = wkq         
      self.task = task   
      if len(wkq) == 0:
         self.state = 2 # Tcb.SUSPENDED
      else:
         self.state = 3 # Tcb.SUSPENDED_RUNNABLE        

   def getLink(self):
      return self.link  
      
   def getId(self):
      return self.id  
      
   def getPriority(self):
      return self.pri 
                                       
   def checkPriorityAdd(self, task, packet):
      if self.wkq: # not empty
         self.wkq.append(packet)
      else:
         self.wkq.append(packet)  
         self.state |= 1 # Tcb.RUNNABLE
         if self.pri > task.getPriority():
            return self                
      return task           
                           
   def run(self):
      if self.state == 3: # Tcb.SUSPENDED_RUNNABLE
         packet = self.wkq.pop(0)
         if self.wkq: # not empty
            self.state = 1 # Tcb.RUNNABLE          
         else:
            self.state = 0 # Tcb.RUNNING      
      else:
         packet = None
      return self.task.run(packet)                               
         
   def setRunning(self):         
      self.state = 0 # Tcb.RUNNING           
      
   def suspended(self):         
      self.state |= 2 # Tcb.SUSPENDED               
         
   def held(self):         
      self.state |= 4 # Tcb.HELD  
      
   def notHeld(self):         
      self.state &= ~4 # Tcb.NOT_HELD  
      
   def isHeldOrSuspended(self):         
      # return (self.state & Tcb.HELD) != 0 
      #    or self.state == Tcb.SUSPENDED      
      return (self.state & 4) != 0 or self.state == 2    
      
      
                                                
class Packet:      
   DEVICE = 0
   WORK = 1
   def __init__(self, id, kind): 
      self.id = id
      self.kind = kind
      self.a1 = 0         
      self.a2 = array('c','0000')    
      
   def getId(self):
      return self.id
      
   def setId(self,id):
      self.id = id
      
   def getKind(self):
      return self.kind
      
   def getA1(self):
      return self.a1  
      
   def setA1(self,a1):
      self.a1 = a1   
      
   def getA2(self):
      return self.a2
            

if __name__ == '__main__':
   import getopt
   opts, args = getopt.getopt(sys.argv[1:],'')
   count = 10000
   if len(args) > 0: 
      count = int(args[0]) 
   main(count=count)

Valid XHTML 1.0!