Beispiel #1
0
    def __init__(self, coreno):
        threading.Thread.__init__(self)

        self.terminated = False

        self.metalock = threading.RLock()

        self.messages = {}  # UUID => (TID waiting for reply, callback)
        self.uuids_by_tid = defaultdict(
            lambda: [])  # TID waiting for reply => UUIDs waited for
        self.rev_uuids_by_tid = defaultdict(
            lambda: [])  # TIDs that are supposed to reply => UUIDs waited for
        self.pending_terminations = queue.Queue()  # queue of tcbs

        self.uuidgen = NewIDIssuer()
        self.uuidgen.adjustID(coreno << 32)
Beispiel #2
0
    def __init__(self, coreno):
        threading.Thread.__init__(self)

        self.terminated = False

        self.metalock = threading.RLock()

        self.events = []  # a heap queue of (run_at, Handler)

        self.pending_terminations = queue.Queue()  # queue of tcbs

        self.teidgen = NewIDIssuer()  # timer event ID, unique per TEP
Beispiel #3
0
 def __init__(self, coreno):
     threading.Thread.__init__(self)
     
     self.terminated = False
     
     self.metalock = threading.RLock()
     
     self.messages = {}      # UUID => (TID waiting for reply, callback)
     self.uuids_by_tid = defaultdict(lambda: [])  # TID waiting for reply => UUIDs waited for
     self.rev_uuids_by_tid = defaultdict(lambda: [])  # TIDs that are supposed to reply => UUIDs waited for
     self.pending_terminations = queue.Queue() # queue of tcbs
     
     self.uuidgen = NewIDIssuer()
     self.uuidgen.adjustID(coreno << 32)
Beispiel #4
0
class SMP(threading.Thread, Processor):
    def __init__(self, coreno):
        threading.Thread.__init__(self)

        self.terminated = False

        self.metalock = threading.RLock()

        self.messages = {}  # UUID => (TID waiting for reply, callback)
        self.uuids_by_tid = defaultdict(
            lambda: [])  # TID waiting for reply => UUIDs waited for
        self.rev_uuids_by_tid = defaultdict(
            lambda: [])  # TIDs that are supposed to reply => UUIDs waited for
        self.pending_terminations = queue.Queue()  # queue of tcbs

        self.uuidgen = NewIDIssuer()
        self.uuidgen.adjustID(coreno << 32)

    def terminate(self):
        self.terminated = True

    def onTaskletTerminated(self, tcb: TaskletControlBlock):
        self.pending_terminations.put(tcb)

    def deliver_reply_to(self, remote_tid: int, target_tid: int, obj: object,
                         msg: SynchronousMessage):
        with self.metalock:
            try:
                tid_waiting_for_reply, callback = self.messages[msg.uuid]
                if tid_waiting_for_reply != target_tid: raise KeyError
            except KeyError:
                return  # invalid!

            with S.syslock:
                try:
                    tcb = S.tcbs[target_tid]
                except KeyError:
                    return

            del self.messages[msg.uuid]
            self.uuids_by_tid[target_tid].remove(msg.uuid)
            if len(self.uuids_by_tid[target_tid]) == 0:
                del self.uuids_by_tid[target_tid]
            self.rev_uuids_by_tid[remote_tid].remove(msg.uuid)
            if len(self.rev_uuids_by_tid[remote_tid]) == 0:
                del self.rev_uuids_by_tid[remote_tid]

            tcb.handlers -= 1

            S.schedule(tcb, callback, obj)

    def send_sync_to(self, from_tcb: TaskletControlBlock, target_tid: int,
                     obj: object, handler: callable):
        """
        Called from tasklet. Send a sync message from local tasklet to target tasklet
        """
        if not S.isLocal(target_tid):
            raise NotImplementedError("No IPC for now, sorry!")

        smsg = SynchronousMessage(obj, from_tcb.tid, target_tid,
                                  self.uuidgen.next())

        with S.syslock:
            if target_tid not in S.tcbs:
                S.schedule(from_tcb, handler, Tasklet.DoesNotExist)
            else:
                S.schedule(S.tcbs[target_tid],
                           S.tcb_inst[target_tid].on_message, from_tcb.tid,
                           smsg)

        with self.metalock:
            self.messages[smsg.uuid] = (from_tcb.tid, handler)
            self.rev_uuids_by_tid[target_tid].append(smsg.uuid)
            self.uuids_by_tid[from_tcb.tid].append(smsg.uuid)

        from_tcb.handlers += 1

    def run(self):
        while not self.terminated:
            try:
                tcb_to_terminate = self.pending_terminations.get(True, 5)
            except queue.Empty:
                continue

            with self.metalock:
                a = self.rev_uuids_by_tid.pop(tcb_to_terminate.tid, ())
                b = self.uuids_by_tid.pop(tcb_to_terminate.tid, ())
                for uuid in itertools.chain(a, b):
                    del self.messages[uuid]
Beispiel #5
0
class SMP(threading.Thread, Processor):
    def __init__(self, coreno):
        threading.Thread.__init__(self)
        
        self.terminated = False
        
        self.metalock = threading.RLock()
        
        self.messages = {}      # UUID => (TID waiting for reply, callback)
        self.uuids_by_tid = defaultdict(lambda: [])  # TID waiting for reply => UUIDs waited for
        self.rev_uuids_by_tid = defaultdict(lambda: [])  # TIDs that are supposed to reply => UUIDs waited for
        self.pending_terminations = queue.Queue() # queue of tcbs
        
        self.uuidgen = NewIDIssuer()
        self.uuidgen.adjustID(coreno << 32)
        
    def terminate(self):
        self.terminated = True

    def onTaskletTerminated(self, tcb: TaskletControlBlock):
        self.pending_terminations.put(tcb)
    
    def deliver_reply_to(self, remote_tid: int, target_tid: int, obj: object, msg: SynchronousMessage):
        with self.metalock:
            try:
                tid_waiting_for_reply, callback = self.messages[msg.uuid]
                if tid_waiting_for_reply != target_tid: raise KeyError
            except KeyError:
                return      # invalid!
            
            with S.syslock:
                try:
                    tcb = S.tcbs[target_tid]
                except KeyError:
                    return
            
            del self.messages[msg.uuid]
            self.uuids_by_tid[target_tid].remove(msg.uuid)
            if len(self.uuids_by_tid[target_tid]) == 0:
                del self.uuids_by_tid[target_tid]
            self.rev_uuids_by_tid[remote_tid].remove(msg.uuid)
            if len(self.rev_uuids_by_tid[remote_tid]) == 0:
                del self.rev_uuids_by_tid[remote_tid]
                
            tcb.handlers -= 1
            
            S.schedule(tcb, callback, obj)            
    
    def send_sync_to(self, from_tcb: TaskletControlBlock, target_tid: int, obj: object, handler: callable):
        """
        Called from tasklet. Send a sync message from local tasklet to target tasklet
        """
        if not S.isLocal(target_tid):
            raise NotImplementedError("No IPC for now, sorry!")

        smsg = SynchronousMessage(obj, from_tcb.tid, target_tid, self.uuidgen.next())
        
        with S.syslock:
            if target_tid not in S.tcbs:
                S.schedule(from_tcb, handler, Tasklet.DoesNotExist)
            else:
                S.schedule(S.tcbs[target_tid], S.tcb_inst[target_tid].on_message, from_tcb.tid, smsg)
        
        with self.metalock:
            self.messages[smsg.uuid] = (from_tcb.tid, handler)
            self.rev_uuids_by_tid[target_tid].append(smsg.uuid)
            self.uuids_by_tid[from_tcb.tid].append(smsg.uuid)
            
        from_tcb.handlers += 1
    
    def run(self):
        while not self.terminated:
            try:
                tcb_to_terminate = self.pending_terminations.get(True, 5)
            except queue.Empty:
                continue
            
            with self.metalock:
                a = self.rev_uuids_by_tid.pop(tcb_to_terminate.tid, ())
                b = self.uuids_by_tid.pop(tcb_to_terminate.tid, ())            
                for uuid in itertools.chain(a, b):
                    del self.messages[uuid]
Beispiel #6
0
class S(object):
    """
    The grand central dispatch
    """
    
    frameNo = 0
    pageNo = 0
    
    syslock = Lock()
    
    tcbs = {}   # tid: int -> TaskletControlBlock
    tcb_inst = {}    # tid: int -> TaskletInstance
    
    terminations = Queue()  # list of tids'


    tidIssuer = NewIDIssuer()

    loc = local()


    eeps = []       # event processors
    neps = []       # network processors
    smps = []       # synchronous message processors
    teps = []       # time event processors
    
    @staticmethod
    def registerNewTasklet(tcb, inst):
        S.tcbs[tcb.tid] = tcb
        S.tcb_inst[tcb.tid] = inst
    
    @staticmethod
    def onTaskletTerminated(tcb):
        """an EEP has decided that a tasklet is dead"""
        del S.tcbs[tcb.tid]
        del S.tcb_inst[tcb.tid]
        
        for proc in itertools.chain(S.eeps, S.neps, S.smps, S.teps):
            proc.onTaskletTerminated(tcb)

    @staticmethod
    def startup(eeps=3, neps=3, smps=2, teps=2):
        """Starts up the SIC"""
        from ypage.processors.EEP import EEP
        for i in range(0, eeps):
            eep = EEP()
            eep.start()             
            S.eeps.append(eep)
        
        from ypage.processors.NEP import NEP
        for i in range(0, neps):
            nep = NEP()
            nep.start()
            S.neps.append(nep)
            
        from ypage.processors.SMP import SMP
        for i in range(0, smps):
            smp = SMP(i)
            smp.start()
            S.smps.append(smp)
        
        from ypage.processors.TEP import TEP
        for i in range(0, teps):
            tep = TEP(i)
            tep.start()
            S.teps.append(tep)
        
        print("Started", eeps+neps+smps+teps, "processors total:")
        print("   ", neps, "Network Event Processors")
        print("   ", eeps, "Event Execution Processors")
        print("   ", smps, "Synchronous Message Processors")
        print("   ", teps, "Time Event Processors")
        
    @staticmethod
    def getNEP(tcb):
        """Returns a NEP that handles given tasklet"""
        return S.neps[tcb.tid % len(S.neps)]

    @staticmethod
    def getSMP(tid):
        """Returns a SMP that handles given tasklet on behalf of tid"""
        return S.smps[tid % len(S.smps)]

    @staticmethod
    def getTEP(tid):
        """Returns a TEP that handles given tasklet on behalf of tid"""
        return S.teps[tid % len(S.teps)]
        
    @staticmethod
    def schedule(tcb, callable_: callable, *args, **kwargs):
        """Schedule an event on one of available EEPs"""
        S.eeps[tcb.tid % len(S.eeps)].put(tcb, callable_, *args, **kwargs)


    @staticmethod
    def isLocal(tid: int) -> bool:
        """Checks if a particular TID belongs to a local tasklet"""
        return (tid >> 40) == ((S.frameNo << 8) + S.pageNo)

    @staticmethod
    def getNextTID() -> int:
        """Returns a new, free TID"""
        return S.tidIssuer.next()