def read(self):
        if self._read_ev is not None:
            raise RuntimeError('Already reading')

        event = self._read_ev = Event(self.env)

        if self._read_buf:
            self._read_data(Event(self.env).succeed(b''))
        else:
            self.socket.read(self.blocksize).callbacks.append(self._read_data)

        return event
    def recv(self):
        if self._in_queue is None:
            raise self.reader.value

        # Enqueue reads if there are no pending incoming messages.
        if not self._in_queue:
            if self._recv_ev is not None:
                raise RuntimeError('Concurrent receive attempt')

            self._recv_ev = Event(self.env)
            return self._recv_ev

        return Event(self.env).succeed(self._in_queue.pop(0))
Exemplo n.º 3
0
    def _write_outgoing(self):
        """Pulls data from :attr:`outgoing` and pushes it to the peer."""
        while True:
            if len(self.outgoing) == 0:
                if self._outgoing_error is None:
                    self._outgoing_avail = Event(self.env)
                    yield self._outgoing_avail

            data = self.outgoing[:self.max_segment_size]
            frame = Frame(self, data)
            yield self.env.timeout(self._latency())

            if self._peer._frame_transmission:
                # Inform peer of the frame and wait for the acknowledgement.
                self._peer._frame_transmission.succeed(frame)
                sent = yield frame
            else:
                # Peer has closed the connection
                sent = 0
                self._outgoing_error = errno.EPIPE

            if not frame.data:
                # The close frame has been sent.
                break

            self.outgoing = self.outgoing[sent:]

            if self._writer:
                self._try_write()
Exemplo n.º 4
0
        def event(self) -> Event:
            """Return a new :class:`~simpy.events.Event` instance.

            Yielding this event suspends a process until another process
            triggers the event.
            """
            return Event(self)
Exemplo n.º 5
0
    def run(self, until=None):
        """Executes :meth:`step()` until the given criterion *until* is met.

        - If it is ``None`` (which is the default) this method will return if
          there are no further events to be processed.

        - If it is an :class:`~simpy.events.Event` the method will continue
          stepping until this event has been triggered and will return its
          value.

        - If it can be converted to a number the method will continue stepping
          until the environment's time reaches *until*.

        """
        if until is None:
            until = Event(self)
        elif not isinstance(until, Event):
            at = float(until)

            if at <= self.now:
                raise ValueError('until(=%s) should be > the current '
                                 'simulation time.' % at)

            # Schedule the event with before all regular timeouts.
            until = Event(self)
            until.ok = True
            until._value = None
            self.schedule(until, URGENT, at - self.now)

        until.callbacks.append(_stop_simulate)

        try:
            while True:
                self.step()
        except EmptySchedule:
            pass

        if not until.triggered:
            return None

        if not until.ok:
            raise until.value

        return until.value
Exemplo n.º 6
0
    def run(self,
            until: Optional[Union[SimTime, Event]] = None) -> Optional[Any]:
        """Executes :meth:`step()` until the given criterion *until* is met.

        - If it is ``None`` (which is the default), this method will return
          when there are no further events to be processed.

        - If it is an :class:`~simpy.events.Event`, the method will continue
          stepping until this event has been triggered and will return its
          value.  Raises a :exc:`RuntimeError` if there are no further events
          to be processed and the *until* event was not triggered.

        - If it is a number, the method will continue stepping
          until the environment's time reaches *until*.

        """
        if until is not None:
            if not isinstance(until, Event):
                # Assume that *until* is a number if it is not None and
                # not an event.  Create a Timeout(until) in this case.
                at: SimTime
                if isinstance(until, int):
                    at = until
                else:
                    at = float(until)

                if at <= self.now:
                    raise ValueError(
                        f'until(={at}) must be > the current simulation time.')

                # Schedule the event before all regular timeouts.
                until = Event(self)
                until._ok = True
                until._value = None
                self.schedule(until, URGENT, at - self.now)

            elif until.callbacks is None:
                # Until event has already been processed.
                return until.value

            until.callbacks.append(StopSimulation.callback)

        try:
            while True:
                self.step()
        except StopSimulation as exc:
            return exc.args[0]  # == until.value
        except EmptySchedule:
            if until is not None:
                assert not until.triggered
                raise RuntimeError(
                    f'No scheduled events left but "until" event was not '
                    f'triggered: {until}')
        return None
    def _writer(self):
        env = self.env
        try:
            while True:
                if not self._out_queue:
                    self._send_ev = Event(self.env)
                    yield self._send_ev

                yield self.socket.write(self._out_queue.pop(0))
        except BaseException as e:
            self._handle_error(self.writer, e)
        def __init__(self, env, arrival_time, eid):
            self.eid = eid

            #                start_event = env.timeout(arrival_time)
            start_event = env.timeout(0)
            xor1_yes = Event(env)
            xor1_no = Event(env)

            end_act_A = env.process(
                act_A(env, start_event, dur_A(self), self.eid))
            end_act_B = env.process(
                act_B(env, end_act_A, dur_B(self), self.eid))
            end_act_B.callbacks.append(xor1(xor1_yes, xor1_no))
            end_act_C = env.process(act_C(env, xor1_yes, dur_C(self),
                                          self.eid))
            end_act_D = env.process(
                act_D(env, end_act_C, dur_D(self), self.eid))
            end_act_E = env.process(act_E(env, xor1_no, dur_E(self), self.eid))
            end_act_F = env.process(
                act_F(env, AnyOf(env, [end_act_D, end_act_E]), dur_F(self),
                      self.eid))
            env.process(act_G(env, end_act_F, dur_G(self), self.eid))
Exemplo n.º 9
0
    def _read_incoming(self):
        """Pushes remote data frames into :attr:`incoming`."""
        self._frame_transmission = Event(self.env)

        while True:
            if self._reader:
                self._try_read()

            if self._incoming_error is not None:
                break

            # Wait until there is room for incoming data.
            if len(self.incoming) >= self.max_buffer_size:
                self._incoming_avail = Event(self.env)
                yield self._incoming_avail
                continue

            frame = yield self._frame_transmission
            self._frame_transmission = Event(self.env)

            if frame is None:
                # A local close will end the frame transmission with None.
                continue

            if frame.data:
                read = min(self.max_buffer_size - len(self.incoming),
                           len(frame.data))
                self.incoming += frame.data[:read]
                # Simulate transmission of the frame acknowledgement.
                yield self.env.timeout(self._latency())
                frame.succeed(read)
            else:
                # An empty frame has been received, this means the remote side
                # has closed the connection.
                self._incoming_error = errno.ECONNRESET
                self.env._unregister(self)
                frame.succeed()

        self._frame_transmission = None
Exemplo n.º 10
0
    def run(self, until=None):
        """Executes :meth:`step()` until the given criterion *until* is met.

        - If it is ``None`` (which is the default), this method will return
          when there are no further events to be processed.

        - If it is an :class:`~simpy.events.Event`, the method will continue
          stepping until this event has been triggered and will return its
          value.  Raises a :exc:`RuntimeError` if there are no further events
          to be processed and the *until* event was not triggered.

        - If it is a number, the method will continue stepping
          until the environment's time reaches *until*.

        """
        if until is not None:
            if not isinstance(until, Event):
                # Assume that *until* is a number if it is not None and
                # not an event.  Create a Timeout(until) in this case.
                at = float(until)

                if at <= self.now:
                    raise ValueError('until(=%s) should be > the current '
                                     'simulation time.' % at)

                # Schedule the event with before all regular timeouts.
                until = Event(self)
                until.ok = True
                until._value = None
                self.schedule(until, URGENT, at - self.now)

            elif until.callbacks is None:
                # Until event has already been processed.
                return until.value

            until.callbacks.append(StopSimulation.callback)

        try:
            while True:
                self.step()
        except StopSimulation as exc:
            return exc.args[0]  # == until.value
        except EmptySchedule:
            if until is not None:
                # @ FIXED ASSERTION ERROR
                try:
                    not until.triggered
                except:
                    pass
                raise RuntimeError('No scheduled events left but "until" '
                                   'event was not triggered: %s' % until)
    def write(self, packet):
        if self._write_ev is not None:
            raise RuntimeError('Already writing')

        if self.encode is not None:
            packet = self.encode(packet)

        if len(packet) > self.max_packet_size:
            raise ValueError('Packet too large. Allowed %d bytes but '
                             'got %d bytes' %
                             (self.max_packet_size, len(packet)))

        self._write_ev = Event(self.env)
        self._write_buf = Header.pack(len(packet)) + packet
        self.socket.write(self._write_buf).callbacks.append(self._write_data)
        return self._write_ev
Exemplo n.º 12
0
    def networkInHandler(self, cmd):

        if isinstance(cmd, Message):
            if cmd.type is StackMessageTypes.RECEIVE:
                logger.debug("%s: Entering receive mode.", self)
                # start receiving
                self._receiveCmd = cmd
                # set _receiving and a timeout event
                self._receiving = True
                self._receiveTimeout = SimMan.timeout(cmd.args["duration"])
                self._receiveTimeout.callbacks.append(
                    self._receiveTimeoutCallback)

        elif isinstance(cmd, Packet):
            payload = cmd
            packet = Packet(
                SimpleMacHeader(self.addr, payload.header.destMAC, flag=0),
                payload)
            self._packetQueue.append(packet)
            self._packetAddedEvent.succeed()
            self._packetAddedEvent = Event(SimMan.env)
Exemplo n.º 13
0
    def __init__(self, name: str, device: Device,
                 frequencyBandSpec: FrequencyBandSpec, addr: bytes):
        """
        Args:
            name: The layer's name
            device: The device that operates the SimpleMac layer
            addr: The 6-byte-long MAC address to be assigned to this MAC layer
        """
        super(SimpleMac, self).__init__(name, owner=device)
        self._addPort("phy")
        self._addPort("network")
        self.addr = addr
        self._packetQueue = deque(maxlen=100)  # allow 100 packets to be queued
        self._packetAddedEvent = Event(SimMan.env)
        self._mcs = BpskMcs(frequencyBandSpec)
        self._transmissionPower = 0.0  # dBm
        self._receiving = False
        self._receiveCmd = None
        self._receiveTimeout = None

        logger.debug("Initialization completed, MAC address: %s",
                     self.addr,
                     sender=self)
Exemplo n.º 14
0
 def event(self):
     """
     Creates and returns a new :class:`~simpy.events.Event` object belonging to the
     current environment.
     """
     return Event(self.env)
Exemplo n.º 15
0
"""
一次等待多个事件.py:
有时候,你想同时等待多个事件。例如,您可能需要等待资源,但不是无限次的。或者你可能要等到所有的一系列事件发生。

因此SimPy中提供了AnyOf与AllOf事件,都是一个Condition事件。

两者都以事件列表作为参数,如果它们中的至少一个或全部被触发,则被触发。

"""

import simpy
from simpy.events import AnyOf, AllOf, Event

env = simpy.Environment()

events = [Event(env) for i in range(3)]
a = AnyOf(env, events)  # Triggers if at least one of "events" is triggered.
b = AllOf(env, events)  # Triggers if all each of "events" is triggered.


# '''
def test_condition(env):
    t1, t2 = env.timeout(1, value='spam'), env.timeout(2, value='eggs')
    ret = yield t1 | t2
    assert ret == {t1: 'spam'}

    t1, t2 = env.timeout(1, value='spam'), env.timeout(2, value='eggs')
    ret = yield t1 & t2
    assert ret == {t1: 'spam', t2: 'eggs'}

    # You can also concatenate & and |
Exemplo n.º 16
0
 def __init__(self, type: Enum, args: Dict[str, Any] = None):
     self.type = type
     self.args = args
     self.eProcessed = Event(SimMan.env)
Exemplo n.º 17
0
 def schedule(self, delay):
     evt = Event(self.env)
     evt.callbacks.append(self.observe)
     evt._ok = True
     self.env.schedule(evt, priority=2, delay=delay)