def __getitem__( s, idx ): if idx >= s.size: raise StopIteration # Create a memory request to send out memory request port s.trace = "r" r_addr = s.base_addr + (idx * 4) s.memreq.msg.next = s.mk_req( s.rd, r_addr, 0, 0 ) s.memreq.val.next = 1 s.memresp.rdy.next = 1 # Yield so we wait at least one cycle for the response greenlet.getcurrent().parent.switch(0) s.memreq.val.next = 0 s.memresp.rdy.next = 1 # If memory response has not arrived, then yield while not s.memresp.val or not s.memresp.rdy: s.trace = ":" greenlet.getcurrent().parent.switch(0) # When memory response has arrived, return the corresponding data s.trace = " " s.memreq.val.next = 0 s.memresp.rdy.next = 0 return s.memresp.msg[ s.data_slice ].uint()
def __setitem__( s, idx, value ): if idx >= s.size: raise StopIteration # Create a memory request to send out memory request port s.trace = "w" r_addr = s.base_addr + (idx * 4) s.memreq.msg.next = s.mk_req( s.wr, r_addr, 0, value ) s.memreq.val.next = 1 s.memresp.rdy.next = 1 # Yield so we wait at least one cycle for the response greenlet.getcurrent().parent.switch(0) s.memreq.val.next = 0 s.memresp.rdy.next = 1 # If memory response has not arrived, then yield while not s.memresp.val or not s.memresp.rdy: s.trace = ":" greenlet.getcurrent().parent.switch(0) # When memory response has arrived, then we are done s.trace = " " s.memreq.val.next = 0 s.memresp.rdy.next = 0
def wrap(): # We use this variable to tell whether app() has returned yet response = None def close(): if hasattr(response, 'close'): response.close() def write(data): if result is None: data = ResponseWrapper( _iter_greenlet(greenlet.getcurrent()), data, close ) elif response is not None: raise WSGIViolation( "Applications MUST NOT invoke write() from within their" " return iterable - see PEP 333/3333" ) greenlet.getcurrent().parent.switch(data) def start_response(status, headers, *exc): _start_response(status, headers, *exc) return write response = app(environ, start_response) if result is None: # write() was never called; ok to pass through return response else: for data in response: greenlet.getcurrent().parent.switch(data)
def fmain(seen): try: greenlet.getcurrent().parent.switch() except: seen.append(sys.exc_info()[0]) raise raise SomeError
def wrapper(*args,**kwargs): global gr_waitmap try: gr = greenlet(lambda *args,**kwargs : (str(id(greenlet.getcurrent())),f(*args,**kwargs))) grid = str(id(gr)) gr_waitmap[grid] = gr result = gr.switch(*args,**kwargs) if result == None: return (False,None) ret_grid,ret = result del gr_waitmap[grid] if greenlet.getcurrent() == gr_main: return (False,None) else: while ret_grid != grid: ret_grid,ret = gr_main.switch() return (True,ret) except Exception: return (False,'Einternal')
def fthread(): lock2.acquire() greenlet.getcurrent() del g[0] lock1.release() lock2.acquire() greenlet.getcurrent() lock1.release()
def worker(): try: # Wait to be killed main.switch() except greenlet.GreenletExit: # Resurrect and switch to parent result.append(greenlet.getcurrent().parent) result.append(greenlet.getcurrent()) hub.switch()
def get_current_process(): """ Called from within the execution frame of a Process. Returns the current active process. """ try: proc_mgr = _gr_pm_map[greenlet.getcurrent()] except KeyError: ds.failure.write("Cannot find a process manager service for greenlet.") return proc_mgr.get_gr_process(greenlet.getcurrent())
def _greenlet_block_generator(): block = greenlet.getcurrent().parent.switch() try: while block: yield block block = greenlet.getcurrent().parent.switch() finally: block = None
def write(data): if result is None: data = ResponseWrapper( _iter_greenlet(greenlet.getcurrent()), data, close ) elif response is not None: raise WSGIViolation( "Applications MUST NOT invoke write() from within their" " return iterable - see PEP 333/3333" ) greenlet.getcurrent().parent.switch(data)
def schedule_next(self, time): """ Schedules a timer for creating next chunk of events """ if time <= self.upto_time: return # else # schedule a timer just before this event and switch back to main "thread" # print "SHOULD NOT" core.set_event_scheduler_timer(time) greenlet.getcurrent().parent.switch()
def worker(): # wait for the value value = greenlet.getcurrent().parent.switch() # delete all references to ourself del worker[0] initiator.parent = greenlet.getcurrent().parent # switch to main with the value, but because # ts_current is the last reference to us we # return immediately try: greenlet.getcurrent().parent.switch(value) finally: seen.append(greenlet.getcurrent())
def proc_waitfor(self, p1, p2): """ Suspends process p1 till p2 finishes execution """ #util.check_type(process.Process, p1) p1_info = self.proc_table[id(p1)] #print "in wait for. chaning proc info at memory location",p1_info if not p1_info.gobject_ == greenlet.getcurrent(): ds.failure.write("ProcessManager: Invalid greenlet call state") if not p1_info.status_ == ProcStatus._active: ds.failure.write("ProcessManager: Process not in active state") p1_info.status_ = ProcStatus._waitfor p1_info.waitfor_ = p2 greenlet.getcurrent().parent.switch()
def proc_kill(self, proc): """ kills associated greenlet object and de-activates process """ #util.check_type(process.Process, proc) # make sure the calling process is not trying to kill itself. global _gr_pm_map if _gr_pm_map[greenlet.getcurrent()] == proc: ds.error.write("ProcessManager: process",proc.__class__.__name__ ,"trying to kill self. Not allowed") return try: proc_info = self.proc_table[id(proc)] except KeyError: ds.failure.write("ProcessManager: proc_kill: no entry found for process", proc.__class__.__name__,"in process table") if proc_info.status_ == ProcStatus._inactive: ds.info.write("ProcessManager: proc_kill: process already inactive", proc.__class__.__name__) else: # kill greenlet if not already dead if ( not proc_info.gobject_ is None) and (not proc_info.gobject_.dead): proc_info.gobject_.GreenletExit # de-activate process self.proc_deactivate( proc_info )
def post(self, who = None, cond = None, when = None): if who == None: who = greenlet.getcurrent() if cond: self._conds.append((who, cond)) if when: heappush(self._times, when)
def __iter__(self): while True: case = greenlet.getcurrent().parent.switch() if case: yield case else: raise StopIteration
def Yield(value): g = greenlet.getcurrent() while not isinstance(g, genlet): if g is None: raise RuntimeError('yield outside a genlet') g = g.parent g.parent.switch(value)
def getInstance(cls, *args, **kargs): '''Static method to have a reference to **THE UNIQUE** instance''' if cls.__instance is None: # (Some exception may be thrown...) # Initialize **the unique** instance cls.__instance = object.__new__(cls) # Initialize members for scheduler cls.__instance.new = [] cls.__instance.next = [] cls.__instance.main_process = MainProcess(greenlet.getcurrent(), cls.__instance) cls.__instance.current = cls.__instance.main_process # Timer specific value = (activation time, process) # On update we do a sort based on the activation time cls.__instance.timers = [] # Io specific cls.__instance.cond = threading.Condition() cls.__instance.blocking = 0 # Start scheduler greenlet cls.__instance.greenlet = greenlet(cls.__instance.main) return cls.__instance
def current_id(): co = greenlet.getcurrent() thrd = _current_threads.get (co, None) if thrd is None: return -1 else: return thrd.thread_id()
def __next__(self): self.parent = greenlet.getcurrent() result = self.switch() if self: return result else: raise StopIteration
def test_threaded_updatecurrent(self): # released when main thread should execute lock1 = threading.Lock() lock1.acquire() # released when another thread should execute lock2 = threading.Lock() lock2.acquire() class finalized(object): def __del__(self): # happens while in green_updatecurrent() in main greenlet # should be very careful not to accidentally call it again # at the same time we must make sure another thread executes lock2.release() lock1.acquire() # now ts_current belongs to another thread def deallocator(): greenlet.getcurrent().parent.switch() def fthread(): lock2.acquire() greenlet.getcurrent() del g[0] lock1.release() lock2.acquire() greenlet.getcurrent() lock1.release() main = greenlet.getcurrent() g = [greenlet(deallocator)] g[0].bomb = finalized() g[0].switch() t = threading.Thread(target=fthread) t.start() # let another thread grab ts_current and deallocate g[0] lock2.release() lock1.acquire() # this is the corner stone # getcurrent() will notice that ts_current belongs to another thread # and start the update process, which would notice that g[0] should # be deallocated, and that will execute an object's finalizer. Now, # that object will let another thread run so it can grab ts_current # again, which would likely crash the interpreter if there's no # check for this case at the end of green_updatecurrent(). This test # passes if getcurrent() returns correct result, but it's likely # to randomly crash if it's not anyway. self.assertEqual(greenlet.getcurrent(), main) # wait for another thread to complete, just in case t.join()
def wait_for_write(self, fd): ''' 等待,直到某fd可以写 ''' self.fdwmap[fd] = greenlet.getcurrent() self._setpoll(fd) self.schedule() try: del self.fdwmap[fd] except KeyError: pass self._setpoll(fd)
def wait(self, *types): """ Wait until the results of this invocation are resolved """ # TODO: pass typelist down to call for later checking # Pass our ids so the parent knows when to reinvoke self.green = greenlet.getcurrent() results = self.green.parent.switch(self) return results
def _get_new_main(): def main(): # Define function with __name__ for tasklet.__repr__. assert 0 main = tasklet(main) main._greenlet = greenlet.getcurrent() main.alive = True main.next = main.prev = main return main
def generator(): # This is the generator that the wrapped function will consume from while True: item = greenlet.getcurrent().parent.switch(sentinel) if isinstance(item, GeneratorExit): return else: yield item
def wait_for_gr(self, gr): ''' 等待一个gr结束。注意被等待的gr必须是使用fork_gr建立的。 ''' curgr = greenlet.getcurrent() if gr.dead: return if gr not in self.wait_for_end: self.wait_for_end[gr] = [] if curgr not in self.wait_for_end[gr]: self.wait_for_end[gr].append(curgr) while not gr.dead: self.schedule()
def switch_out(self, gr, *args): ''' 人工调出,执行gr所指定的上下文,最终可能切回。 @param gr: greenlet,需要被切入的上下文 @param args: 切入的参数 ''' if not gr: return self.add_queue(greenlet.getcurrent()) self._pre_switch() gr.switch(*args)
def test_throw_2(self): from greenlet import greenlet gmain = greenlet.getcurrent() # def f(): gmain.throw(ValueError) # g = greenlet(f) raises(ValueError, g.switch)
def register(self, fileno, flag): log.debug("ioloop.register %r %r", fileno, flag) if fileno in self.registered: # TODO: given the way this is meant to be used could one socket really be registered for multiple operations? if flag in self.registered[fileno]['operations']: raise JEventException("%r already registered for operation %r" % (fileno, flag)) self.registered[fileno]['flags'] |= flag self.registered[fileno]['operations'][flag] = greenlet.getcurrent() self.poll.modify(fileno, self.registered[fileno]['flags']) else: self.registered[fileno] = { 'operations': { flag: greenlet.getcurrent() }, 'flags': flag } self.poll.register(fileno, flag)
def go( s ): s.trace = " " s.to_cp2_queue.append( MatrixVecProxy.mk_msg( 0x0, 0x1 ) ) # Wait at least one cycle greenlet.getcurrent().parent.switch(0) # If cp2 not done then yield while s.from_cp2.done != 1: s.trace = ":" greenlet.getcurrent().parent.switch(0) # cp2 is done s.trace = " "
def __init__(self, thunk=None): if thunk: self.greenlet = greenlet(thunk) else: self.greenlet = greenlet.getcurrent()
def f(x, y): seen.append((x, y)) seen.append(greenlet.getcurrent().parent.switch()) seen.append(greenlet.getcurrent().parent.switch(42)) return 44, 'z'
def on_diff_commit__topo(self, *data): greenlet.getcurrent().data = data raise KeyboardInterrupt( ) # TODO: cleanup: properly close socket
def f(): lst.append(1) greenlet.getcurrent().parent.switch() lst.append(3)
def test_throw_3(self): from greenlet import greenlet gmain = greenlet.getcurrent() raises(ValueError, gmain.throw, ValueError)
def test_parent(self): from greenlet import greenlet gmain = greenlet.getcurrent() assert gmain.parent is None g = greenlet(lambda: None) assert g.parent is gmain
A costate object holds last and current. There are different coroutine concepts existing in parallel, like plain interp-level coroutines and app-level structures like coroutines, greenlets and tasklets. Every concept is associated with its own costate object. This allows for peaceful co-existence of many concepts. The type of a switch is determined by the target's costate. """ from pypy.rlib.rstack import yield_current_frame_to_caller, resume_point from pypy.rlib.objectmodel import we_are_translated try: from greenlet import greenlet main_greenlet = greenlet.getcurrent() except (ImportError, ValueError): def greenlet(*args, **kwargs): raise NotImplementedError( "need either greenlets or a translated version of pypy") class FrameChain(object): """Greenlet-based emulation of the primitive rstack 'frames' of RPython""" def __init__(self, thunk=None): if thunk: self.greenlet = greenlet(thunk) else: self.greenlet = greenlet.getcurrent()